Esta sección de la documentación de Kubernetes contiene páginas que muestran cómo acometer tareas individuales. Cada página de tarea muestra cómo realizar una única cosa, típicamente proporcionando una pequeña secuencia de comandos.
Despliega y accede al interfaz web de usuario del Tablero de Control para ayudarte en la gestión y monitorización de las aplicaciones en contenedores de tu clúster de Kubenertes.
Instala y configura la herramienta de línea de comandos kubectl para gestionar de forma directa tus clústers de Kubernetes.
Realiza tareas comunes de configuración para tus Pods y Contenedores.
Realiza tareas comunes de gestión de aplicaciones, como actualizaciones de lanzamiento, inyectar información en los pods, y auto-escalado horizontal de pods.
Ejecuta Jobs usando procesado paralelo.
Configura el balanceo de carga, re-envío de puertos, o configura el cortafuegos o las configuraciones de DNS para acceder a las aplicaciones en un clúster.
Configura la monitorización y las trazas para identificar problemas en un clúster o depurar una aplicación en un contenedor.
Aprende varios métodos para acceder directamente a la API de Kubernetes.
Configura tu aplicación para que confíe y use el Certificado de Autoridad (CA) raíz de tu clúster.
Aprende tareas comunes de administración de un clúster.
Configura componentes en una federación de clústers.
Realiza tareas comunes de gestión de aplicaciones con estado, incluyendo escalado, borrado y depuración de StatefulSets.
Realiza tareas comunes de gestión de un DaemonSet, como llevar a cabo una actualización de lanzamiento.
Configura y planifica GPUs de NVIDIA para hacerlas disponibles como recursos a los nodos de un clúster.
Configura y planifica HugePages como un recurso planificado en un clúster.
Si quisieras escribir una página de Tareas, echa un vistazo a Crear una Petición de Subida de Documentación.
Usa la herramienta de línea de comandos de Kubernetes, kubectl, para desplegar y gestionar aplicaciones en Kubernetes. Usando kubectl, puedes inspeccionar recursos del clúster; crear, eliminar, y actualizar componentes; explorar tu nuevo clúster y arrancar aplicaciones.
Ver Instalar y Configurar kubectl para más información sobre cómo descargar y instalar kubectl y configurarlo para acceder su clúster.
Ver la guía de instalación y configuración de kubectl
También se puede leer la documentación de referencia de kubectl.
kind le permite usar Kubernetes en su máquina local. Esta herramienta require que Docker instalado y configurado.
En la página de inicio rápido encontrarás toda la información necesaria para empezar con kind.
De forma similar a kind, minikube es una herramienta que le permite usar Kubernetes en su máquina local. minikube le permite ejecutar un único nodo en su computadora personal (PC de Windows, macOS y Linux) para que se pueda probar Kubernetes, o para su trabajo de desarrollo.
Se puede seguir la guía oficial de minikube si su enfoque esta instalando la herramienta.
Una vez minikube ha terminado de instalarse, está lista para desplegar un aplicación de ejemplo (/docs/tutorials/hello-minikube/).
Se puede usar la utilidad kubeadm para crear y gestionar clústeres de Kubernetes.
En instalando kubeadm se muestra como instalar kubeadm. Una vez instalado, se puede utilizar para crear un clúster.
Se debe utilizar la versión de kubectl con una minor versión de diferencia con tu cluster. Por ejemplo, un cliente con versión v1.35 se puede comunicar con las siguientes versiones de plano de control v1.34, v1.35 y v1.36. Utilizar la última versión compatible de kubectl evita posibles errores.
Existen los siguientes métodos para instalar kubectl en Linux:
Descargar la última versión con el siguiente comando:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl"
Para descargar una versión específica reemplaza la siguiente parte del comando con la
versión que desea instalar $(curl -L -s https://dl.k8s.io/release/stable.txt)
Por ejemplo, para descargar la versión 1.35.0 en linux x86-64:
curl -LO https://dl.k8s.io/release/v1.35.0/bin/linux/amd64/kubectl
Y para Linux ARM64:
curl -LO https://dl.k8s.io/release/v1.35.0/bin/linux/arm64/kubectl
Validación del binario (paso opcional)
Descargar el archivo checksum:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl.sha256"
Validar el binario de kubectl contra el archivo checksum:
echo "$(cat kubectl.sha256) kubectl" | sha256sum --check
Si es válido, va a obtener la siguiente respuesta:
kubectl: OK
En caso de falla, sha256 terminará con un estado diferente a cero con una salida similar a:
kubectl: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
Instalar kubectl
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
Si no tienes acceso root en el sistema donde se busca instalar, puedes colocar
el binario kubectl en el directorio ~/.local/bin:
chmod +x kubectl
mkdir -p ~/.local/bin
mv ./kubectl ~/.local/bin/kubectl
# Y después agrega el directorio ~/.local/bin a tu $PATH
Test para asegurar que la versión instalada está actualizada:
kubectl version --client
O puedes utilizar lo siguiente para una vista detallada de la versión:
kubectl version --client --output=yaml
Actualiza el índice del paquete apt, luego instala los paquetes necesarios para Kubernetes:
sudo apt-get update
# apt-transport-https may be a dummy package; if so, you can skip that package
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg
Descarga la llave pública firmada para los repositorios de Kubernetes. La misma llave firmada es usada para todos los repositorios por lo que se puede obviar la versión en la URL:
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.35/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
Agregar el repositorio apropiado de Kubernetes. Si quieres una versión de Kubernetes diferente a v1.35, reemplace v1.35 con la versión deseada en el siguiente comando:
# Esto sobrescribe cualquier configuración existente en el archivo /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.35/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
/etc/apt/sources.list.d/kubernetes.list antes de ejecutar apt-get update y apt-get upgrade. Este procedimiento se describe con más detalle en Cambiando el Repositorio de Kubernetes.Actualiza el índice de apt, luego instala kubectl:
sudo apt-get update
sudo apt-get install -y kubectl
/etc/apt/keyrings no existe por defecto, puede ser creado usando el comando sudo mkdir -m 755 /etc/apt/keyringsAgregar Kubernetes al repositorio yum. Si deseas usar una versión de Kubernetes
diferente a v1.35, reemplaza v1.35 con
la versión deseada en el siguiente comando:
# Lo siguiente reemplaza cualquier configuración existente en /etc/yum.repos.d/kubernetes.repo
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.35/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.35/rpm/repodata/repomd.xml.key
EOF
/etc/yum.repos.d/kubernetes.repo
antes de ejecutar yum update. Este procedimiento se describe con más detalle en Changing The Kubernetes Package Repository.Instalar kubectl utilizando yum:
sudo yum install -y kubectl
Agregar Kubernetes al repositorio zypper. Si deseas usar una versión de Kubernetes
diferente a v1.35, reemplaza v1.35 con
la versión deseada en el siguiente comando:
# Lo siguiente reemplaza cualquier configuración existente en /etc/zypp/repos.d/kubernetes.repo
cat <<EOF | sudo tee /etc/zypp/repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.35/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.35/rpm/repodata/repomd.xml.key
EOF
/etc/zypp/repos.d/kubernetes.repo
antes de ejecutar zypper update. Este procedimiento se describe con más detalle en Changing The Kubernetes Package Repository.Instalar kubectl usando zypper:
sudo zypper install -y kubectl
Si utilizas Ubuntu o alguna distribución que soporte el administrador de páquetes snap, kubectl está disponible como una aplicación de snap.
snap install kubectl --classic
kubectl version --client
Si utilizas Homebrew en Linux, kubectl está disponible para su instalación.
brew install kubectl
kubectl version --client
Para que kubectl encuentre y acceda a un clúster de Kubernetes, necesita un
archivo kubeconfig, que se crea automáticamente cuando creas un clúster usando
kube-up.sh
o implementar con éxito un clúster de Minikube.
De forma predeterminada, la configuración de kubectl se encuentra en ~/.kube/config.
Verifique que kubectl esté configurado correctamente obteniendo el estado del clúster:
kubectl cluster-info
Si ve una respuesta de URL, kubectl está configurado correctamente para acceder a su clúster.
Si ve un mensaje similar al siguiente, kubectl no está configurado correctamente o no puede conectarse a un clúster de Kubernetes.
The connection to the server <server-name:port> was refused - did you specify the right host or port?
Por ejemplo, si tiene la intención de ejecutar un clúster de Kubernetes en su computadora portátil (localmente), primero necesitará instalar una herramienta como Minikube y luego volver a ejecutar los comandos indicados anteriormente.
Si kubectl cluster-info devuelve la respuesta de la URL pero no puede acceder a su clúster, para verificar si está configurado correctamente, use:
kubectl cluster-info dump
Kubectl tiene soporte para autocompletar en Bash, Zsh, Fish y Powershell, lo que puede agilizar el tipeo.
A continuación están los procedimientos para configurarlo en Bash, Fish y Zsh.
El script de completado de kubectl para Bash se puede generar con el comando kubectl completion bash. Obtener el script de completado en su shell habilita el autocompletado de kubectl.
Sin embargo, el script de completado depende de bash-completion, lo que significa que primero debe instalar este software (puedes probar si tienes bash-completion ya instalado ejecutando type _init_completion).
El completado de bash es proporcionado por muchos administradores de paquetes (ver aquí). Puedes instalarlo con apt-get install bash-completion o yum install bash-completion, etc.
Los comandos anteriores crean /usr/share/bash-completion/bash_completion, que es el script principal de bash-complete. Dependiendo de su administrador de paquetes, debe obtener manualmente este archivo de perfil en su ~/.bashrc.
Para averiguarlo, recargue su shell y ejecute type _init_completion. Si el comando tiene éxito, ya está configurado; de lo contrario, agregue lo siguiente a su archivo ~/.bashrc:
source /usr/share/bash-completion/bash_completion
Vuelva a cargar su shell y verifique que la finalización de bash esté correctamente instalada escribiendo type _init_completion.
Ahora debe asegurarse de que el script de completado de kubectl se obtenga en todas sus sesiones de shell. Hay dos formas de hacer esto:
Obtenga el script de completado en su perfil ~/.bashrc:
echo 'source <(kubectl completion bash)' >>~/.bashrc
Agregue el script de completado al directorio de /etc/bash_completion.d:
kubectl completion bash >/etc/bash_completion.d/kubectl
Si tiene un alias para kubectl, puede extender el completado del shell para trabajar con ese alias:
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -o default -F __start_kubectl k' >>~/.bashrc
/etc/bash_completion.d.Ambos enfoques son equivalentes. Después de recargar su shell, el autocompletado de kubectl debería estar funcionando.
El script de autocompletado de Fish puede ser generado con el comando kubectl completion fish. Leyendo este archivo en su Shell habilita el autocompletado de kubectl.
Para hacer esto en todas sus sesiones agregue la siguiente linea a su archivo ~/.config/fish/config.fish:
kubectl completion fish | source
Después de recargar tu shell, el autocompletado para kubectl estará funcionando automáticamente.
El script de completado de kubectl para Zsh se puede generar con el comando kubectl completion zsh. Obtener el script de completado en su shell habilita el autocompletado de kubectl.
Para hacerlo en todas sus sesiones de shell, agregue lo siguiente a su perfil ~/.zshrc:
source <(kubectl completion zsh)
Si tiene un alias para kubectl, puede extender el completado del shell para trabajar con ese alias:
echo 'alias k=kubectl' >>~/.zshrc
echo 'compdef __start_kubectl k' >>~/.zshrc
Después de recargar su shell, el autocompletado de kubectl debería estar funcionando.
Si recibe un error como complete:13: command not found: compdef,
luego agregue lo siguiente al comienzo de su perfil ~/.zshrc:
autoload -Uz compinit
compinit
kubectl convertUn plugin para la herramienta de línea de comandos de Kubernetes kubectl, que le permite convertir manifiestos entre diferentes versiones de la API. Esto puede ser particularmente útil para migrar manifiestos a una versión no obsoleta de la API con la versión más reciente de Kubernetes.
Para obtener más información, visite migrar a APIs no obsoletas
Descarga la última versión con el siguiente comando:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl-convert"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl-convert"
Valida el binario (opcional)
Descarga el checksum de kubectl-convert:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl-convert.sha256"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/arm64/kubectl-convert.sha256"
Ahora se puede validar el binario utilizando el checksum:
echo "$(cat kubectl-convert.sha256) kubectl-convert" | sha256sum --check
Si es válido, la salida será:
kubectl-convert: OK
En caso de falla, sha256 terminará con un estado diferente a cero con una salida similar a esta:
kubectl-convert: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
Instalar kubectl-convert
sudo install -o root -g root -m 0755 kubectl-convert /usr/local/bin/kubectl-convert
Verificar si el plugin fue instalado correctamente
kubectl convert --help
Si no visualizas ningún error quiere decir que el plugin fue instalado correctamente.
Después de instalar el plugin elimina los archivos de instalación:
rm kubectl-convert kubectl-convert.sha256
Se debe utilizar la versión de kubectl con la menor diferencia de versión de respecto de su clúster. Por ejemplo, un cliente con versión v1.35 se puede comunicar con los siguientes versiones de plano de control v1.34, v1.35, and v1.36. Utilizar la última versión compatible de kubectl evita posibles errores.
Existen los siguientes métodos para instalar kubectl en macOS:
Descargar la última versión con el siguiente comando:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl"
Para descargar una versión específica, reemplaza la siguiente parte del comando con la
versión que deseas instalar $(curl -L -s https://dl.k8s.io/release/stable.txt)
Por ejemplo, para descargar la versión 1.35.0 en macOS:
curl -LO "https://dl.k8s.io/release/v1.35.0/bin/darwin/amd64/kubectl"
Para macOS con procesador Apple Silicon, ejecuta:
curl -LO "https://dl.k8s.io/release/v1.35.0/bin/darwin/arm64/kubectl"
Validación del binario (paso opcional)
Descargar el archivo checksum:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl.sha256"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl.sha256"
Validar el binario de kubectl contra el archivo checksum:
echo "$(cat kubectl.sha256) kubectl" | shasum -a 256 --check
Si es válido, vas a obtener la siguiente respuesta:
kubectl: OK
En caso de falla, sha256 terminará con un estado diferente a cero con una salida similar a:
kubectl: FAILED
shasum: WARNING: 1 computed checksum did NOT match
Dar permisos de ejecución al binario.
chmod +x ./kubectl
Mover el binario de kubectl al PATH de tu sistema.
sudo mv ./kubectl /usr/local/bin/kubectl
sudo chown root: /usr/local/bin/kubectl
/usr/local/bin forme parte de las variables de entorno.Test para asegurar que la versión instalada está actualizada:
kubectl version --client
Se puede utilizar lo siguiente para una vista detallada de la versión:
kubectl version --client --output=yaml
Luego de instalar el plugin puede eliminar los archivos de instalación:
rm kubectl kubectl.sha256
Si está utilizando Homebrew en macOS, puede instalar kubectl con Homebrew.
Ejecute el comando para instalar:
brew install kubectl
ó
brew install kubernetes-cli
Test para asegurar que la versión instalada está actualizada:
kubectl version --client
Si esta en macOS y utiliza Macports, puedes instalar kubectl con Macports.
Ejecute el comando para instalar:
sudo port selfupdate
sudo port install kubectl
Test para asegurar que la versión instalada está actualizada:
kubectl version --client
Para que kubectl encuentre y acceda a un clúster de Kubernetes, necesita un
archivo kubeconfig, que se crea automáticamente cuando creas un clúster usando
kube-up.sh
o implementar con éxito un clúster de Minikube.
De forma predeterminada, la configuración de kubectl se encuentra en ~/.kube/config.
Verifique que kubectl esté configurado correctamente obteniendo el estado del clúster:
kubectl cluster-info
Si ve una respuesta de URL, kubectl está configurado correctamente para acceder a su clúster.
Si ve un mensaje similar al siguiente, kubectl no está configurado correctamente o no puede conectarse a un clúster de Kubernetes.
The connection to the server <server-name:port> was refused - did you specify the right host or port?
Por ejemplo, si tiene la intención de ejecutar un clúster de Kubernetes en su computadora portátil (localmente), primero necesitará instalar una herramienta como Minikube y luego volver a ejecutar los comandos indicados anteriormente.
Si kubectl cluster-info devuelve la respuesta de la URL pero no puede acceder a su clúster, para verificar si está configurado correctamente, use:
kubectl cluster-info dump
Kubectl tiene soporte para autocompletar en Bash, Zsh, Fish y Powershell, lo que puede agilizar el tipeo.
A continuación están los procedimientos para configurarlo en Bash, Fisch y Zsh.
El script de completado de kubectl para Bash se puede generar con kubectl completion bash. Obtener este script en su shell permite el completado de kubectl.
Sin embargo, el script de finalización de kubectl depende de bash-completion que, por lo tanto, debe instalar previamente.
Las siguientes instrucciones asumen que usa Bash 4.1+. Puede verificar la versión de su Bash ejecutando:
echo $BASH_VERSION
Si es demasiado antiguo, puede instalarlo o actualizarlo usando Homebrew:
brew install bash
Vuelva a cargar su shell y verifique que se esté utilizando la versión deseada:
echo $BASH_VERSION $SHELL
Homebrew generalmente lo instala en /usr/local/bin/bash.
Puede probar si ya tiene instalado bash-complete v2 con type _init_completion. Si no es así, puede instalarlo con Homebrew:
brew install bash-completion@2
Como se indica en el resultado de este comando, agregue lo siguiente a su archivo ~/.bash_profile:
brew_etc="$(brew --prefix)/etc" && [[ -r "${brew_etc}/profile.d/bash_completion.sh" ]] && . "${brew_etc}/profile.d/bash_completion.sh"
Vuelva a cargar su shell y verifique que bash-complete v2 esté instalado correctamente con type _init_completion.
Ahora debe asegurarse de que el script de completado de kubectl se obtenga en todas sus sesiones de shell. Hay varias formas de lograrlo:
Obtenga el script de finalización en su perfil ~/.bash_profile:
echo 'source <(kubectl completion bash)' >>~/.bash_profile
Agregue el script de completado al directorio /usr/local/etc/bash_completion.d:
kubectl completion bash >/usr/local/etc/bash_completion.d/kubectl
Si tiene un alias para kubectl, puede extender el completado del shell para trabajar con ese alias:
echo 'alias k=kubectl' >>~/.bash_profile
echo 'complete -o default -F __start_kubectl k' >>~/.bash_profile
Si instaló kubectl con Homebrew (como se explica aquí), entonces el script de completado de kubectl ya debería estar en /usr/local/etc/bash_completion.d/kubectl. En ese caso, no necesita hacer nada.
BASH_COMPLETION_COMPAT_DIR, es por eso que los dos últimos métodos funcionan.En cualquier caso, después de recargar su shell, el completado de kubectl debería estar funcionando.
El script de autocompletado de Fish puede ser generado con el comando kubectl completion fish. Leyendo este archivo en su Shell habilita el autocompletado de kubectl.
Para hacer esto en todas sus sesiones agregue la siguiente linea a su archivo ~/.config/fish/config.fish:
kubectl completion fish | source
Después de recargar tu shell, el autocompletado para kubectl estará funcionando automáticamente.
El script de completado de kubectl para Zsh se puede generar con el comando kubectl completion zsh. Obtener el script de completado en su shell habilita el autocompletado de kubectl.
Para hacerlo en todas sus sesiones de shell, agregue lo siguiente a su perfil ~/.zshrc:
source <(kubectl completion zsh)
Si tiene un alias para kubectl, puede extender el completado del shell para trabajar con ese alias:
echo 'alias k=kubectl' >>~/.zshrc
echo 'compdef __start_kubectl k' >>~/.zshrc
Después de recargar su shell, el autocompletado de kubectl debería estar funcionando.
Si recibe un error como complete:13: command not found: compdef,
luego agregue lo siguiente al comienzo de su perfil ~/.zshrc:
autoload -Uz compinit
compinit
kubectl convertUn plugin para la herramienta de línea de comandos de Kubernetes kubectl, que le permite convertir manifiestos entre diferentes versiones de la API. Esto puede ser particularmente útil para migrar manifiestos a una versión no obsoleta de la API con la versión más reciente de Kubernetes.
Para obtener más información, visite migrar a APIs no obsoletas
Descarga la última versión con el siguiente comando:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl-convert"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl-convert"
Valide el binario (opcional)
Descargue el checksum de kubectl-convert:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl-convert.sha256"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl-convert.sha256"
Ahora se puede validar el binario utilizando el checksum:
echo "$(cat kubectl-convert.sha256) kubectl-convert" | shasum -a 256 --check
Si es válido, la salida será:
kubectl-convert: OK
En caso de falla, sha256 terminará con un estado diferente a cero con una salida similar a esta:
kubectl-convert: FAILED
shasum: WARNING: 1 computed checksum did NOT match
Dar permisos de ejecución al binario.
chmod +x ./kubectl-convert
Mover el binario de kubectl al PATH de su sistema.
sudo mv ./kubectl-convert /usr/local/bin/kubectl-convert
sudo chown root: /usr/local/bin/kubectl-convert
/usr/local/bin forme parte de las variables de entorno.Verificar si el plugin fue instalado correctamente
kubectl convert --help
Si no visualiza ningún error quiere decir que el plugin fue instalado correctamente.
Después de instalar el plugin elimine los archivos de instalación:
rm kubectl-convert kubectl-convert.sha256
Dependiendo de como haya instalado kubectl puede utilizar uno de los siguientes métodos.
Ubique el binario de kubectl en su sistema:
which kubectl
Elimine el binario de kubectl:
sudo rm <path>
Reemplace <path> con el path que apunta al binario de kubectl del paso anterior. Por ejemplo, sudo rm /usr/local/bin/kubectl
Si instaló kubectl utilizando Homebrew ejecute el siguiente comando:
brew remove kubectl
Debes usar una versión de kubectl que esté dentro de una diferencia de versión menor de tu clúster. Por ejemplo, un cliente v1.35 puede comunicarse con versiones v1.34, v1.35, y v1.36 del plano de control.
El uso de la última versión de kubectl ayuda a evitar problemas imprevistos.
Existen los siguientes métodos para instalar kubectl en Windows:
Tiene dos opciones para instalar kubectl en su dispositivo Windows:
Descarga directa: Descargue la última versión 1.35.0 del binario directamente según tu arquitectura visitando Kubernetes release page. Asegúrese de seleccionar el binario correcto para tu arquitectura (e.g., amd64, arm64, etc.).
Usando curl:
Si tiene curl instalado, use este comando:
curl.exe -LO https://dl.k8s.io/release/v1.35.0/bin/windows/amd64/kubectl.exe
Validar el binario (opcional)
Descargue el archivo de comprobación de kubectl:
curl.exe -LO https://dl.k8s.io/v1.35.0/bin/windows/amd64/kubectl.exe.sha256
Valide el binario kubectl con el archivo de comprobación:
Usando la consola del sistema para comparar manualmente la salida de CertUtil con el archivo de comprobación descargado:
CertUtil -hashfile kubectl.exe SHA256
type kubectl.exe.sha256
Usando PowerShell puede automatizar la verificación usando el operador -eq para obtener un resultado de True o False:
$(Get-FileHash -Algorithm SHA256 .\kubectl.exe).Hash -eq $(Get-Content .\kubectl.exe.sha256)
Agregue el binario kubectl a su PATH en las variables de entorno.
Para asegurar que la versión de kubectl es la misma que descargada, ejecute:
kubectl version --client
O para una vista detallada de la versión, ejecute:
kubectl version --client --output=yaml
kubectl al PATH.
Si ha instalado Docker Desktop antes, es posible que deba colocar su entrada del PATH antes de la agregada por el instalador de Docker Desktop o elimine el kubectl de Docker Desktop.Para instalar kubectl en Windows puede usar el gestor de paquetes Chocolatey, el instalador por línea de comandos Scoop o el gestor de paquetes winget.
choco install kubernetes-cli
scoop install kubectl
winget install -e --id Kubernetes.kubectl
Para asegurarse de que la versión que instaló esté actualizada, ejecute:
kubectl version --client
Navegue a su directorio de inicio:
# Si estás usando cmd.exe, correr: cd %USERPROFILE%
cd ~
Cree el directorio .kube:
mkdir .kube
Cambie al directorio .kube que acaba de crear:
cd .kube
Configure kubectl para usar un clúster de Kubernetes remoto:
New-Item config -type file
Para que kubectl encuentre y acceda a un clúster de Kubernetes, necesita un
archivo kubeconfig, que se crea automáticamente cuando creas un clúster usando
kube-up.sh
o implementar con éxito un clúster de Minikube.
De forma predeterminada, la configuración de kubectl se encuentra en ~/.kube/config.
Verifique que kubectl esté configurado correctamente obteniendo el estado del clúster:
kubectl cluster-info
Si ve una respuesta de URL, kubectl está configurado correctamente para acceder a su clúster.
Si ve un mensaje similar al siguiente, kubectl no está configurado correctamente o no puede conectarse a un clúster de Kubernetes.
The connection to the server <server-name:port> was refused - did you specify the right host or port?
Por ejemplo, si tiene la intención de ejecutar un clúster de Kubernetes en su computadora portátil (localmente), primero necesitará instalar una herramienta como Minikube y luego volver a ejecutar los comandos indicados anteriormente.
Si kubectl cluster-info devuelve la respuesta de la URL pero no puede acceder a su clúster, para verificar si está configurado correctamente, use:
kubectl cluster-info dump
kubectl proporciona soporte de autocompletado para Bash, Zsh, Fish, y PowerShell, lo que puede ahorrarle mucho tiempo de escritura.
A continuación se muestran los procedimientos para configurar el autocompletado para PowerShell.
El script de autocompletado de kubectl para PowerShell se puede generar con el comando kubectl completion powershell.
Para hacerlo en todas tus sesiones de shell, agrega la siguiente línea a tu archivo $PROFILE:
kubectl completion powershell | Out-String | Invoke-Expression
Este comando agregará el script de autocompletado en cada sesión de PowerShell. También puedes añadir el script generado directamente en tu archivo $PROFILE.
Para agregar el script generado a tu archivo $PROFILE, ejecute el siguiente comando en el prompt de tu PowerShell:
kubectl completion powershell >> $PROFILE
Después de recargar tu shell, el autocompletado de kubectl debería funcionar.
kubectl-convertDescargue la última versión con el comando:
curl.exe -LO "https://dl.k8s.io/release/v1.35.0/bin/windows/amd64/kubectl-convert.exe"
Validar el binario (opcional)
Descargue el archivo de comprobación kubectl-convert:
curl.exe -LO "https://dl.k8s.io/v1.35.0/bin/windows/amd64/kubectl-convert.exe.sha256"
Valide el binario kubectl-convert con el archivo de comprobación:
Usando la consola del sistema puede comparar manualmente la salida de CertUtil con el archivo de comprobación descargado:
CertUtil -hashfile kubectl-convert.exe SHA256
type kubectl-convert.exe.sha256
Usando PowerShell puede automatizar la verificación usando el operador -eq para obtener
un resultado de True o False:
$($(CertUtil -hashfile .\kubectl-convert.exe SHA256)[1] -replace " ", "") -eq $(type .\kubectl-convert.exe.sha256)
Agregue el binario a su PATH.
Verifique que el plugin se haya instalado correctamente
kubectl convert --help
Si no ve un error, significa que el plugin se instaló correctamente.
Después de instalar el plugin, elimine los archivos de instalación:
del kubectl-convert.exe
del kubectl-convert.exe.sha256
En esta página se muestra cómo configurar un Pod para usar un Volume (volumen) como almacenamiento.
El sistema de ficheros de un Contenedor existe mientras el Contenedor exista. Por tanto, cuando un Contenedor es destruido o reiniciado, los cambios realizados en el sistema de ficheros se pierden. Para un almacenamiento más consistente que sea independiente del ciclo de vida del Contenedor, puedes usar un Volume. Esta característica es especialmente importante para aplicaciones que deben mantener un estado, como motores de almacenamiento clave-valor (por ejemplo Redis) y bases de datos.
Debes tener un cluster Kubernetes a tu dispocición, y la herramienta de línea de comandos kubectl debe estar configurada. Si no tienes un cluster, puedes crear uno utilizando Minikube,
o puedes utilizar una de las siguientes herramientas en línea:
Para comprobar la versión, introduzca kubectl version.
En este ejercicio crearás un Pod que ejecuta un único Contenedor. Este Pod tiene un Volume de tipo emptyDir (directorio vacío) que existe durante todo el ciclo de vida del Pod, incluso cuando el Contenedor es destruido y reiniciado. Aquí está el fichero de configuración del Pod:
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
volumeMounts:
- name: redis-storage
mountPath: /data/redis
volumes:
- name: redis-storage
emptyDir: {}
Crea el Pod:
kubectl apply -f https://k8s.io/examples/pods/storage/redis.yaml
Verifica que el Contenedor del Pod se está ejecutando y después observa los cambios en el Pod
kubectl get pod redis --watch
La salida debería ser similar a:
NAME READY STATUS RESTARTS AGE
redis 1/1 Running 0 13s
En otro terminal, abre una sesión interactiva dentro del Contenedor que se está ejecutando:
kubectl exec -it redis -- /bin/bash
En el terminal, ve a /data/redis y crea un fichero:
root@redis:/data# cd /data/redis/
root@redis:/data/redis# echo Hello > test-file
En el terminal, lista los procesos en ejecución:
root@redis:/data/redis# apt-get update
root@redis:/data/redis# apt-get install procps
root@redis:/data/redis# ps aux
La salida debería ser similar a:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
redis 1 0.1 0.1 33308 3828 ? Ssl 00:46 0:00 redis-server *:6379
root 12 0.0 0.0 20228 3020 ? Ss 00:47 0:00 /bin/bash
root 15 0.0 0.0 17500 2072 ? R+ 00:48 0:00 ps aux
En el terminal, mata el proceso de Redis:
root@redis:/data/redis# kill <pid>
donde <pid> es el ID de proceso (PID) de Redis.
En el terminal original, observa los cambios en el Pod de Redis. Eventualmente verás algo como lo siguiente:
NAME READY STATUS RESTARTS AGE
redis 1/1 Running 0 13s
redis 0/1 Completed 0 6m
redis 1/1 Running 1 6m
En este punto, el Contenedor ha sido destruido y reiniciado. Esto es debido a que el Pod de Redis tiene una
restartPolicy (política de reinicio)
de Always (siempre).
Abre un terminal en el Contenedor reiniciado:
kubectl exec -it redis -- /bin/bash
En el terminal, ve a /data/redis y verifica que test-file todavía existe:
root@redis:/data/redis# cd /data/redis/
root@redis:/data/redis# ls
test-file
Elimina el Pod que has creado para este ejercicio:
kubectl delete pod redis
Revisa Volume.
Revisa Pod.
Además del almacenamiento local proporcionado por emptyDir, Kubernetes soporta diferentes tipos de soluciones de almacenamiento por red, incluyendo los discos gestionados de los diferentes proveedores cloud, como por ejemplo los Persistent Disks en Google Cloud Platform o el Elastic Block Storage de Amazon Web Services. Este tipo de soluciones para volúmenes son las preferidas para el almacenamiento de datos críticos. Kubernetes se encarga de todos los detalles, tal como montar y desmontar los dispositivos en los nodos del clúster. Revisa Volumes para obtener más información.
Objetos en Kubernetes pueden ser creados, actualizados y eliminados utilizando
archivos de configuración almacenados en un directorio. Usando el comando
kubectl apply podrá crearlos o actualizarlos de manera recursiva según sea necesario.
Este método retiene cualquier escritura realizada contra objetos activos en el
sistema sin unirlos de regreso a los archivos de configuración. kubectl diff le
permite visualizar de manera previa los cambios que apply realizará.
Instale kubectl.
Debes tener un cluster Kubernetes a tu dispocición, y la herramienta de línea de comandos kubectl debe estar configurada. Si no tienes un cluster, puedes crear uno utilizando Minikube,
o puedes utilizar una de las siguientes herramientas en línea:
Para comprobar la versión, introduzca kubectl version.
La herramienta kubectl soporta tres modos distintos para la administración de objetos:
Acceda Administración de objetos de Kubernetes para una discusión de las ventajas y desventajas de cada modo distinto de administración.
La configuración de objetos declarativa requiere una comprensión firme de la definición y configuración de objetos de Kubernetes. Si aún no lo ha hecho, lea y complete los siguientes documentos:
A continuación la definición de términos usados en este documento:
kubectl apply. Los archivos de configuración
por lo general se almacenan en un sistema de control de versiones, como Git.kubectl apply para aplicarlos.Utilice kubectl apply para crear todos los objetos definidos en los archivos
de configuración existentes en un directorio específico, con excepción de aquellos que
ya existen:
kubectl apply -f <directorio>/
Esto definirá la anotación kubectl.kubernetes.io/last-applied-configuration: '{...}'
en cada objeto. Esta anotación contiene el contenido del archivo de configuración
utilizado para la creación del objeto.
-R para procesar un directorio de manera recursiva.El siguiente es un ejemplo de archivo de configuración para un objeto:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
minReadySeconds: 5
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Ejecute kubectl diff para visualizar el objeto que será creado:
kubectl diff -f https://k8s.io/examples/application/simple_deployment.yaml
diff utiliza server-side dry-run,
que debe estar habilitado en el kube-apiserver.
Dado que diff ejecuta una solicitud de apply en el servidor en modo de simulacro (dry-run),
requiere obtener permisos de PATCH, CREATE, y UPDATE.
Vea Autorización Dry-Run
para más detalles.
Cree el objeto usando kubectl apply:
kubectl apply -f https://k8s.io/examples/application/simple_deployment.yaml
Despliegue la configuración activa usando kubectl get:
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
La salida le mostrará que la anotación kubectl.kubernetes.io/last-applied-configuration
fue escrita a la configuración activa, y es consistente con los contenidos del archivo
de configuración:
kind: Deployment
metadata:
annotations:
# ...
# Esta es la representación JSON de simple_deployment.yaml
# Fue escrita por kubectl apply cuando el objeto fue creado
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.14.2","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
# ...
minReadySeconds: 5
selector:
matchLabels:
# ...
app: nginx
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.14.2
# ...
name: nginx
ports:
- containerPort: 80
# ...
# ...
# ...
# ...
También puede usar kubectl apply para actualizar los objetos definidos en un directorio,
aún cuando esos objetos ya existan en la configuración activa. Con este enfoque logrará
lo siguiente:
kubectl diff -f <directorio>/
kubectl apply -f <directorio>/
-R para procesar directorios de manera recursiva.Este es un ejemplo de archivo de configuración:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
minReadySeconds: 5
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Cree el objeto usando kubectl apply:
kubectl apply -f https://k8s.io/examples/application/simple_deployment.yaml
Despliegue la configuración activa usando kubectl get:
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
La salida le mostrará que la anotación kubectl.kubernetes.io/last-applied-configuration
fue escrita a la configuración activa, y es consistente con los contenidos del archivo
de configuración:
kind: Deployment
metadata:
annotations:
# ...
# Esta es la representación JSON de simple_deployment.yaml
# Fue escrita por kubectl apply cuando el objeto fue creado
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.14.2","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
# ...
minReadySeconds: 5
selector:
matchLabels:
# ...
app: nginx
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.14.2
# ...
name: nginx
ports:
- containerPort: 80
# ...
# ...
# ...
# ...
De manera directa, actualice el campo replicas en la configuración activa usando kubectl scale.
En este caso no se usa kubectl apply:
kubectl scale deployment/nginx-deployment --replicas=2
Despliegue la configuración activa usando kubectl get:
kubectl get deployment nginx-deployment -o yaml
La salida le muestra que el campo replicas ha sido definido en 2, y que la
anotación last-applied-configuration no contiene el campo replicas:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
# ...
# note que la anotación no contiene replicas
# debido a que el objeto no fue actualizado usando apply
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.14.2","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
replicas: 2 # definido por scale
# ...
minReadySeconds: 5
selector:
matchLabels:
# ...
app: nginx
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.14.2
# ...
name: nginx
ports:
- containerPort: 80
# ...
Actualice el archivo de configuración simple_deployment.yaml para cambiar el campo image
de nginx:1.14.2 a nginx:1.16.1, y elimine el campo minReadySeconds:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16.1 # actualice el valor de image
ports:
- containerPort: 80
Aplique los cambios realizados al archivo de configuración:
kubectl diff -f https://k8s.io/examples/application/update_deployment.yaml
kubectl apply -f https://k8s.io/examples/application/update_deployment.yaml
Despliegue la configuración activa usando kubectl get:
kubectl get -f https://k8s.io/examples/application/update_deployment.yaml -o yaml
La salida le mostrará los siguientes cambios hechos a la configuración activa:
replicas retiene el valor de 2 definido por kubectl scale.
Esto es posible ya que el campo fue omitido en el archivo de configuración.image ha sido actualizado de nginx:1.16.1 a nginx:1.14.2.last-applied-configuration ha sido actualizada con la nueva imagen.minReadySeconds ha sido despejado.last-applied-configuration ya no contiene el campo minReadySecondsapiVersion: apps/v1
kind: Deployment
metadata:
annotations:
# ...
# La anotación contiene la imagen acutalizada a nginx 1.11.9,
# pero no contiene la actualización de las replicas a 2
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.16.1","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
replicas: 2 # Definido por `kubectl scale`. Ignorado por `kubectl apply`.
# minReadySeconds fue despejado por `kubectl apply`
# ...
selector:
matchLabels:
# ...
app: nginx
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.16.1 # Definido `kubectl apply`
# ...
name: nginx
ports:
- containerPort: 80
# ...
# ...
# ...
# ...
kubectl apply con comandos de configuración imperativa de objetos
como create y replace. Esto se debe a que create
y replace no retienen la anotación kubectl.kubernetes.io/last-applied-configuration
que kubectl apply utiliza para calcular los cambios por realizar.Hay dos opciones diferentes para eliminar objetos gestionados por kubectl apply.
kubectl delete -f <archivo>La manera recomendada de eliminar objetos de manera manual es utilizando el comando imperativo, ya que es más explícito en relación a lo que será eliminado, y es menos probable que resulte en algo siendo eliminado sin la intención del usuario.
kubectl delete -f <archivo>
kubectl apply -f <directorio/> --prune -l etiqueta=deseadaÚnicamente utilice esta opción si está seguro de saber lo que está haciendo.
kubectl apply --prune se encuentra aún en alpha, y cambios incompatibles con versiones previas
podrían ser introducidos en lanzamientos futuros.Como una alternativa a kubectl delete, puede usar kubectl apply para identificar objetos a ser
eliminados, luego de que sus archivos de configuración han sido eliminados del directorio. El commando apply con --prune
consulta a la API del servidor por todos los objetos que coincidan con un grupo de etiquetas, e intenta relacionar
la configuración obtenida de los objetos activos contra los objetos según sus archivos de configuración.
Si un objeto coincide con la consulta, y no tiene un archivo de configuración en el directorio, pero si
tiene una anotación last-applied-configuration, entonces será eliminado.
kubectl apply -f <directorio/> --prune -l <etiquetas>
apply con --prune debería de ser ejecutado únicamente en contra del directorio
raíz que contiene los archivos de configuración. Ejecutarlo en contra de sub-directorios
podría causar que objetos sean eliminados no intencionalmente, si son retornados en la
consulta por selección de etiqueta usando -l <etiquetas> y no existen en el subdirectorio.Puede usar kubectl get con -o yaml para ver la configuración de objetos activos:
kubectl get -f <archivo|url> -o yaml
Cuando kubectl apply actualiza la configuración activa para un objeto, lo hace enviando
una solicitud de patch al servidor de API. El patch define actualizaciones para campos
específicos en la configuración del objeto activo. El comando kubectl apply calcula esta solicitud
de patch usando el archivo de configuración, la configuración activa, y la anotación last-applied-configuration
almacenada en la configuración activa.
El comando kubectl apply escribe los contenidos de la configuración a la anotación
kubectl.kubernetes.io/last-applied-configuration. Esto es usado para identificar aquellos campos
que han sido eliminados de la configuración y deben ser limpiados. Los siguientes pasos
son usados para calcular que campos deben ser eliminados o definidos:
last-applied-configuration pero ausentes en el archivo de configuración.A continuación un ejemplo. Suponga que este es el archivo de configuración para un objeto de tipo Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16.1 # actualice el valor de image
ports:
- containerPort: 80
También, suponga que esta es la configuración activa para ese mismo objeto de tipo Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
# ...
# tome nota de que la anotación no contiene un valor para replicas
# dado que no fue actualizado usando el comando apply
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.14.2","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
replicas: 2 # definidas por scale
# ...
minReadySeconds: 5
selector:
matchLabels:
# ...
app: nginx
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.14.2
# ...
name: nginx
ports:
- containerPort: 80
# ...
Estos son los cálculos de unión que serían realizados por kubectl apply:
last-applied-configuration
y comparándolos con los valores en el archivo de configuración.
Limpiar los campos definidos en null de manera explícita en el archivo de configuración
sin tomar en cuenta si se encuentran presentes en la anotación last-applied-configuration.
En este ejemplo, minReadySeconds aparece en la anotación
last-applied-configuration pero no aparece en el archivo de configuración.
Acción: Limpiar minReadySeconds de la configuración activa.image
en el archivo de configuración, no coincide con el valor en la configuración activa.
Acción: Definir el campo image en la configuración activa.last-applied-configuration para que sea consistente
con el archivo de configuración.Esta es la configuración activa como resultado de esta unión:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
# ...
# La anotación contiene la imágen actualizada a nginx 1.11.9,
# pero no contiene la actualización a 2 replicas
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment",
"metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},
"spec":{"selector":{"matchLabels":{"app":nginx}},"template":{"metadata":{"labels":{"app":"nginx"}},
"spec":{"containers":[{"image":"nginx:1.16.1","name":"nginx",
"ports":[{"containerPort":80}]}]}}}}
# ...
spec:
selector:
matchLabels:
# ...
app: nginx
replicas: 2 # Definido por `kubectl scale`. Ignorado por `kubectl apply`.
# minReadySeconds eliminado por `kubectl apply`
# ...
template:
metadata:
# ...
labels:
app: nginx
spec:
containers:
- image: nginx:1.16.1 # Definido por `kubectl apply`
# ...
name: nginx
ports:
- containerPort: 80
# ...
# ...
# ...
# ...
La manera en la que los campos en un archivo de configuración son unidos con la configuración activa depende del tipo de campo. Existen varios tipos de campos:
primitivo: Campos de cadena de texto (string), enteros (integer), o lógicos (boolean).
Por ejemplo, image y replicas son campos de tipo primitivo. Acción: Reemplazarlos.
mapa, también llamados objeto: Campo de tipo mapa o un tipo
complejo que contiene sub-campos. Por ejemplo, labels,
annotations,spec y metadata son todos mapas. Acción: Unir los elementos o sub-campos.
lista: Campos que contienen una lista de elementos que pueden ser de tipo primitivo o mapa.
Como ejemplos, containers, ports, y args son listas. Acción: Varía.
Cuando kubectl apply actualiza un campo de tipo mapa o lista, típicamente no reemplaza
el campo completo, sino actualiza los sub-elementos individuales.
Por ejemplo, cuando se hace una unión del campo spec en un Deployment, el spec
completo no es reemplazado, por el contrario, únicamente los sub-campos de spec como
replica son comparados y unidos.
Campos primitivos son limpiados o reemplazados.
- determina que "no aplica" debido a que el valor no es utilizado.| Campo en el archivo de configuración | Campo en la configuración activa | Campo en last-applied-configuration | Acción |
|---|---|---|---|
| Si | Si | - | Define el valor en el archivo de configuración como activo. |
| Si | No | - | Define el valor a la configuración local. |
| No | - | Si | Elimina de la configuración activa. |
| No | - | No | No hacer nada. Mantiene el valor activo. |
Los campos que conjuntamente representan un mapa, son unidos al comparar cada uno de los subcampos o elementos del mapa:
- determina que "no aplica" debido a que el valor no es utilizado.| Propiedad en archivo de configuración | Propiedad en configuración activa | Campo en last-applied-configuration | Acción |
|---|---|---|---|
| Si | Si | - | Comparar valores de sub-propiedades. |
| Si | No | - | Usar configuración local. |
| No | - | Si | Eliminar de la configuración activa. |
| No | - | No | No hacer nada. Mantener el valor activo. |
El unir cambios en una lista utiliza una de tres posibles estrategias:
Se define la estrategia elegida con base en cada campo.
Trata la lista como si fuese un campo primitivo. Reemplaza o elimina la lista completa. Esto preserva el orden de los elementos.
Ejemplo: Usando kubectl apply para actualizar el campo args de un Contenedor en un Pod.
Esto define el valor de args en la configuración activa, al valor en el archivo de configuración.
Cualquier elemento de args que haya sido previamente agregado a la configuración activa se perderá.
El orden de los elementos definidos en args en el archivo de configuración, serán conservados
en la configuración activa.
# valor en last-applied-configuration
args: ["a", "b"]
# valores en archivo de configuración
args: ["a", "c"]
# configuración activa
args: ["a", "b", "d"]
# resultado posterior a la unión
args: ["a", "c"]
Explicación: La unión utilizó los valores del archivo de configuración para definir los nuevos valores de la lista.
Trata la lista como un mapa, y trata cada campo específico de cada elemento como una llave. Agrega, elimina o actualiza elementos individuales. Esta operación no conserva el orden.
Esta estrategia de unión utiliza una etiqueta especial en cada campo llamada patchMergeKey. La etiqueta
patchMergeKey es definida para cada campo en el código fuente de Kubernetes:
types.go
Al unir una lista de mapas, el campo especificado en patchMergeKey para el elemento dado
se utiliza como un mapa de llaves para ese elemento.
Ejemplo: Utilice kubectl apply para actualizar el campo containers de un PodSpec.
Esto une la lista como si fuese un mapa donde cada elemento utiliza name por llave.
# valor en last-applied-configuration
containers:
- name: nginx
image: nginx:1.16
- name: nginx-helper-a # llave: nginx-helper-a; será eliminado en resultado
image: helper:1.3
- name: nginx-helper-b # llave: nginx-helper-b; será conservado
image: helper:1.3
# valor en archivo de configuración
containers:
- name: nginx
image: nginx:1.16
- name: nginx-helper-b
image: helper:1.3
- name: nginx-helper-c # llavel: nginx-helper-c; será agregado en el resultado
image: helper:1.3
# configuración activa
containers:
- name: nginx
image: nginx:1.16
- name: nginx-helper-a
image: helper:1.3
- name: nginx-helper-b
image: helper:1.3
args: ["run"] # Campo será conservado
- name: nginx-helper-d # llave: nginx-helper-d; será conservado
image: helper:1.3
# resultado posterior a la unión
containers:
- name: nginx
image: nginx:1.16
# Elemento nginx-helper-a fue eliminado
- name: nginx-helper-b
image: helper:1.3
args: ["run"] # Campo fue conservado
- name: nginx-helper-c # Elemento fue agregado
image: helper:1.3
- name: nginx-helper-d # Elemento fue ignorado
image: helper:1.3
Explicación:
args
en la configuración activa. kubectl apply pudo identificar que
el contenedor "nginx-helper-b" en la configuración activa es el mismo
"nginx-helper-b" que aparece en el archivo de configuración, aún teniendo diferentes
valores en los campos (no existe args en el archivo de configuración). Esto sucede
debido a que el valor del campo patchMergeKey (name) es idéntico en ambos.A partir de Kubernetes 1.5, el unir listas de elementos primitivos no es soportado.
patchStrategy en types.go es la que
determina cual de las estrategias aplica para cualquier campo en particular.
Para campos de tipo lista, el campo será reemplazado cuando no exista una especificación de patchStrategy.El Servidor de API define algunos campos a sus valores por defecto si no son especificados al momento de crear un objeto.
Aquí puede ver un archivo de configuración para un Deployment. Este archivo no especifica
el campo strategy:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
minReadySeconds: 5
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Cree un nuevo objeto kubectl apply:
kubectl apply -f https://k8s.io/examples/application/simple_deployment.yaml
Despliegue la configuración activa usando kubectl get:
kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml
La salida muestra que el servidor de API definió varios campos con los valores por defecto en la configuración activa. Estos campos no fueron especificados en el archivo de configuración.
apiVersion: apps/v1
kind: Deployment
# ...
spec:
selector:
matchLabels:
app: nginx
minReadySeconds: 5
replicas: 1 # valor por defecto definido por apiserver
strategy:
rollingUpdate: # valor por defecto definido por apiserver - derivado de strategy.type
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate # valor por defecto definido por apiserver
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.14.2
imagePullPolicy: IfNotPresent # valor por defecto definido por apiserver
name: nginx
ports:
- containerPort: 80
protocol: TCP # valor por defecto definido por apiserver
resources: {} # valor por defecto definido por apiserver
terminationMessagePath: /dev/termination-log # valor por defecto definido por apiserver
dnsPolicy: ClústerFirst # valor por defecto definido por apiserver
restartPolicy: Always # valor por defecto definido por apiserver
securityContext: {} # valor por defecto definido por apiserver
terminationGracePeriodSeconds: 30 # valor por defecto definido por apiserver
# ...
En una solicitud de patch, los campos definidos a valores por defecto no son redefinidos a excepción de cuando hayan sido limpiados de manera explícita como parte de la solicitud de patch. Esto puede causar comportamientos no esperados para campos cuyo valor por defecto es basado en los valores de otros campos. Cuando el otro campo ha cambiado, el valor por defecto de ellos no será actualizado de no ser que sean limpiados de manera explícita.
Por esta razón, se recomienda que algunos campos que reciben un valor por defecto del servidor sean definidos de manera explícita en los archivos de configuración, aun cuando el valor definido sea idéntico al valor por defecto. Esto facilita la identificación de valores conflictivos que podrían no ser revertidos a valores por defecto por parte del servidor.
Ejemplo:
# last-applied-configuration
spec:
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
# archivo de configuración
spec:
strategy:
type: Recreate # valor actualizado
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
# configuración activa
spec:
strategy:
type: RollingUpdate # valor por defecto
rollingUpdate: # valor por defecto derivado del campo type
maxSurge : 1
maxUnavailable: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
# resultado posterior a la unión - ERROR!
spec:
strategy:
type: Recreate # valor actualizado: incompatible con RollingUpdate
rollingUpdate: # valor por defecto: incompatible con "type: Recreate"
maxSurge : 1
maxUnavailable: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Explicación:
strategy.type.strategy.type a su valor por defecto de RollingUpdate y
agrega los valores por defecto a strategy.rollingUpdate.strategy.type a Recreate. Los valores de strategy.rollingUpdate
se mantienen en su configuración por defecto, sin embargo el servidor espera que se limpien.
Si los valores de strategy.rollingUpdate hubiesen sido definidos inicialmente en el archivo
de configuración, hubiese sido más claro que requerían ser eliminados.strategy.rollingUpdate no fue eliminado. El campo strategy.rollingupdate
no puede estar definido, si el valor de strategy.type es Recreate.Recomendación: Estos campos deberían de ser definidos de manera explícita en el archivo de configuración:
Campos que no aparecen en el archivo de configuración pueden ser limpiados si se define su valor
a null y luego se aplica el archivo de configuración.
Para los campos definidos a valores por defecto por el servidor, esto provoca que se reestablezca
a sus valores por defecto.
Estos son los únicos métodos que debe usar para cambiar un campo individual de un objeto:
kubectl apply.kubectl scale.Añada el campo al archivo de configuración, y no realice nuevas actualizaciones a la configuración
activa que no sucedan por medio de kubectl apply.
A partir de Kubernetes 1.5, el cambiar un campo que ha sido definido por medio de un archivo de configuración para que sea modificado por un escritor imperativo requiere pasos manuales:
kubectl.kubernetes.io/last-applied-configuration en el objeto activo.Los objetos en Kubernetes deberían de ser gestionados utilizando únicamente un método a la vez. El alternar de un método a otro es posible, pero es un proceso manual.
El migrar de gestión imperativa utilizando comandos a la gestión declarativa de objetos requiere varios pasos manuales:
Exporte el objeto activo a un archivo local de configuración:
kubectl get <tipo>/<nombre> -o yaml > <tipo>_<nombre>.yaml
Elimine de manera manual el campo status del archivo de configuración.
Este paso es opcional, ya que `kubectl apply` no actualiza el campo `status`
aunque este presente en el archivo de configuración.
Defina la anotación kubectl.kubernetes.io/last-applied-configuration en el objeto:
kubectl replace --save-config -f <tipo>_<nombre>.yaml
Modifique el proceso para usar kubectl apply para gestionar el objeto de manera exclusiva.
Defina la anotación kubectl.kubernetes.io/last-applied-configuration en el objeto:
kubectl replace --save-config -f <tipo>_<nombre>.yaml
Modifique el proceso para usar kubectl apply para gestionar el objeto de manera exclusiva.
La forma recomendada es definir una etiqueta única e inmutable para PodTemplate usada únicamente por el selector del controlador sin tener ningún otro significado semántico.
Ejemplo:
selector:
matchLabels:
controller-selector: "apps/v1/deployment/nginx"
template:
metadata:
labels:
controller-selector: "apps/v1/deployment/nginx"
Kustomize es una herramienta independiente para personalizar objetos de Kubernetes a través de un archivo de kustomization.
Desde la versión 1.14, Kubectl también admite la gestión de objetos de Kubernetes utilizando un archivo de kustomización. Para ver Recursos encontrados en un directorio que contiene un archivo de kustomización, ejecuta el siguiente comando:
kubectl kustomize <directorio_de_kustomización>
Para aplicar esos Recursos, ejecuta kubectl apply con la bandera --kustomize o -k :
kubectl apply -k <directorio_de_kustomización>
Instala kubectl.
Debes tener un cluster Kubernetes a tu dispocición, y la herramienta de línea de comandos kubectl debe estar configurada. Si no tienes un cluster, puedes crear uno utilizando Minikube,
o puedes utilizar una de las siguientes herramientas en línea:
Para comprobar la versión, introduzca kubectl version.
Kustomize es una herramienta para personalizar configuraciones de Kubernetes. Ofrece características para manejar archivos de configuración de aplicaciones, tales como:
ConfigMaps y Secrets almacenan configuración o datos sensibles utilizados por otros objetos de Kubernetes, como los Pods. La fuente de verdad de los ConfigMaps o Secrets suele ser externa a un clúster, como un archivo .properties o un archivo de clave SSH.
Kustomize tiene secretGenerator y configMapGenerator, que generan Secret y ConfigMap a partir de archivos o literales.
Para generar un ConfigMap desde un archivo, añade una entrada en la lista files en configMapGenerator. Aquí tienes un ejemplo de cómo generar un ConfigMap con un elemento de datos de un archivo .properties:
# Crear un archivo application.properties
cat <<EOF >application.properties
FOO=Bar
EOF
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-1
files:
- application.properties
EOF
El ConfigMap generado se puede examinar con el siguiente comando:
kubectl kustomize ./
El ConfigMap generado es:
apiVersion: v1
data:
application.properties: |
FOO=Bar
kind: ConfigMap
metadata:
name: example-configmap-1-8mbdf7882g
Para generar un ConfigMap desde un archivo env, añade una entrada en la lista de envs en configMapGenerator. Aquí tienes un ejemplo de cómo generar un ConfigMap con un elemento de datos de un archivo .env:
# Crear un archivo .env
cat <<EOF >.env
FOO=Bar
EOF
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-1
envs:
- .env
EOF
El ConfigMap generado se puede examinar con el siguiente comando:
kubectl kustomize ./
El ConfigMap generado es:
apiVersion: v1
data:
FOO: Bar
kind: ConfigMap
metadata:
name: example-configmap-1-42cfbf598f
.env se convierte en una clave separada en el ConfigMap que generas. Esto es diferente del ejemplo anterior, que incorpora un archivo llamado application.properties (y todas sus entradas) como el valor para una única clave.Los ConfigMaps también pueden generarse a partir de pares clave-valor literales. Para generar un ConfigMap a partir de una literal clave-valor, añade una entrada a la lista literals en configMapGenerator. Aquí hay un ejemplo de cómo generar un ConfigMap con un elemento de datos de un par clave-valor:
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-2
literals:
- FOO=Bar
EOF
El ConfigMap generado se puede verificar con el siguiente comando:
kubectl kustomize ./
El ConfigMap generado es:
apiVersion: v1
data:
FOO: Bar
kind: ConfigMap
metadata:
name: example-configmap-2-g2hdhfc6tk
Para usar un ConfigMap generado en un Deployment, refiérelo por el nombre del configMapGenerator. Kustomize reemplazará automáticamente este nombre con el nombre generado.
Este es un ejemplo de un Deployment que utiliza un ConfigMap generado:
# Crear un archivo application.properties
cat <<EOF >application.properties
FOO=Bar
EOF
cat <<EOF >deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app
volumeMounts:
- name: config
mountPath: /config
volumes:
- name: config
configMap:
name: example-configmap-1
EOF
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
configMapGenerator:
- name: example-configmap-1
files:
- application.properties
EOF
Genera el ConfigMap y Deployment:
kubectl kustomize ./
El Deployment generado hara referencia al ConfigMap generado por nombre:
apiVersion: v1
data:
application.properties: |
FOO=Bar
kind: ConfigMap
metadata:
name: example-configmap-1-g4hk9g2ff8
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: my-app
name: my-app
spec:
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- image: my-app
name: app
volumeMounts:
- mountPath: /config
name: config
volumes:
- configMap:
name: example-configmap-1-g4hk9g2ff8
name: config
Puedes generar Secrets a partir de archivos o pares clave-valor literales. Para generar un Secret a partir de un archivo, añade una entrada a la lista files en secretGenerator. Aquí tienes un ejemplo de cómo generar un Secret con un elemento de datos de un archivo.
# Crea un archivo password.txt
cat <<EOF >./password.txt
username=admin
password=secret
EOF
cat <<EOF >./kustomization.yaml
secretGenerator:
- name: example-secret-1
files:
- password.txt
EOF
El Secret generado se vería de la siguiente manera:
apiVersion: v1
data:
password.txt: dXNlcm5hbWU9YWRtaW4KcGFzc3dvcmQ9c2VjcmV0Cg==
kind: Secret
metadata:
name: example-secret-1-t2kt65hgtb
type: Opaque
Para generar un Secret a partir de una literal clave-valor, añade una entrada a la lista literals en secretGenerator. Aquí tienes un ejemplo de cómo generar un Secret con un elemento de datos de un par clave-valor.
cat <<EOF >./kustomization.yaml
secretGenerator:
- name: example-secret-2
literals:
- username=admin
- password=secret
EOF
El Secret generado se verá de la siguiente manera:
apiVersion: v1
data:
password: c2VjcmV0
username: YWRtaW4=
kind: Secret
metadata:
name: example-secret-2-t52t6g96d8
type: Opaque
Al igual que los ConfigMaps, los Secrets generados pueden utilizarse en Deployments refiriéndose al nombre del secretGenerator.
# Crea un archivo password.txt
cat <<EOF >./password.txt
username=admin
password=secret
EOF
cat <<EOF >deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app
volumeMounts:
- name: password
mountPath: /secrets
volumes:
- name: password
secret:
secretName: example-secret-1
EOF
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
secretGenerator:
- name: example-secret-1
files:
- password.txt
EOF
Los ConfigMaps y Secrets generados tienen un sufijo de hash de contenido añadido. Esto asegura que se genere un nuevo ConfigMap o Secret cuando se cambian los contenidos. Para desactivar el comportamiento de añadir un sufijo, se puede utilizar generatorOptions. Además, es posible especificar opciones transversales para los ConfigMaps y Secrets generados.
cat <<EOF >./kustomization.yaml
configMapGenerator:
- name: example-configmap-3
literals:
- FOO=Bar
generatorOptions:
disableNameSuffixHash: true
labels:
type: generated
annotations:
note: generated
EOF
Ejecuta kubectl kustomize ./ para visualizar el ConfigMap generado:
apiVersion: v1
data:
FOO: Bar
kind: ConfigMap
metadata:
annotations:
note: generated
labels:
type: generated
name: example-configmap-3
Es bastante común establecer campos transversales para todos los recursos de Kubernetes en un proyecto. Algunos casos de uso para establecer campos transversales:
Aquí hay un ejemplo:
# Crea un deployment.yaml
cat <<EOF >./deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
EOF
cat <<EOF >./kustomization.yaml
namespace: my-namespace
namePrefix: dev-
nameSuffix: "-001"
commonLabels:
app: bingo
commonAnnotations:
oncallPager: 800-555-1212
resources:
- deployment.yaml
EOF
Ejecuta kubectl kustomize ./ para ver que esos campos están todos establecidos en el Recurso Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
oncallPager: 800-555-1212
labels:
app: bingo
name: dev-nginx-deployment-001
namespace: my-namespace
spec:
selector:
matchLabels:
app: bingo
template:
metadata:
annotations:
oncallPager: 800-555-1212
labels:
app: bingo
spec:
containers:
- image: nginx
name: nginx
Es común componer un conjunto de recursos en un proyecto y gestionarlos dentro del mismo archivo o directorio.
Kustomize ofrece la composición de recursos desde diferentes archivos y la aplicación de parches u otras personalizaciones a ellos.
Kustomize admite la composición de diferentes recursos. El campo resources, en el archivo kustomization.yaml, define la lista de recursos para incluir en una configuración. Establece la ruta al archivo de configuración de un recurso en la lista resources.
Aquí hay un ejemplo de una aplicación NGINX compuesta por un Deployment y un Service:
# Crea un archivo deployment.yaml
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
EOF
# Crea un archivo service.yaml
cat <<EOF > service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
EOF
# Crea un kustomization.yaml que los integra
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
- service.yaml
EOF
Los Recursos de kubectl kustomize ./ contienen tanto los objetos de Deployment como los de Service.
Los parches pueden usarse para aplicar diferentes personalizaciones a los recursos. Kustomize admite diferentes mecanismos de parcheo a través de patchesStrategicMerge y patchesJson6902. patchesStrategicMerge es una lista de rutas de archivo. Cada archivo debe resolverse en un parche de fusión estratégica. Los nombres dentro de los parches deben coincidir con los nombres de recursos que ya están cargados. Se recomiendan pequeños parches que hagan una sola cosa. Por ejemplo, crear un parche para aumentar el número de réplicas del Deployment y otro parche para establecer el límite de memoria.
# Crea un archivo deployment.yaml
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
EOF
# Crea un parche increase_replicas.yaml
cat <<EOF > increase_replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 3
EOF
# Crea otro parche set_memory.yaml
cat <<EOF > set_memory.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
template:
spec:
containers:
- name: my-nginx
resources:
limits:
memory: 512Mi
EOF
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
patchesStrategicMerge:
- increase_replicas.yaml
- set_memory.yaml
EOF
Ejecuta kubectl kustomize ./ para visualizar el Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 3
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- image: nginx
name: my-nginx
ports:
- containerPort: 80
resources:
limits:
memory: 512Mi
No todos los recursos o campos admiten parches de fusión estratégica. Para admitir la modificación de campos arbitrarios en recursos arbitrarios,
Kustomize ofrece la implementacion a través de JSON patch patchesJson6902.
Para encontrar el Recurso correcto para un parche Json, el grupo, versión, tipo y nombre de ese recurso necesitan ser especificados en kustomization.yaml. Por ejemplo, aumentar el número de réplicas de un objeto de Deployment también se puede hacer a través de patchesJson6902.
# Crea un archivo deployment.yaml
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
EOF
# Crea un parche en json
cat <<EOF > patch.yaml
- op: replace
path: /spec/replicas
value: 3
EOF
# Crea un kustomization.yaml
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
patchesJson6902:
- target:
group: apps
version: v1
kind: Deployment
name: my-nginx
path: patch.yaml
EOF
Ejecuta kubectl kustomize ./ para ver que el campo replicas está actualizado:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 3
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- image: nginx
name: my-nginx
ports:
- containerPort: 80
Además de los parches, Kustomize también ofrece personalizar imágenes de contenedores o inyectar valores de campos de otros objetos en contenedores sin crear parches. Por ejemplo, puedes cambiar la imagen utilizada dentro de los contenedores especificando la nueva imagen en el campo images en kustomization.yaml.
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
EOF
cat <<EOF >./kustomization.yaml
resources:
- deployment.yaml
images:
- name: nginx
newName: my.image.registry/nginx
newTag: "1.4.0"
EOF
Ejecuta kubectl kustomize ./ para ver que el campo image ha sido actualizado:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 2
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- image: my.image.registry/nginx:1.4.0
name: my-nginx
ports:
- containerPort: 80
A veces, la aplicación que se ejecuta en un Pod puede necesitar usar valores de configuración de otros objetos. Por ejemplo, un Pod de un objeto de Deployment necesita leer el nombre del Service correspondiente desde Env o como un argumento de comando.
Dado que el nombre del Service puede cambiar a medida que se agrega namePrefix o nameSuffix en el archivo kustomization.yaml. No se recomienda codificar de manera fija el nombre del Service en el argumento del comando. Para este uso, Kustomize puede inyectar el nombre del Service en los contenedores a través de vars.
# Crea un archivo deployment.yaml (citando el delimitador de documento aquí)
cat <<'EOF' > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
command: ["start", "--host", "$(MY_SERVICE_NAME)"]
EOF
# Crea un archivo service.yaml
cat <<EOF > service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
EOF
cat <<EOF >./kustomization.yaml
namePrefix: dev-
nameSuffix: "-001"
resources:
- deployment.yaml
- service.yaml
vars:
- name: MY_SERVICE_NAME
objref:
kind: Service
name: my-nginx
apiVersion: v1
EOF
Ejecuta kubectl kustomize ./ para ver que el nombre del Service inyectado en la sección de contaierns es dev-my-nginx-001:
apiVersion: apps/v1
kind: Deployment
metadata:
name: dev-my-nginx-001
spec:
replicas: 2
selector:
matchLabels:
run: my-nginx
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- command:
- start
- --host
- dev-my-nginx-001
image: nginx
name: my-nginx
Kustomize tiene los conceptos de bases y overlays. Una base es un directorio con un kustomization.yaml, que contiene un conjunto de recursos y personalización asociada. Una base puede ser un directorio local o un directorio de un repositorio remoto, siempre que haya un kustomization.yaml presente dentro. Un overlay es un directorio con un kustomization.yaml que se refiere a otros directorios de kustomization como sus bases. Una base no tiene conocimiento de un overlay y puede ser utilizada en múltiples overlays. Un overlay puede tener múltiples bases y compone todos los recursos de las bases y también puede tener personalizaciones encima de ellos.
Aquí hay un ejemplo de una base:
# Crea un directorio que tendrá la **base**
mkdir base
# Crea el archivo base/deployment.yaml
cat <<EOF > base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
EOF
# Crea el archivo base/service.yaml
cat <<EOF > base/service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
protocol: TCP
selector:
run: my-nginx
EOF
# Crea un archivo base/kustomization.yaml
cat <<EOF > base/kustomization.yaml
resources:
- deployment.yaml
- service.yaml
EOF
Esta base puede ser utilizada en múltiples overlays. Puedes agregar diferentes namePrefix u otros campos transversales en diferentes overlays. Aquí hay dos overlays utilizando la misma base.
mkdir dev
cat <<EOF > dev/kustomization.yaml
resources:
- ../base
namePrefix: dev-
EOF
mkdir prod
cat <<EOF > prod/kustomization.yaml
resources:
- ../base
namePrefix: prod-
EOF
Usa --kustomize o -k en comandos de kubectl para reconocer recursos gestionados por
kustomization.yaml.
Nota que -k debe apuntar a un directorio de kustomization, tal como:
kubectl apply -k <kustomization directory>/
Dando como resultado el siguientekustomization.yaml,
# Crea un archivo deployment.yaml
cat <<EOF > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
EOF
# Crea un archivo kustomization.yaml
cat <<EOF >./kustomization.yaml
namePrefix: dev-
commonLabels:
app: my-nginx
resources:
- deployment.yaml
EOF
Ejecuta el siguiente comando para aplicar el objeto de Deployment dev-my-nginx:
> kubectl apply -k ./
deployment.apps/dev-my-nginx created
Ejecuta uno de los siguientes comandos para ver el objeto de Deployment dev-my-nginx:
kubectl get -k ./
kubectl describe -k ./
Ejecuta el siguiente comando para comparar el objecto Deployment dev-my-nginx contra el
estado en el que estaría el clúster si se aplicara el manifiesto:
kubectl diff -k ./
Ejecuta el siguiente comando para eliminar el objeto de Deployment dev-my-nginx:
> kubectl delete -k ./
deployment.apps "dev-my-nginx" deleted
| Campo | Tipo | Explicación |
|---|---|---|
| namespace | string | Agregar namespace a todos los recursos |
| namePrefix | string | El valor de este campo se antepone a los nombres de todos los recursos |
| nameSuffix | string | El valor de este campo se añade al final de los nombres de todos los recursos |
| commonLabels | map[string]string | Etiquetas para agregar a los recursos y selectores. |
| commonAnnotations | map[string]string | Anotaciones para agregar a todos los recursos |
| resources | []string | Cada entrada en esta lista debe resolverse en un archivo de configuración de recurso existente |
| configMapGenerator | []ConfigMapArgs | Cada entrada en esta lista genera un ConfigMap |
| secretGenerator | []SecretArgs | Cada entrada en esta lista genera un Secret |
| generatorOptions | GeneratorOptions | Modifica comportamientos de todos los generadores de ConfigMap y Secret |
| bases | []string | Cada entrada en esta lista debe resolverse en un directorio que contenga un archivo kustomization.yaml |
| patchesStrategicMerge | []string | Cada entrada en esta lista debe resolver un parche de fusión estratégica de un objeto de Kubernetes |
| patchesJson6902 | []Patch | Cada entrada en esta lista debe resolverse en un objeto de Kubernetes y un parche Json |
| vars | []Var | Cada entrada es para capturar texto del campo de un recurso |
| images | []Image | Cada entrada es para modificar el nombre, las etiquetas y/o el digesto de una imagen sin crear parches |
| configurations | []string | Cada entrada en esta lista debe resolverse en un archivo que contenga Configuraciones de transformador de Kustomize |
| crds | []string | Cada entrada en esta lista debería resolver a un archivo de definición OpenAPI para los tipos de Kubernetes. |
Los objetos de Kubernetes se pueden crear, actualizar y eliminar utilizando la herramienta
de línea de comandos kubectl junto con un archivo de configuración de objetos escrito en YAML o JSON.
Este documento explica cómo definir y gestionar objetos utilizando archivos de configuración.
Instalar kubectl.
Debes tener un cluster Kubernetes a tu dispocición, y la herramienta de línea de comandos kubectl debe estar configurada. Si no tienes un cluster, puedes crear uno utilizando Minikube,
o puedes utilizar una de las siguientes herramientas en línea:
Para comprobar la versión, introduzca kubectl version.
La herramienta kubectl admite tres tipos de administración de objetos:
Consulta Administración de objetos de Kubernetes para una discusión de las ventajas y desventajas de cada tipo de administración de objetos.
Puede usar kubectl create -f para crear un objeto a partir de un archivo de configuración.
Consulta la referencia de la API de Kubernetes
para mas detalles.
kubectl create -f <filename|url>replace elimina todas las
partes de la especificación no especificadas en el archivo de configuración. Esto no debe
usarse con objetos cuyas especificaciones son administradas
parcialmente por el clúster, como Services de tipo LoadBalancer, donde el
campo externalIPs se administra independientemente del archivo de
configuración. Los campos administrados de forma independiente deben copiarse en
el archivo de configuración para evitar que replace los elimine.Puedes usar kubectl replace -f para actualizar un objeto en activo de acuerdo con un archivo de configuración.
kubectl replace -f <filename|url>Puedes usar kubectl delete -f para eliminar un objeto que se describe en un
archivo de configuración.
kubectl delete -f <filename|url>Si el archivo de configuración especifica el campo generateName en la sección metadata en lugar del campo name, no puede eliminar el objeto usando kubectl delete -f <filename|url>. Tendrás que usar otras banderas para eliminar el objeto. Por ejemplo:
kubectl delete <type> <name>
kubectl delete <type> -l <label>
Puedes usar kubectl get -f para ver información sobre un objeto que está
descrito en un archivo de configuración.
kubectl get -f <filename|url> -o yamlLa bandera -o yaml especifica que se imprime la configuración completa del objeto. Utiliza kubectl get -h para ver una lista de opciones.
Los comandos create, replace y delete funcionan bien cuando la configuración de cada objeto está completamente definida y registrada en su archivo de configuración. Sin embargo, cuando se actualiza un objeto activo y las actualizaciones no se combinan en su archivo de configuración las actualizaciones se perderán la próxima vez que se ejecute un replace. Esto puede suceder si un controlador, como un HorizontalPodAutoscaler, realiza actualizaciones directamente a un objeto en activo.
Los comandos create, replace y delete funcionan bien cuando la configuración de cada objeto
está completamente definida y registrada en su archivo
de configuración. Sin embargo, cuando se actualiza un objeto activo y las actualizaciones no se combinan
en su archivo de configuración las actualizaciones se perderán la próxima vez que
se ejecute un replace. Esto puede suceder si un controlador, como un
HorizontalPodAutoscaler, realice actualizaciones directamente a un objeto en activo.
Ejemplo:
Si necesitas admitir varios escritores en el mismo objeto, puede usar kubectl apply para administrar el objeto.
Supongamos que tienes la URL de un archivo de configuración de objeto. Puedes usar
kubectl create -f <url> --edit
La migración de comandos imperativos a la configuración de objetos imperativos implica varios pasos manuales.
Exporta el objeto en vivo a un archivo de configuración de objeto local.
kubectl get <kind>/<name> -o yaml > <kind>_<name>.yaml
Elimina manualmente el campo de estado del archivo de configuración del objeto.
Para la gestión posterior de objetos, utiliza replace exclusivamente.
kubectl replace -f <kind>_<name>.yaml
El enfoque recomendado es definir una etiqueta PodTemplate única e inmutable utilizada únicamente por el selector del controlador sin ningún otro significado semántico.
Etiqueta de ejemplo:
selector:
matchLabels:
controller-selector: "apps/v1/deployment/nginx"
template:
metadata:
* [Referencia de la API de Kubernetes](/docs/reference/generated/kubernetes-api/v1.35/)
controller-selector: "apps/v1/deployment/nginx"
Esta tarea muestra cómo utilizar kubectl patch para actualizar un objeto del API sin reemplazarlo.
Los ejercicios de esta tarea demuestran el uso de "strategic merge patch" y "JSON merge patch"
Debes tener un cluster Kubernetes a tu dispocición, y la herramienta de línea de comandos kubectl debe estar configurada. Si no tienes un cluster, puedes crear uno utilizando Minikube,
o puedes utilizar una de las siguientes herramientas en línea:
Para comprobar la versión, introduzca kubectl version.
Aquí está el archivo de configuración para un Deployment con dos réplicas. Cada réplica es un Pod que tiene un contenedor:
apiVersion: apps/v1
kind: Deployment
metadata:
name: patch-demo
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: patch-demo-ctr
image: nginx
tolerations:
- effect: NoSchedule
key: dedicated
value: test-team
Crea el Deployment:
kubectl apply -f https://k8s.io/examples/application/deployment-patch.yaml
Revisa los Pods asociados con tu Deployment:
kubectl get pods
El resultado muestra que el Deployment tiene dos Pods. El 1/1 indica
que cada Pod tiene un contenedor:
NAME READY STATUS RESTARTS AGE
patch-demo-28633765-670qr 1/1 Running 0 23s
patch-demo-28633765-j5qs3 1/1 Running 0 23s
Toma nota de los nombres de los Pods que se están ejecutando. Verás que estos Pods son terminados y reemplazados posteriormente.
En este punto cada Pod tiene un contenedor que ejecuta una imagen de nginx. Ahora supón que quieres que cada Pod tenga dos contenedores: uno que ejecute nginx y otro que ejecute redis.
Crea un archivo llamado patch-file.yaml con el siguiente contenido:
spec:
template:
spec:
containers:
- name: patch-demo-ctr-2
image: redis
Modifica tu Deployment usando Patch:
kubectl patch deployment patch-demo --patch-file patch-file.yaml
Revisa el Deployment modificado:
kubectl get deployment patch-demo --output yaml
El resultado muestra que el PodSpec del Deployment tiene dos contenedores:
containers:
- image: redis
imagePullPolicy: Always
name: patch-demo-ctr-2
...
- image: nginx
imagePullPolicy: Always
name: patch-demo-ctr
...
Revisa los Pods asociados con tu Deployment modificado:
kubectl get pods
El resultado muestra que los Pods tienen un nombre distinto a los que se estaban
ejecutando anteriormente. El Deployment terminó los Pods viejos y creo dos nuevos
que cumplen con la especificación actualizada del Deployment. El 2/2 indica que
cada Pod tiene dos contenedores:
NAME READY STATUS RESTARTS AGE
patch-demo-1081991389-2wrn5 2/2 Running 0 1m
patch-demo-1081991389-jmg7b 2/2 Running 0 1m
Un vistazo más de cerca a uno de los Pods del patch-demo:
kubectl get pod <your-pod-name> --output yaml
El resultado muestra que el Pod tienen dos contenedores: uno ejecutando nginx y otro redis:
containers:
- image: redis
...
- image: nginx
...
El patch que hiciste en el ejercicio anterior se llama strategic merge patch.
Toma en cuenta que el path no reemplazó la lista containers. Sino que agregó
un contenedor nuevo a la lista. En otras palabras, la lista en el patch fue agregada
a la lista ya existente. Esto no es lo que pasa siempre que se utiliza strategic merge patch
en una lista. En algunos casos la lista existente podría ser reemplazada en lugar de unir ambas.
Con strategic merge patch, la lista existente puede ser reemplazada o unida con la nueva
dependiendo de la estrategia de patch. La estrategia de patch se especifica en el valor de la clave
patchStrategyen un campo tag del código fuente de Kubernetes. Por ejemplo el
campo Containers de la struct PodSpec tiene un valor de merge en su clave patchStrategy:
type PodSpec struct {
...
Containers []Container `json:"containers" patchStrategy:"merge" patchMergeKey:"name" ...`
...
}
También puedes consultar la estrategia de patch en OpenApi spec:
"io.k8s.api.core.v1.PodSpec": {
...,
"containers": {
"description": "List of containers belonging to the pod. ...."
},
"x-kubernetes-patch-merge-key": "name",
"x-kubernetes-patch-strategy": "merge"
}
Y puedes consultar la estrategia de patch en la Documentación del API Kubernetes.
Crea un archivo llamado patch-file-tolerations.yaml que tenga el siguiente contenido:
spec:
template:
spec:
tolerations:
- effect: NoSchedule
key: disktype
value: ssd
Modifica tu Deployment utilizando Patch:
kubectl patch deployment patch-demo --patch-file patch-file-tolerations.yaml
Revisa el Deployment modificado:
kubectl get deployment patch-demo --output yaml
El resultado muestra que el PodsSpec del Deployment tiene solo un Toleration:
tolerations:
- effect: NoSchedule
key: disktype
value: ssd
Toma en cuenta que la lista de tolerations en el PodSpec fue reemplazada, no unida.
Esto es porque el campo de Tolerations del PodSpec no tiene una clave patchStrategy en su campo de tag.
por lo tanto strategic merge patch utiliza la estrategia de patch por defecto, la cual es replace.
type PodSpec struct {
...
Tolerations []Toleration `json:"tolerations,omitempty" protobuf:"bytes,22,opt,name=tolerations"`
...
}
Un strategic merge patch es distinto a un JSON merge patch.
Con JSON merge patch, si quieres actualizar una lista tienes que especificar la lista nueva en su totalidad y reemplazar la lista existente con la lista nueva.
El comando kubectl patch tiene un parámetro type que acepta los siguientes valores:
| Valor del parámetro | tipo de unión |
|---|---|
| json | JSON Patch, RFC 6902 |
| merge | JSON Merge Patch, RFC 7386 |
| strategic | Strategic merge patch |
Para una comparación entre JSON patch y JSON merge patch, revisa JSON Patch y JSON Merge Patch.
El valor predeterminado para el parámetro type es strategic. Entonces en el ejercicio
anterior hiciste un strategic merge patch.
A continuación haz un JSON merge path en el mismo Deployment. Crea un archivo llamado
patch-file-2.yaml que tenga el siguiente contenido:
spec:
template:
spec:
containers:
- name: patch-demo-ctr-3
image: gcr.io/google-samples/node-hello:1.0
En el comando patch configura el valor de type como merge
kubectl patch deployment patch-demo --type merge --patch-file patch-file-2.yaml
Revisa el Deployment modificado:
kubectl get deployment patch-demo --output yaml
La lista containers que especificaste en el patch solo tiene un contenedor.
el resultado muestra que tu lista con un contenedor reemplazó a la lista containers preexistente.
spec:
containers:
- image: gcr.io/google-samples/node-hello:1.0
...
name: patch-demo-ctr-3
Revisa los Pods en ejecución:
kubectl get pods
En el resultado se puede ver que los Pods existentes fueron terminados y se
crearon Pods nuevos. El 1/1 indica que cada Pod nuevo esta ejecutando un solo
contenedor.
NAME READY STATUS RESTARTS AGE
patch-demo-1307768864-69308 1/1 Running 0 1m
patch-demo-1307768864-c86dc 1/1 Running 0 1m
Aquí esta el archivo de configuración para un Deployment que usa la estrategia RollingUpdate:
apiVersion: apps/v1
kind: Deployment
metadata:
name: retainkeys-demo
spec:
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 30%
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: retainkeys-demo-ctr
image: nginx
Crea el Deployment:
kubectl apply -f https://k8s.io/examples/application/deployment-retainkeys.yaml
En este punto, el Deployment es creado y está usando la estrategia RollingUpdate.
Crea un archivo llamado patch-file-no-retainkeys.yaml con el siguiente contenido:
spec:
strategy:
type: Recreate
Modifica tu Deployment:
kubectl patch deployment retainkeys-demo --type strategic --patch-file patch-file-no-retainkeys.yaml
En el resultado se puede ver que no es posible definir el type como Recreate cuando hay un value definido para spec.strategy.rollingUpdate:
The Deployment "retainkeys-demo" is invalid: spec.strategy.rollingUpdate: Forbidden: may not be specified when strategy `type` is 'Recreate'
La forma para quitar el valor para spec.strategy.rollingUpdate al momento de cambiar el valor type es usar la estrategia retainKeys para el strategic merge.
Crea otro archivo llamado patch-file-retainkeys.yaml con el siguiente contenido:
spec:
strategy:
$retainKeys:
- type
type: Recreate
Con este Patch definimos que solo queremos conservar la clave type del objeto strategy. Por lo tanto la clave rollingUpdate será eliminada durante la operación de modificación.
Modifica tu Deployment de nuevo con este nuevo Patch:
kubectl patch deployment retainkeys-demo --type strategic --patch-file patch-file-retainkeys.yaml
Revisa el contenido del Deployment:
kubectl get deployment retainkeys-demo --output yaml
El resultado muestra que el objeto strategy en el Deployment ya no contiene la clave rollingUpdate:
spec:
strategy:
type: Recreate
template:
La modificación realizada en el ejercicio anterior tiene el nombre de strategic merge patch con estrategia retainKeys. Este método introduce una
nueva directiva $retainKeys que tiene las siguientes estrategias:
$retainKeys.$retainKeys deberán ser un superconjunto o idéntico a los campos presentes en el Patch.La estrategia retainKeys no funciona para todos los objetos. Solo funciona cuando el valor de la key patchStrategyen el campo tag de el código fuente de
Kubernetes contenga retainKeys. Por ejemplo, el campo Strategy del struct DeploymentSpec tiene un valor de retainKeys en su tag patchStrategy
type DeploymentSpec struct {
...
// +patchStrategy=retainKeys
Strategy DeploymentStrategy `json:"strategy,omitempty" patchStrategy:"retainKeys" ...`
...
}
También puedes revisar la estrategia retainKeys en la especificación de OpenApi:
"io.k8s.api.apps.v1.DeploymentSpec": {
...,
"strategy": {
"$ref": "#/definitions/io.k8s.api.apps.v1.DeploymentStrategy",
"description": "The deployment strategy to use to replace existing pods with new ones.",
"x-kubernetes-patch-strategy": "retainKeys"
},
....
}
Además puedes revisar la estrategia retainKeys en la documentación del API de k8s.
El comando kubectl patch toma como entrada un archivo en formato YAML o JSON desde el sistema de archivos o la línea de comandos.
Crea un archivo llamado patch-file.json que contenga lo siguiente:
{
"spec": {
"template": {
"spec": {
"containers": [
{
"name": "patch-demo-ctr-2",
"image": "redis"
}
]
}
}
}
}
Los siguientes comandos son equivalentes:
kubectl patch deployment patch-demo --patch-file patch-file.yaml
kubectl patch deployment patch-demo --patch 'spec:\n template:\n spec:\n containers:\n - name: patch-demo-ctr-2\n image: redis'
kubectl patch deployment patch-demo --patch-file patch-file.json
kubectl patch deployment patch-demo --patch '{"spec": {"template": {"spec": {"containers": [{"name": "patch-demo-ctr-2","image": "redis"}]}}}}'
kubectl patch con --subresourceKubernetes v1.24 [alpha]
La bandera --subresource=[subresource-name] es utilizada con comandos de kubectl como get,
patch y replace para obtener y actualizar los subrecursos status y scale de los recursos
(aplicable para las versiones de kubectl de v1.24 en adelante). Esta bandera se utiliza con
todos los recursos del API (incluidos en k8s o CRs) que tengan los subrecursos status o scale.
Deployment es un ejemplo de un objeto con estos subrecursos.
A continuación se muestra un ejemplo de un Deployment con dos réplicas:
apiVersion: apps/v1 # Usa apps/v1beta2 para versiones anteriores a 1.9.0
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # indica al controlador que ejecute 2 pods
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
Crea el Deployment:
kubectl apply -f https://k8s.io/examples/application/deployment.yaml
Revisa los Pods asociados al Deployment
kubectl get pods -l app=nginx
En el resultado se puede observar que el Deployment tiene dos Pods:
NAME READY STATUS RESTARTS AGE
nginx-deployment-7fb96c846b-22567 1/1 Running 0 47s
nginx-deployment-7fb96c846b-mlgns 1/1 Running 0 47s
Ahora modifica el Deployment utilizando Patch con la bandera --subresource=[subresource-name]:
kubectl patch deployment nginx-deployment --subresource='scale' --type='merge' -p '{"spec":{"replicas":3}}'
El resultado es :
scale.autoscaling/nginx-deployment patched
Revisa los Pods asociados al Deployment modificado:
kubectl get pods -l app=nginx
En el resultado se puede apreciar que se ha creado un Pod nuevo. Ahora tienes 3 Pods en ejecución.
NAME READY STATUS RESTARTS AGE
nginx-deployment-7fb96c846b-22567 1/1 Running 0 107s
nginx-deployment-7fb96c846b-lxfr2 1/1 Running 0 14s
nginx-deployment-7fb96c846b-mlgns 1/1 Running 0 107s
Revisa el Deployment modificado
kubectl get deployment nginx-deployment -o yaml
...
spec:
replicas: 3
...
status:
...
availableReplicas: 3
readyReplicas: 3
replicas: 3
kubectl patch y especificas la bandera --subresource para un recurso que no soporte
un subrecurso en particular, el servidor del API regresará un error 404 Not Found.En este ejercicio utilizaste kubectl patch para cambiar la configuración en ejecución de
un objeto de tipo Deployment. No hubo cambios al archivo de configuración que se utilizó
originalmente para crear el Deployment. Otros comandos utilizados para actualizar objetos del API
incluyen:
kubectl annotate,
kubectl edit,
kubectl replace,
kubectl scale,
y
kubectl apply.
Ésta página enseña como correr una aplicación stateless usando un deployment de Kubernetes.
deployment de nginx.deployment.deployment.Debes tener un cluster Kubernetes a tu dispocición, y la herramienta de línea de comandos kubectl debe estar configurada. Si no tienes un cluster, puedes crear uno utilizando Minikube,
o puedes utilizar una de las siguientes herramientas en línea:
Para comprobar la versión, introduzca kubectl version.
Puedes correr una aplicación creando un deployment de Kubernetes, y puedes describir el deployment en un fichero YAML. Por ejemplo, el siguiente fichero YAML describe un deployment que corre la imágen Docker nginx:1.7.9:
apiVersion: apps/v1 # Usa apps/v1beta2 para versiones anteriores a 1.9.0
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # indica al controlador que ejecute 2 pods
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
Crea un deployment basado en el fichero YAML:
kubectl apply -f https://k8s.io/examples/application/deployment.yaml
Obtén información acerca del deployment:
kubectl describe deployment nginx-deployment
El resultado es similar a esto:
Name: nginx-deployment
Namespace: default
CreationTimestamp: Tue, 30 Aug 2016 18:11:37 -0700
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision=1
Selector: app=nginx
Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.7.9
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-1771418926 (2/2 replicas created)
No events.
Lista los pods creados por el deployment:
kubectl get pods -l app=nginx
El resultado es similar a esto:
NAME READY STATUS RESTARTS AGE
nginx-deployment-1771418926-7o5ns 1/1 Running 0 16h
nginx-deployment-1771418926-r18az 1/1 Running 0 16h
Muestra información acerca del pod:
kubectl describe pod <pod-name>
donde <pod-name> es el nombre de uno de los pods.
Puedes actualizar el deployment aplicando un nuevo fichero YAML. El siguiente fichero YAML
especifica que el deployment debería ser actualizado para usar nginx 1.8.
apiVersion: apps/v1 # Usa apps/v1beta2 para versiones anteriores a 1.9.0
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.8 # Actualiza la versión de nginx de 1.7.9 a 1.8
ports:
- containerPort: 80
Aplica el nuevo fichero YAML:
kubectl apply -f https://k8s.io/examples/application/deployment-update.yaml
Comprueba como el deployment crea nuevos pods con la nueva imagen mientras va eliminando los pods con la especificación antigua:
kubectl get pods -l app=nginx
Puedes aumentar el número de pods en tu deployment aplicando un nuevo fichero YAML.
El siguiente fichero YAML especifica un total de 4 replicas, lo que significa que el deployment debería tener cuatro pods:
apiVersion: apps/v1 # Usa apps/v1beta2 para versiones anteriores a 1.9.0
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 4 # Actualiza el número de réplicas de 2 a 4
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.8
ports:
- containerPort: 80
Aplica el nuevo fichero YAML:
kubectl apply -f https://k8s.io/examples/application/deployment-scale.yaml
Verifica que el deployment tiene cuatro pods:
kubectl get pods -l app=nginx
El resultado es similar a esto:
NAME READY STATUS RESTARTS AGE
nginx-deployment-148880595-4zdqq 1/1 Running 0 25s
nginx-deployment-148880595-6zgi1 1/1 Running 0 25s
nginx-deployment-148880595-fxcez 1/1 Running 0 2m
nginx-deployment-148880595-rwovn 1/1 Running 0 2m
Elimina el deployment por el nombre:
kubectl delete deployment nginx-deployment
La manera preferida de crear una aplicación con múltiples instancias es usando un Deployment, el cual usa un ReplicaSet. Antes de que Deployment y ReplicaSet fueran introducidos en Kubernetes, aplicaciones con múltiples instancias eran configuradas usando un ReplicationController.
Esta página muestra cómo escalar un StatefulSet. Escalar un StatefulSet es incrementar o decrementar el número de réplicas.
Los StatefulSets están solamente disponibles en Kubernetes 1.5 o posterior.
Para verificar su versión de Kubernetes puede ejecutar kubectl version.
No todas las aplicaciones que manejan estados escalan correctamente. Si no está seguro sobre si puede escalar sus StatefulSets, visite los conceptos de StatefulSet o el tutorial sobre StatefulSet para más información.
Solamente se debe realizar un escalamiento cuando esté lo suficientemente seguro del buen funcionamiento de su clúster y de las aplicaciones que manejan estados.
Como primer paso, identifica el StatefulSet que deseas escalar.
kubectl get statefulsets <nombre-del-stateful-set>
Cambia el número de réplicas de tu StatefulSet:
kubectl scale statefulsets <nombre-del-stateful-set> --replicas=<número-de-réplicas>
De manera alternativa, se pueden hacer actualizaciones in-place en tus StatefulSets.
Si el StatefulSet fue inicialmente creado con kubectl apply,
puedes actualizar .spec.replicas en el manifiesto previamente definido y ahí hacer kubectl apply:
kubectl apply -f <archivo-stateful-set-actualizado>
De otra manera, edita esa línea con kubectl edit:
kubectl edit statefulsets <nombre-del-stateful-set>
También puedes usar kubectl patch:
kubectl patch statefulsets <nombre-del-stateful-set> -p '{"spec":{"replicas":<número-de-réplicas>}}'
No se puede escalar hacia abajo un StatefulSet cuando alguno de los Pods que administra está dañado. Desescalar solo tiene lugar después de tener los Pods disponibles.
Si spec.replicas > 1, Kubernetes no puede determinar la razón de un Pod dañado. Esto puede ser el resultado de una falla permanente o una falla transitoria. Una falla transitoria puede ser causada por un reinicio necesario para una actualización o mantenimiento.
Si el Pod está dañado con una falla permanente, escalar sin corregir la falla puede llevarnos a un estado donde el StatefulSet cae en una cantidad de miembros inferior a la cantidad de replicas que son necesarias para funcionar correctamente. Esto puede causar que el StatefulSet no este disponible.
Si el Pod está dañado por una falla transitoria y el Pod puede volver a estar disponible nuevamente, el error transitorio puede interferir con la operación de escalar. Algunas bases de datos distribuidas tienen errores cuando los nodos se unen y abandonan en el mismo momento. Es mejor analizar acerca de escalar la operación a nivel de la aplicación y realizar el escalamiento solamente cuando está seguro que el clúster de la aplicación está funcionando y en buen estado.
Esta página muestra cómo se debe eliminar un StatefulSet.
Se puede eliminar un StatefulSet de la misma manera que se eliminan el resto de los recursos en Kubernetes:
Usa el comando kubectl delete y especifica el StatefulSet, usando su nombre o el archivo con el que fue creado.
kubectl delete -f <archivo.yaml>
kubectl delete statefulsets <nombre-del-stateful-set>
Puede suceder que necesites eliminar los servicios headless asociados después de eliminar el StatefulSet.
kubectl delete service <nombre-del-servicio>
Cuando se elimina un StatefulSet utilizando kubectl, el StatefulSet escala a 0.
Todos los Pods que eran parte de esta carga de trabajo son eliminados. Si tú quieres eliminar
solo el StatefulSet y no los Pods utiliza --cascade=orphan. Por ejemplo:
kubectl delete -f <archivo.yaml> --cascade=orphan
Agregando --cascade=orphan al comando kubectl delete, los Pods administrados por el StatefulSet
dejan de pertenecer al StatefulSet cuando es eliminado. Si los pods tienen una
etiqueta app.kubernetes.io/name=MyApp se los puede eliminar de la siguiente manera:
kubectl delete pods -l app.kubernetes.io/name=MyApp
Eliminar los Pods de un StatefulSet no va a eliminar los volúmenes asociados. Esto es para asegurar que se tiene una oportunidad de copiar los datos fuera del volumen antes de eliminarlo. Borrar el PVC después de que los pods estén terminados puede disparar la eliminación del Volumen Persistente que hay detrás dependiendo de la clase de almacenamiento y la política de reclamo. Nunca debes asumir la capacidad de acceder a un volumen después de la eliminación del claim.
Para eliminar todo en un StatefulSet, incluyendo los pods asociados, se puede correr una serie de comandos similares a los siguientes:
grace=$(kubectl get pods <stateful-set-pod> --template '{{.spec.terminationGracePeriodSeconds}}')
kubectl delete statefulset -l app.kubernetes.io/name=MyApp
sleep $grace
kubectl delete pvc -l app.kubernetes.io/name=MyApp
En este ejemplo, los Pods tienen la etiqueta app.kubernetes.io/name=MyApp,
sustituye la misma por tu propia etiqueta.
Si encuentras algunos pods bloqueados en tu StatefulSet en el estado 'Terminating' o 'Unknown' por un largo período de tiempo, puede ser que necesites intervenir manualmente para forzar la eliminación de los pods del apiserver. Ésta es una tarea potencialmente riesgosa. Visita Forzar eliminación de Pods en StatefulSet para más detalles.
Aprende más sobre Forzar eliminación de Pods en StatefulSet.
Esta página muestra cómo eliminar Pods que son parte de un StatefulSet, y explica las consideraciones a tener en cuenta al hacerlo.
En la operación normal de un StatefulSet, nunca hay necesidad de eliminar forzosamente un Pod de StatefulSet. El controlador de StatefulSet es responsable de crear, escalar y eliminar miembros del StatefulSet. Intenta asegurar que el número especificado de Pods, desde el ordinal 0 hasta N-1, estén vivos y listos. StatefulSet asegura que, en cualquier momento, exista como máximo un Pod con una identidad dada, corriendo en un clúster. Esto se refiere a la semántica de como máximo uno proporcionada por un StatefulSet.
La eliminación manual forzada debe realizarse con precaución, ya que tiene el potencial de violar la semántica de como máximo uno, inherente a StatefulSet. Los StatefulSets pueden usarse para ejecutar aplicaciones distribuidas y agrupadas que necesitan una identidad de red estable y almacenamiento estable. Estas aplicaciones a menudo tienen configuraciones que dependen de un conjunto de un número fijo de miembros con identidades fijas. Tener múltiples miembros con la misma identidad puede ser desastroso y puede llevar a pérdida de datos (por ejemplo, escenario de cerebro dividido en sistemas basados en quórum).
Puedes realizar una eliminación de Pod paulatina con el siguiente comando:
kubectl delete pods <pod>
Para que lo anterior conduzca a una terminación paulatina, el Pod no debe especificar un
pod.Spec.TerminationGracePeriodSeconds de 0. La práctica de establecer un
pod.Spec.TerminationGracePeriodSeconds de 0 segundos es insegura y se desaconseja rotundamente
para los Pods de StatefulSet. La eliminación paulatina es segura y garantizará que el Pod
se apague de manera paulatina, antes de que kubelet elimine el nombre en el apiserver.
Un Pod no se elimina automáticamente cuando un nodo no es accesible. Los Pods que se ejecutan en un Nodo inaccesible entran en el estado 'Terminating' o 'Unknown' después de un tiempo de espera. Los Pods también pueden entrar en estos estados cuando el usuario intenta la eliminación paulatina de un Pod en un nodo inaccesible. Las únicas formas en que un Pod en tal estado puede ser eliminado del apiserver son las siguientes:
La mejor práctica recomendada es usar el primer o segundo enfoque. Si un nodo está confirmado como muerto (por ejemplo, desconectado permanentemente de la red, apagado, etc.), entonces elimina el objeto Node. Si el nodo es afectado de una partición de red, entonces trata de resolver esto o espera a que se resuelva. Cuando la partición se solucione, kubelet completará la eliminación del Pod y liberará su nombre en el apiserver.
Normalmente, el sistema completa la eliminación una vez que el Pod ya no se está ejecutando en un nodo, o el nodo es eliminado por un administrador. Puedes anular esto forzando la eliminación del Pod.
Las eliminaciones forzosas no esperan confirmación de kubelet de que el Pod ha sido terminado. Independientemente de si una eliminación forzosa tiene éxito en matar un Pod, inmediatamente liberará el nombre del apiserver. Esto permitiría que el controlador de StatefulSet cree un Pod de reemplazo con esa misma identidad; esto puede llevar a la duplicación de un Pod que aún está en ejecución, y si dicho Pod todavía puede comunicarse con los otros miembros del StatefulSet, violará la semántica de como máximo uno que StatefulSet está diseñado para garantizar.
Cuando eliminas forzosamente un Pod de StatefulSet, estás afirmando que el Pod en cuestión nunca volverá a hacer contacto con otros Pods en el StatefulSet y su nombre puede ser liberado de forma segura para que se cree un reemplazo.
Si quieres eliminar un Pod de forma forzosa usando la versión de kubectl >= 1.5, haz lo siguiente:
kubectl delete pods <pod> --grace-period=0 --force
Si estás usando cualquier versión de kubectl <= 1.4, deberías omitir la opción --force y usar:
kubectl delete pods <pod> --grace-period=0
Si incluso después de estos comandos el pod está atascado en el estado Unknown, usa el siguiente comando para
eliminar el Pod del clúster:
kubectl patch pod <pod> -p '{"metadata":{"finalizers":null}}'
Siempre realiza la eliminación forzosa de Pods de StatefulSet con cuidado y con pleno conocimiento de los riesgos involucrados.
Aprende más sobre depurar un StatefulSet.
Ésta pagina enseña como limitar el numero de disrupciones concurrentes que afectan a tu aplicación definiendo presupuestos de disrupción de pods, Pod Disruption Budgets (PDB) en inglés. Estos presupuestos definen el mínimo número de pods que deben estar ejecutándose en todo momento para asegurar la disponibilidad de la aplicación durante operaciones de mantenimiento efectuadas sobre los nodos por los administradores del cluster.
El caso más común es proteger aplicaciones que usan uno de los controladores incorporados en Kubernetes:
En este caso, toma nota del .spec.selector que utiliza el controlador; el mismo se utilizará en el spec.selector del PDB.
También puedes utilizar PDBs para proteger pods que no estan gestionados por uno de los controladores listados arriba, o agrupaciones arbitrarias de pods, con algunas restricciones descritas en Controladores Arbitrarios y Selectors.
Decide cuántas instancias de tu aplicación pueden estar fuera de servicio al mismo tiempo debido a disrupciones voluntarias de corto plazo.
Un PodDisruptionBudget tiene tres atributos:
.spec.selector para especificar el grupo de
pods donde aplicar el presupuesto. Este campo es requerido..spec.minAvailable que es una descripción del número de pods del grupo que deben estar disponibles después del desalojo, incluso en ausencia del pod desalojado. minAvailable puede ser un número absoluto o un porcentaje..spec.maxUnavailable (disponible en Kubernetes 1.7 y superior) que es una descripción
del numero de pods del grupo que pueden estar indisponibles despues del desalojo. Puede ser un número absoluto o un porcentaje.PodDisruptionBudget
utilizando la herramienta de línea de comandos kubectl, el campo minAvailable es 1 por defecto si no se especifica minAvailable ni maxUnavailable.Puedes especificar únicamente un valor para maxUnavailable y minAvailable por PodDisruptionBudget.
maxUnavailable solo se puede usar para controlar el desalojo de pods
que tienen un controlador asociado manejándolos. En los ejemplos a continuación, "réplicas deseadas"
hace referencia al valor 'scale' del controlador que gestiona el grupo de pods seleccionados por el
PodDisruptionBudget.
Ejemplo 1: Con un minAvailable de 5, se permiten los desalojos siempre que dejen
5 o más pods disponibles entre las seleccionadas por el selector del PodDisruptionBudget.
Ejemplo 2: Con un minAvailable del 30%, se permiten los desalojos mientras que al menos 30% de la cantidad de réplicas se mantengan disponibles.
Ejemplo 3: Con un maxUnavailable de 5, se permiten desalojos siempre que haya como máximo 5
réplicas indisponibles entre el número total de réplicas deseadas.
Ejemplo 4: Con un maxUnavailable de 30%, se permiten los desalojos siempre y cuando no más del 30%
de las réplicas esten indisponibles.
En el uso típico, se usaría un solo presupuesto para una colección de pods administrados por un controlador, por ejemplo, los pods en un solo ReplicaSet o StatefulSet.
Un maxUnavailable de 0% (o 0) o un minAvailable de 100% (o igual al
número de réplicas) puede prevenir que los nodos sean purgados completamente.
Esto está permitido según la semántica de PodDisruptionBudget.
Puedes encontrar ejemplos de presupuestos de disrupción de pods definidas a continuación. Los ejemplos aplican al grupo de pods que tienen la etiqueta app: zookeeper.
Ejemplo de PDB usando minAvailable:
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: zk-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: zookeeper
Ejemplo de PDB usando maxUnavailable (Kubernetes 1.7 o superior):
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: zk-pdb
spec:
maxUnavailable: 1
selector:
matchLabels:
app: zookeeper
Por ejemplo, si el objeto anterior zk-pdb selecciona los pods de un StatefulSet de tamaño 3, ambas
especificaciones tienen el mismo significado exacto. Se recomienda el uso de maxUnavailable ya que
responde automáticamente a los cambios en el número de réplicas del controlador correspondiente.
Puedes crear el objeto PDB con el comando kubectl apply -f mypdb.yaml.
No puedes actualizar objetos PDB. Deben ser eliminados y recreados.
Utiliza kubectl para comprobar que se ha creado tu PDB.
Suponiendo que en realidad no tengas pods que coincidan con app: zookeeper en su namespace,
entonces verás algo como esto:
kubectl get poddisruptionbudgets
NAME MIN-AVAILABLE ALLOWED-DISRUPTIONS AGE
zk-pdb 2 0 7s
Si hay pods que coinciden (por ejemplo, 3), entonces debes ver algo similar a esto:
kubectl get poddisruptionbudgets
NAME MIN-AVAILABLE ALLOWED-DISRUPTIONS AGE
zk-pdb 2 1 7s
El valor distinto a cero de ALLOWED-DISRUPTIONS significa que el controlador de disrupción ha visto los pods, contó los pods coincidentes, y actualizó el estado del PDB.
Puedes obtener más información sobre el estado de un PDB con este comando:
kubectl get poddisruptionbudgets zk-pdb -o yaml
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
creationTimestamp: 2017-08-28T02:38:26Z
generation: 1
name: zk-pdb
...
status:
currentHealthy: 3
desiredHealthy: 3
disruptedPods: null
disruptionsAllowed: 1
expectedPods: 3
observedGeneration: 1
Por último, los PodDisruptionBudgets también se pueden consultar con kubectl utilizando el nombre corto pdb:
kubectl get pdb
NAME MIN-AVAILABLE ALLOWED-DISRUPTIONS AGE
zk-pdb 2 0 7s
Puedes omitir esta sección si solo utilizas PDBs con los controladores integrados de aplicaciones (Deployment, Replicationcontrolador, ReplicaSet y StatefulSet), con el selector de PDB coincidiendo con el selector del controlador.
Puedes utilizar un PDB con pods controlados por otro tipo de controlador, por un "Operator", o pods individuales, pero con las siguientes restricciones:
.spec.minAvailable, no .spec.maxUnavailable..spec.minAvailable, no un porcentaje.Puedes usar un selector que selecciona un subconjunto o superconjunto de los pods que pertenecen a un controlador incorporado. Sin embargo, cuando hay varios PDB en un namespace, debes tener cuidado de no crear PDBs cuyos selectores se superponen.
Esta guía muestra como acceder a la API de Kubernetes desde de un Pod.
Debes tener un cluster Kubernetes a tu dispocición, y la herramienta de línea de comandos kubectl debe estar configurada. Si no tienes un cluster, puedes crear uno utilizando Minikube,
o puedes utilizar una de las siguientes herramientas en línea:
El acceder a la API desde un Pod, la ubicacion y autentication del servidor de la API es ligeramente diferente que en el caso de un cliente externo.
La forma más fácil de usar la API de Kubernetes desde un Pod es utilizando una de las bibliotecas de cliente oficiales. Estas bibliotecas pueden automáticamente descubrir el servidor de la API y autenticarse.
Desde un Pod, las formas recomendadas de conectarse a la API de Kubernetes son:
Para un cliente de Go, utilice la
biblioteca oficial del cliente de Go.
La función rest.InClusterConfig() maneja automáticamente el descubrimiento del host de la API
y la autenticación. Vea un ejemplo aqui.
Para un cliente de Python, utilice la
biblioteca oficial del cliente de Python.
La función config.load_incluster_config() maneja automáticamente el descubrimiento
del host de la API y la autenticación. Vea un ejemplo aqui.
Existen varias bibliotecas disponibles, por favor consulte la página de Bibliotecas de Clientes.
En cada caso, las credenciales de la cuenta de servicio del Pod se utilizan para comunicarse de manera segura con el servidor de la API.
Al ejecutarse en un Pod, su contenedor puede crear una URL HTTPS para el servidor de la API de Kubernetes
obteniendo las variables de entorno KUBERNETES_SERVICE_HOSTy KUBERNETES_SERVICE_PORT_HTTPS.
La dirección del servidor de la API dentro del clúster también se publica
en un Servicio llamado kubernetes en el namespace default, de modo que los pods pueden hacer referencia a
kubernetes.default.svc como el nombre DNS para el servidor de la API local.
kubernetes.default.svc;
Sin embargo, se espera que el plano de control presente un certificado válido para
el nombre de host o la dirección IP que representa $KUBERNETES_SERVICE_HOSTLa forma recomendada para autenticarse con el servidor de la API es con una
credencial de cuenta de servicio.
Por defecto, un Pod esta asociado con una cuenta de servicio,
esta asociado con una cuenta de servicio, y una credencial (token) para esa cuenta
de servicio se coloca en el sistema de archivos de cada contenedor en ese Pod
en la ruta /var/run/secrets/kubernetes.io/serviceaccount/token.
Si está disponible, un paquete de certificados se coloca en el sistema de archivos de
cada contenedor en la ruta /var/run/secrets/kubernetes.io/serviceaccount/ca.crt, y
debe usarse para verificar el certificado de servicio del servidor API.
Finalmente, el Namespace default puede ser utilizado en las operaciones de API con ámbito de espacio de nombres que se colocan en un archivo
con la ruta /var/run/secrets/kubernetes.io/serviceaccount/namespace de cada contenedor
Si deseas consultar la API sin una biblioteca de cliente oficial, puedes ejecutar kubectl proxy
como el comando
de un nuevo contenedor sidecar en el Pod. De esta manera, kubectl proxy se autenticará
en la API y la expondrá en la interfaz localhost del Pod, para que otros contenedores
en el Pod puedan usarla directamente.
Es posible evitar el uso del proxy de kubectl pasando el token de autenticación directamente al servidor de la API. El certificado interno asegura la conexión.
# Apuntar nombre de host del servidor API interno.
APISERVER=https://kubernetes.default.svc
# Ruta del token de ServiceAccount
SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
# Lectura del Namespace del Pod
NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
# Lectura del bearer token del ServiceAccount
TOKEN=$(cat ${SERVICEACCOUNT}/token)
# Referencia a la autoridad de certificación interna (CA)
CACERT=${SERVICEACCOUNT}/ca.crt
# Explora la API con TOKEN
curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api
La salida será similar a esto:
{
"kind": "APIVersions",
"versions": ["v1"],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "10.0.1.149:443"
}
]
}
A veces las cosas salen mal. Esta guía tiene como objetivo solucionarlas. Tiene dos secciones:
También debe comprobar los problemas conocidos del release usado.
Si ninguna de las guías anteriores resuelve su problema, existen varias formas de obtener ayuda de la comunidad de Kubernetes.
La documentación de este sitio ha sido estructurada para brindar respuestas a una amplia gama de preguntas. Conceptos explican la arquitectura de Kubernetes
y cómo funciona cada componente, mientras Configuración proporciona
instrucciones prácticas para empezar. Tareas muestran cómo
realizar tareas de uso común, y Tutoriales son recorridos más completos de escenarios de desarrollo reales, específicos de la industria o de extremo a extremo. La sección de Referencia proporciona
documentación detallada sobre el Kubernetes API
y las interfaces de línea de comandos (CLIs), tal como kubectl.
Si tienes preguntas relacionadas con desarrollo de software para tu aplicación en contenedores, puedes preguntar en Stack Overflow.
Si tienes preguntas sobre Kubernetes relacionadas con administración de clústeres o configuración, puedes preguntar en Server Fault.
También hay varios sitios de Stack Exchange que podrían ser el lugar adecuado para hacer preguntas sobre Kubernetes en áreas como DevOps, Ingeniería de Software, o InfoSec.
Es posible que otra persona de la comunidad ya haya hecho una pregunta similar o pueda ayudar con su problema.
El equipo de Kubernetes también monitoreará publicaciones etiquetadas con Kubernetes. Si no hay ninguna pregunta existente que te ayude, asegúrate de que tu pregunta sea sobre el tema en Stack Overflow, Server Fault, o el Stack Exchange correcto en el que estás preguntando, y lee las instrucciones sobre Cómo hacer una nueva pregunta, antes de preguntar una nueva!
Muchas personas de la comunidad de Kubernetes se reúnen en Kubernetes Slack en el canal #kubernetes-users.
Slack requiere registro; puedes solicitar una invitación, el registro está abierto a todos. No dudes en participar y hacer todas y cada una de las preguntas.
Una vez registrado, ingresa a la Organización de Kubernetes en Slack
a través de tu navegador web o mediante la aplicación dedicada de Slack.
Una vez que estés registrado, explora la creciente lista de canales para diversos temas de
interés. Por ejemplo, las personas nuevas en Kubernetes también pueden querer unirse al canal
#kubernetes-novice. Como otro ejemplo, los desarrolladores deberían unirse al canal
#kubernetes-contributors.
También hay muchos canales en idiomas locales o específicos de cada país. Siéntete libre de unirte a estos canales para obtener soporte e información localizados:
| Región | Canal(es) |
|---|---|
| China | #cn-users, #cn-events |
| Finlandia | #fi-users |
| Francia | #fr-users, #fr-events |
| Alemania | #de-users, #de-events |
| India | #in-users, #in-events |
| Italia | #it-users, #it-events |
| Japon | #jp-users, #jp-events |
| Corea | #kr-users |
| Países Bajos | #nl-users |
| Noruega | #norw-users |
| Polonia | #pl-users |
| Rusia | #ru-users |
| Países Hispanos | #es-users |
| Suecia | #se-users |
| Turquia | #tr-users, #tr-events |
Te invitamos a unirte al Foro oficial de Kubernetes: discuss.kubernetes.io.
Si tienes lo que parece ser un error (bug) o deseas realizar una solicitud de funcionalidades, por favor utiliza el sistema de seguimiento de asuntos en el GitHub.
Antes de presentar un problema, busca problemas existentes para ver si tu problema ya está cubierto.
Si presenta un error, incluya información detallada sobre cómo reproducir el problema, como por ejemplo:
kubectl versionEsta página muestra cómo investigar problemas relacionados con la ejecución
de los contenedores de inicialización (init containers). Las líneas de comando del ejemplo de abajo
se refieren al Pod como <pod-name> y a los Init Containers como <init-container-1> e
<init-container-2> respectivamente.
Debes tener un cluster Kubernetes a tu dispocición, y la herramienta de línea de comandos kubectl debe estar configurada. Si no tienes un cluster, puedes crear uno utilizando Minikube,
o puedes utilizar una de las siguientes herramientas en línea:
Para comprobar la versión, introduzca kubectl version.
Muestra el estado de tu pod:
kubectl get pod <pod-name>
Por ejemplo, un estado de Init:1/2 indica que uno de los Init Containers
se ha ejecutado satisfactoriamente:
NAME READY STATUS RESTARTS AGE
<pod-name> 0/1 Init:1/2 0 7s
Echa un vistazo a Comprender el estado de un Pod para más ejemplos de valores de estado y sus significados.
Para ver información detallada acerca de la ejecución de un Init Container:
kubectl describe pod <pod-name>
Por ejemplo, un Pod con dos Init Containers podría mostrar lo siguiente:
Init Containers:
<init-container-1>:
Container ID: ...
...
State: Terminated
Reason: Completed
Exit Code: 0
Started: ...
Finished: ...
Ready: True
Restart Count: 0
...
<init-container-2>:
Container ID: ...
...
State: Waiting
Reason: CrashLoopBackOff
Last State: Terminated
Reason: Error
Exit Code: 1
Started: ...
Finished: ...
Ready: False
Restart Count: 3
...
También puedes acceder al estado del Init Container de forma programática mediante
la lectura del campo status.initContainerStatuses dentro del Pod Spec:
kubectl get pod nginx --template '{{.status.initContainerStatuses}}'
Este comando devolverá la misma información que arriba en formato JSON.
Indica el nombre del Init Container así como el nombre del Pod para acceder a sus logs.
kubectl logs <pod-name> -c <init-container-2>
Los Init Containers que ejecutan secuencias de línea de comandos muestran los comandos
conforme se van ejecutando. Por ejemplo, puedes hacer lo siguiente en Bash
indicando set -x al principio de la secuencia.
Un estado de un Pod que comienza con Init: especifica el estado de la ejecución de
un Init Container. La tabla a continuación muestra algunos valores de estado de ejemplo
que puedes encontrar al depurar Init Containers.
| Estado | Significado |
|---|---|
Init:N/M |
El Pod tiene M Init Containers, y por el momento se han completado N. |
Init:Error |
Ha fallado la ejecución de un Init Container. |
Init:CrashLoopBackOff |
Un Init Container ha fallado de forma repetida. |
Pending |
El Pod todavía no ha comenzado a ejecutar sus Init Containers. |
PodInitializing o Running |
El Pod ya ha terminado de ejecutar sus Init Containers. |
La auditoría de Kubernetes proporciona un conjunto de registros cronológicos referentes a la seguridad que documentan la secuencia de actividades que tanto los usuarios individuales, como los administradores y otros componentes del sistema ha realizado en el sistema. Así, permite al administrador del clúster responder a las siguientes cuestiones:
El componente Kube-apiserver lleva a cabo la auditoría. Cada petición en cada fase de su ejecución genera un evento, que se pre-procesa según un cierto reglamento y se escribe en un backend. Este reglamento determina lo que se audita y los backends persisten los registros. Las implementaciones actuales de backend incluyen los archivos de logs y los webhooks.
Cada petición puede grabarse junto con una "etapa" asociada. Las etapas conocidas son:
RequestReceived - La etapa para aquellos eventos generados tan pronto como
el responsable de la auditoría recibe la petición, pero antes de que sea delegada al
siguiente responsable en la cadena.ResponseStarted - Una vez que las cabeceras de la respuesta se han enviado,
pero antes de que el cuerpo de la respuesta se envíe. Esta etapa sólo se genera
en peticiones de larga duración (ej. watch).ResponseComplete - El cuerpo de la respuesta se ha completado y no se enviarán más bytes.Panic - Eventos que se generan cuando ocurre una situación de pánico.El reglamento de auditoría define las reglas acerca de los eventos que deberían registrarse y
los datos que deberían incluir. La estructura del objeto de reglas de auditoría se define
en el audit.k8s.io grupo de API. Cuando se procesa un evento, se compara
con la lista de reglas en orden. La primera regla coincidente establece el "nivel de auditoría"
del evento. Los niveles de auditoría conocidos son:
None - no se registra eventos que disparan esta regla.Metadata - se registra los metadatos de la petición (usuario que la realiza, marca de fecha y hora, recurso,
verbo, etc.), pero no la petición ni el cuerpo de la respuesta.Request - se registra los metadatos del evento y el cuerpo de la petición, pero no el cuerpo de la respuesta.
Esto no aplica para las peticiones que no son de recurso.RequestResponse - se registra los metadatos del evento, y los cuerpos de la petición y la respuesta.
Esto no aplica para las peticiones que no son de recurso.Es posible indicar un archivo al definir el reglamento en el kube-apiserver
usando el parámetro --audit-policy-file. Si dicho parámetros se omite, no se registra ningún evento.
Nótese que el campo rules debe proporcionarse en el archivo del reglamento de auditoría.
Un reglamento sin (0) reglas se considera ilegal.
Abajo se presenta un ejemplo de un archivo de reglamento de auditoría:
apiVersion: audit.k8s.io/v1 # Esto es obligatorio.
kind: Policy
# No generar eventos de auditoría para las peticiones en la etapa RequestReceived.
omitStages:
- "RequestReceived"
rules:
# Registrar los cambios del pod al nivel RequestResponse
- level: RequestResponse
resources:
- group: ""
# Los recursos "pods" no hacen coincidir las peticiones a cualquier sub-recurso de pods,
# lo que es consistente con la regla RBAC.
resources: ["pods"]
# Registrar "pods/log", "pods/status" al nivel Metadata
- level: Metadata
resources:
- group: ""
resources: ["pods/log", "pods/status"]
# No registrar peticiones al configmap denominado "controller-leader"
- level: None
resources:
- group: ""
resources: ["configmaps"]
resourceNames: ["controller-leader"]
# No registrar peticiones de observación hechas por "system:kube-proxy" sobre puntos de acceso o servicios
- level: None
users: ["system:kube-proxy"]
verbs: ["watch"]
resources:
- group: "" # Grupo API base
resources: ["endpoints", "services"]
# No registrar peticiones autenticadas a ciertas rutas URL que no son recursos.
- level: None
userGroups: ["system:authenticated"]
nonResourceURLs:
- "/api*" # Coincidencia por comodín.
- "/version"
# Registrar el cuerpo de la petición de los cambios de configmap en kube-system.
- level: Request
resources:
- group: "" # Grupo API base
resources: ["configmaps"]
# Esta regla sólo aplica a los recursos en el Namespace "kube-system".
# La cadena vacía "" se puede usar para seleccionar los recursos sin Namespace.
namespaces: ["kube-system"]
# Registrar los cambios de configmap y secret en todos los otros Namespaces al nivel Metadata.
- level: Metadata
resources:
- group: "" # Grupo API base
resources: ["secrets", "configmaps"]
# Registrar todos los recursos en core y extensions al nivel Request.
- level: Request
resources:
- group: "" # Grupo API base
- group: "extensions" # La versión del grupo NO debería incluirse.
# Regla para "cazar" todos las demás peticiones al nivel Metadata.
- level: Metadata
# Las peticiones de larga duración, como los watches, que caen bajo esta regla no
# generan un evento de auditoría en RequestReceived.
omitStages:
- "RequestReceived"
Puedes usar un archivo mínimo de reglamento de auditoría para registrar todas las peticiones al nivel Metadata de la siguiente forma:
# Log all requests at the Metadata level.
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
El perfil de auditoría utilizado por GCE debería servir como referencia para que los administradores construyeran sus propios perfiles de auditoría.
Los backends de auditoría persisten los eventos de auditoría en un almacenamiento externo. El Kube-apiserver por defecto proporciona tres backends:
En todos los casos, la estructura de los eventos de auditoría se define por la API del grupo
audit.k8s.io. La versión actual de la API es
v1.
En el caso de parches, el cuerpo de la petición es una matriz JSON con operaciones de parcheado, en vez
de un objeto JSON que incluya el objeto de la API de Kubernetes apropiado. Por ejemplo,
el siguiente cuerpo de mensaje es una petición de parcheado válida para
/apis/batch/v1/namespaces/some-namespace/jobs/some-job-name.
[
{
"op": "replace",
"path": "/spec/parallelism",
"value": 0
},
{
"op": "remove",
"path": "/spec/template/spec/containers/0/terminationMessagePolicy"
}
]
El backend de logs escribe los eventos de auditoría a un archivo en formato JSON. Puedes configurar el backend de logs de auditoría usando el siguiente parámetro de kube-apiserver flags:
--audit-log-path especifica la ruta al archivo de log que el backend utiliza para
escribir los eventos de auditoría. Si no se especifica, se deshabilita el backend de logs. - significa salida estándar--audit-log-maxage define el máximo número de días a retener los archivos de log--audit-log-maxbackup define el máximo número de archivos de log a retener--audit-log-maxsize define el tamaño máximo en megabytes del archivo de logs antes de ser rotadoEl backend de Webhook envía eventos de auditoría a una API remota, que se supone es la misma API que expone el kube-apiserver. Puedes configurar el backend de webhook de auditoría usando los siguientes parámetros de kube-apiserver:
--audit-webhook-config-file especifica la ruta a un archivo con configuración del webhook.
La configuración del webhook es, de hecho, un archivo kubeconfig.--audit-webhook-initial-backoff especifica la cantidad de tiempo a esperar tras una petición fallida
antes de volver a intentarla. Los reintentos posteriores se ejecutan con retraso exponencial.El archivo de configuración del webhook usa el formato kubeconfig para especificar la dirección remota del servicio y las credenciales para conectarse al mismo.
En la versión 1.13, los backends de webhook pueden configurarse dinámicamente.
Tanto el backend de logs como el de webhook permiten procesamiento por lotes. Si usamos el webhook como ejemplo,
aquí se muestra la lista de parámetros disponibles. Para aplicar el mismo parámetro al backend de logs,
simplemente sustituye webhook por log en el nombre del parámetro. Por defecto,
el procesimiento por lotes está habilitado en webhook y deshabilitado en log. De forma similar,
por defecto la regulación (throttling) está habilitada en webhook y deshabilitada en log.
--audit-webhook-mode define la estrategia de memoria intermedia (búfer), que puede ser una de las siguientes:
batch - almacenar eventos y procesarlos de forma asíncrona en lotes. Esta es la estrategia por defecto.blocking - bloquear todas las respuestas del servidor API al procesar cada evento de forma individual.blocking-strict - igual que blocking, pero si ocurre un error durante el registro de la audtoría en la etapa RequestReceived, la petición completa al apiserver fallará.Los siguientes parámetros se usan únicamente en el modo batch:
--audit-webhook-batch-buffer-size define el número de eventos a almacenar de forma intermedia antes de procesar por lotes.
Si el ritmo de eventos entrantes desborda la memoria intermedia, dichos eventos se descartan.--audit-webhook-batch-max-size define el número máximo de eventos en un único proceso por lotes.--audit-webhook-batch-max-wait define la cantidad máxima de tiempo a esperar de forma incondicional antes de procesar los eventos de la cola.--audit-webhook-batch-throttle-qps define el promedio máximo de procesos por lote generados por segundo.--audit-webhook-batch-throttle-burst define el número máximo de procesos por lote generados al mismo tiempo si el QPS permitido no fue usado en su totalidad anteriormente.Los parámetros deberían ajustarse a la carga del apiserver.
Por ejemplo, si kube-apiserver recibe 100 peticiones por segundo, y para cada petición se audita
las etapas ResponseStarted y ResponseComplete, deberías esperar unos ~200
eventos de auditoría generados por segundo. Asumiendo que hay hasta 100 eventos en un lote,
deberías establecer el nivel de regulación (throttling) por lo menos a 2 QPS. Además, asumiendo
que el backend puede tardar hasta 5 segundos en escribir eventos, deberías configurar el tamaño de la memoria intermedia para almacenar hasta 5 segundos de eventos, esto es,
10 lotes, o sea, 1000 eventos.
En la mayoría de los casos, sin embargo, los valores por defecto de los parámetros deberían ser suficientes y no deberías preocuparte de ajustarlos manualmente. Puedes echar un vistazo a la siguientes métricas de Prometheus que expone kube-apiserver y también los logs para monitorizar el estado del subsistema de auditoría:
apiserver_audit_event_total métrica que contiene el número total de eventos de auditoría exportados.apiserver_audit_error_total métrica que contiene el número total de eventos descartados debido a un error durante su exportación.Tanto el backend de logs como el de webhook permiten truncado. Como ejemplo, aquí se indica la lista de parámetros disponible para el backend de logs:
audit-log-truncate-enabled indica si el truncado de eventos y por lotes está habilitado.audit-log-truncate-max-batch-size indica el tamaño máximo en bytes del lote enviado al backend correspondiente.audit-log-truncate-max-event-size indica el tamaño máximo en bytes del evento de auditoría enviado al backend correspondiente.Por defecto, el truncado está deshabilitado tanto en webhook como en log; un administrador del clúster debe configurar bien el parámetro audit-log-truncate-enabled o audit-webhook-truncate-enabled para habilitar esta característica.
Kubernetes v1.13 [alpha]
En la versión 1.13 de Kubernetes, puedes configurar de forma dinámica los backends de auditoría usando objetos de la API AuditSink.
Para habilitar la auditoría dinámica, debes configurar los siguientes parámetros de apiserver:
--audit-dynamic-configuration: el interruptor principal. Cuando esta característica sea GA, el único parámetro necesario.--feature-gates=DynamicAuditing=true: en evaluación en alpha y beta.--runtime-config=auditregistration.k8s.io/v1alpha1=true: habilitar la API.Cuando se habilita, un objeto AuditSink se provisiona de la siguiente forma:
apiVersion: auditregistration.k8s.io/v1alpha1
kind: AuditSink
metadata:
name: mysink
spec:
policy:
level: Metadata
stages:
- ResponseComplete
webhook:
throttle:
qps: 10
burst: 15
clientConfig:
url: "https://audit.app"
Para una definición completa de la API, ver AuditSink. Múltiples objetos existirán como soluciones independientes.
Aquellos backends estáticos que se configuran con parámetros en tiempo de ejecución no se ven impactados por esta característica. Sin embargo, estos backends dinámicos comparten las opciones de truncado del webhook estático, de forma que si dichas opciones se configura con parámetros en tiempo de ejecución, entonces se aplican a todos los backends dinámicos.
El reglamento de AuditSink es diferente del de la auditoría en tiempo de ejecución. Esto es debido a que el objeto de la API sirve para casos de uso diferentes. El reglamento continuará evolucionando para dar cabida a más casos de uso.
El campo level establece el nivel de auditoría indicado a todas las peticiones. El campo stages es actualmente una lista de las etapas que se permite registrar.
Los administradores deberían tener en cuenta que permitir el acceso en modo escritura de esta característica otorga el modo de acceso de lectura
a toda la información del clúster. Así, el acceso debería gestionarse como un privilegio de nivel cluster-admin.
Actualmente, esta característica tiene implicaciones en el apiserver en forma de incrementos en el uso de la CPU y la memoria. Aunque debería ser nominal cuando se trata de un número pequeño de destinos, se realizarán pruebas adicionales de rendimiento para entender su impacto real antes de que esta API pase a beta.
Si estás extendiendo la API de Kubernetes mediante la capa de agregación, puedes también configurar el registro de auditoría para el apiserver agregado. Para ello, pasa las opciones de configuración en el mismo formato que se describe arriba al apiserver agregado y configura el mecanismo de ingestión de logs para que recolecte los logs de auditoría. Cada uno de los apiservers puede tener configuraciones de auditoría diferentes con diferentes reglamentos de auditoría.
Fluentd es un recolector de datos de libre distribución que proporciona una capa unificada de registros. En este ejemplo, usaremos fluentd para separar los eventos de auditoría por nombres de espacio:
Instala fluentd, fluent-plugin-forest y fluent-plugin-rewrite-tag-filter en el nodo donde corre kube-apiserver
Crea un archivo de configuración para fluentd:
cat <<'EOF' > /etc/fluentd/config
# fluentd conf runs in the same host with kube-apiserver
<source>
@type tail
# audit log path of kube-apiserver
path /var/log/kube-audit
pos_file /var/log/audit.pos
format json
time_key time
time_format %Y-%m-%dT%H:%M:%S.%N%z
tag audit
</source>
<filter audit>
#https://github.com/fluent/fluent-plugin-rewrite-tag-filter/issues/13
@type record_transformer
enable_ruby
<record>
namespace ${record["objectRef"].nil? ? "none":(record["objectRef"]["namespace"].nil? ? "none":record["objectRef"]["namespace"])}
</record>
</filter>
<match audit>
# route audit according to namespace element in context
@type rewrite_tag_filter
<rule>
key namespace
pattern /^(.+)/
tag ${tag}.$1
</rule>
</match>
<filter audit.**>
@type record_transformer
remove_keys namespace
</filter>
<match audit.**>
@type forest
subtype file
remove_prefix audit
<template>
time_slice_format %Y%m%d%H
compress gz
path /var/log/audit-${tag}.*.log
format json
include_time_key true
</template>
</match>
EOF
Arranca fluentd:
fluentd -c /etc/fluentd/config -vv
Arranca el componente kube-apiserver con las siguientes opciones:
--audit-policy-file=/etc/kubernetes/audit-policy.yaml --audit-log-path=/var/log/kube-audit --audit-log-format=json
Comprueba las auditorías de los distintos espacios de nombres en /var/log/audit-*.log
Logstash es una herramienta de libre distribución de procesamiento de datos en servidor. En este ejemplo, vamos a usar logstash para recolectar eventos de auditoría a partir de un backend de webhook, y grabar los eventos de usuarios diferentes en archivos distintos.
Instala logstash
Crea un archivo de configuración para logstash:
cat <<EOF > /etc/logstash/config
input{
http{
#TODO, figure out a way to use kubeconfig file to authenticate to logstash
#https://www.elastic.co/guide/en/logstash/current/plugins-inputs-http.html#plugins-inputs-http-ssl
port=>8888
}
}
filter{
split{
# Webhook audit backend sends several events together with EventList
# split each event here.
field=>[items]
# We only need event subelement, remove others.
remove_field=>[headers, metadata, apiVersion, "@timestamp", kind, "@version", host]
}
mutate{
rename => {items=>event}
}
}
output{
file{
# Audit events from different users will be saved into different files.
path=>"/var/log/kube-audit-%{[event][user][username]}/audit"
}
}
EOF
Arranca logstash:
bin/logstash -f /etc/logstash/config --path.settings /etc/logstash/
Crea un archivo kubeconfig para el webhook del backend de auditoría de kube-apiserver:
cat <<EOF > /etc/kubernetes/audit-webhook-kubeconfig
apiVersion: v1
clusters:
- cluster:
server: http://<ip_of_logstash>:8888
name: logstash
contexts:
- context:
cluster: logstash
user: ""
name: default-context
current-context: default-context
kind: Config
preferences: {}
users: []
EOF
Arranca kube-apiserver con las siguientes opciones:
--audit-policy-file=/etc/kubernetes/audit-policy.yaml --audit-webhook-config-file=/etc/kubernetes/audit-webhook-kubeconfig
Comprueba las auditorías en los directorios /var/log/kube-audit-*/audit de los nodos de logstash
Nótese que además del plugin para salida en archivos, logstash ofrece una variedad de salidas adicionales que permiten a los usuarios enviar la información donde necesiten. Por ejemplo, se puede enviar los eventos de auditoría al plugin de elasticsearch que soporta búsquedas avanzadas y analíticas.
En la plataforma Google Compute Engine (GCE), por defecto da soporte a la escritura de logs haciendo uso de Stackdriver Logging, el cual se describe en detalle en Logging con Stackdriver Logging.
Este artículo describe cómo configurar un clúster para la ingesta de logs en Elasticsearch y su posterior visualización con Kibana, a modo de alternativa a Stackdriver Logging cuando se utiliza la plataforma GCE.
Para utilizar Elasticsearch y Kibana para escritura de logs del clúster, deberías configurar la siguiente variable de entorno que se muestra a continuación como parte de la creación del clúster con kube-up.sh:
KUBE_LOGGING_DESTINATION=elasticsearch
También deberías asegurar que KUBE_ENABLE_NODE_LOGGING=true (que es el valor por defecto en la plataforma GCE).
Así, cuando crees un clúster, un mensaje te indicará que la recolección de logs de los daemons de Fluentd que corren en cada nodo enviará dichos logs a Elasticsearch:
cluster/kube-up.sh
...
Project: kubernetes-satnam
Zone: us-central1-b
... calling kube-up
Project: kubernetes-satnam
Zone: us-central1-b
+++ Staging server tars to Google Storage: gs://kubernetes-staging-e6d0e81793/devel
+++ kubernetes-server-linux-amd64.tar.gz uploaded (sha1 = 6987c098277871b6d69623141276924ab687f89d)
+++ kubernetes-salt.tar.gz uploaded (sha1 = bdfc83ed6b60fa9e3bff9004b542cfc643464cd0)
Looking for already existing resources
Starting master and configuring firewalls
Created [https://www.googleapis.com/compute/v1/projects/kubernetes-satnam/zones/us-central1-b/disks/kubernetes-master-pd].
NAME ZONE SIZE_GB TYPE STATUS
kubernetes-master-pd us-central1-b 20 pd-ssd READY
Created [https://www.googleapis.com/compute/v1/projects/kubernetes-satnam/regions/us-central1/addresses/kubernetes-master-ip].
+++ Logging using Fluentd to elasticsearch
Tanto los pods por nodo de Fluentd, como los pods de Elasticsearch, y los pods de Kibana deberían ejecutarse en el namespace de kube-system inmediatamente después de que el clúster esté disponible.
kubectl get pods --namespace=kube-system
NAME READY STATUS RESTARTS AGE
elasticsearch-logging-v1-78nog 1/1 Running 0 2h
elasticsearch-logging-v1-nj2nb 1/1 Running 0 2h
fluentd-elasticsearch-kubernetes-node-5oq0 1/1 Running 0 2h
fluentd-elasticsearch-kubernetes-node-6896 1/1 Running 0 2h
fluentd-elasticsearch-kubernetes-node-l1ds 1/1 Running 0 2h
fluentd-elasticsearch-kubernetes-node-lz9j 1/1 Running 0 2h
kibana-logging-v1-bhpo8 1/1 Running 0 2h
kube-dns-v3-7r1l9 3/3 Running 0 2h
monitoring-heapster-v4-yl332 1/1 Running 1 2h
monitoring-influx-grafana-v1-o79xf 2/2 Running 0 2h
Los pods de fluentd-elasticsearch recogen los logs de cada nodo y los envían a los
pods de elasticsearch-logging, que son parte de un servicio llamado elasticsearch-logging.
Estos pods de Elasticsearch almacenan los logs y los exponen via una API REST.
El pod de kibana-logging proporciona una UI via web donde leer los logs almacenados en
Elasticsearch, y es parte de un servicio denominado kibana-logging.
Los servicios de Elasticsearch y Kibana ambos están en el namespace kube-system
y no se exponen de forma directa mediante una IP accesible públicamente. Para poder acceder a dichos logs,
sigue las instrucciones acerca de cómo Acceder a servicios corriendo en un clúster.
Si tratas de acceder al servicio de elasticsearch-logging desde tu navegador,
verás una página de estado que se parece a la siguiente:

A partir de ese momento, puedes introducir consultas de Elasticsearch directamente en el navegador, si lo necesitas. Echa un vistazo a la documentación de Elasticsearch para más detalles acerca de cómo hacerlo.
De forma alternativa, puedes ver los logs de tu clúster en Kibana (de nuevo usando las
instrucciones para acceder a un servicio corriendo en un clúster).
La primera vez que visitas la URL de Kibana se te presentará una página que te pedirá
que configures una vista de los logs. Selecciona la opción de valores de serie temporal
y luego @timestamp. En la página siguiente selecciona la pestaña de Discover
y entonces deberías ver todos los logs. Puedes establecer el intervalo de actualización
en 5 segundos para refrescar los logs de forma regular.
Aquí se muestra una vista típica de logs desde el visor de Kibana:

¡Kibana te permite todo tipo de potentes opciones para explorar tus logs! Puedes encontrar algunas ideas para profundizar en el tema en la documentación de Kibana.
Desde Kubernetes 1.8, las métricas de uso de recursos, tales como el uso de CPU y memoria del contenedor,
están disponibles en Kubernetes a través de la API de métricas. Estas métricas son accedidas directamente
por el usuario, por ejemplo usando el comando kubectl top, o usadas por un controlador en el cluster,
por ejemplo el Horizontal Pod Autoscaler, para la toma de decisiones.
A través de la API de métricas, Metrics API en inglés, puedes obtener la cantidad de recursos usados actualmente por cada nodo o pod. Esta API no almacena los valores de las métricas, así que no es posible, por ejemplo, obtener la cantidad de recursos que fueron usados por un nodo hace 10 minutos.
La API de métricas está completamente integrada en la API de Kubernetes:
/apis/metrics.k8s.io/La API está definida en el repositorio k8s.io/metrics. Puedes encontrar más información sobre la API ahí.
El Servidor de Métricas es un agregador
de datos de uso de recursos de todo el clúster.
A partir de Kubernetes 1.8, el servidor de métricas se despliega por defecto como un objeto de
tipo Deployment en clústeres
creados con el script kube-up.sh. Si usas otro mecanismo de configuración de Kubernetes, puedes desplegarlo
usando los yamls de despliegue
proporcionados. Está soportado a partir de Kubernetes 1.7 (más detalles al final).
El servidor reune métricas de la Summary API, que es expuesta por el Kubelet en cada nodo.
El servidor de métricas se añadió a la API de Kubernetes utilizando el Kubernetes aggregator introducido en Kubernetes 1.7.
Puedes aprender más acerca del servidor de métricas en el documento de diseño.