Versión imprimible multipagina. Haga click aquí para imprimir.
Administrar Objetos en Kubernetes
- 1: Administración declarativa de Objetos en Kubernetes usando archivos de Configuración
- 2: Manejo Declarativo de Objectos de Kubernetes usando Kustomize
- 3: Administración Imperativa de Objetos de Kubernetes Mediante Archivos de Configuración
- 4: Actualiza Objetos del API en su sitio (in Place) usando kubectl patch
1 - Administración declarativa de Objetos en Kubernetes usando archivos de Configuració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á.
Antes de empezar
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:
kubectl version
.
Modos de administración
La herramienta kubectl
soporta tres modos distintos para la administración de objetos:
- Comandos imperativos
- Configuración de objetos imperativa
- Configuración de objetos declarativa
Acceda Administración de objetos de Kubernetes para una discusión de las ventajas y desventajas de cada modo distinto de administración.
Visión general
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:
- Administración de Objetos de Kubernetes usando comandos imperativos
- Administración imperativa de los Objetos de Kubernetes usando archivos de Configuración
A continuación la definición de términos usados en este documento:
- archivo de configuración de objeto / archivo de configuración: Un archivo en el
que se define la configuración de un objeto de Kubernetes. Este tema muestra como
utilizar archivos de configuración con
kubectl apply
. Los archivos de configuración por lo general se almacenan en un sistema de control de versiones, como Git. - configuración activa de objeto / configuración activa: Los valores de configuración activos de un objeto, según estén siendo observados por el Clúster. Esta configuración se almacena en el sistema de almacenamiento de Kubernetes, usualmente etcd.
- escritor de configuración declarativo / escritor declarativo: Una persona o
componente de software que actualiza a un objeto activo. Los escritores activos a
los que se refiere este tema aplican cambios a los archivos de configuración de objetos
y ejecutan
kubectl apply
para aplicarlos.
Como crear objetos
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.
Nota:
Agregue la opción-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
Nota:
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
# ...
# ...
# ...
# ...
Como actualizar objetos
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:
- Definir los campos que aparecerán en la configuración activa.
- Eliminar aquellos campos eliminados en el archivo de configuración, de la configuración activa.
kubectl diff -f <directorio>/
kubectl apply -f <directorio>/
Nota:
Agregue la opción-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
Nota:
Con el propósito de ilustrar, el comando anterior se refiere a un único archivo de configuración en vez de un directorio.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:
- El campo
replicas
retiene el valor de 2 definido porkubectl scale
. Esto es posible ya que el campo fue omitido en el archivo de configuración. - El campo
image
ha sido actualizado denginx:1.16.1
anginx:1.14.2
. - La anotación
last-applied-configuration
ha sido actualizada con la nueva imagen. - El campo
minReadySeconds
ha sido despejado. - La anotación
last-applied-configuration
ya no contiene el campominReadySeconds
apiVersion: 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
# ...
# ...
# ...
# ...
Advertencia:
No se puede combinarkubectl 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.Como eliminar objetos
Hay dos opciones diferentes para eliminar objetos gestionados por kubectl apply
.
Manera recomendada: 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>
Manera alternativa: kubectl apply -f <directorio/> --prune -l etiqueta=deseada
Únicamente utilice esta opción si está seguro de saber lo que está haciendo.
Advertencia:
kubectl apply --prune
se encuentra aún en alpha, y cambios incompatibles con versiones previas
podrían ser introducidos en lanzamientos futuros.Advertencia:
Sea cuidadoso(a) al usar este comando, para evitar eliminar objetos no intencionalmente.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>
Advertencia:
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.Como visualizar un objeto
Puede usar kubectl get
con -o yaml
para ver la configuración de objetos activos:
kubectl get -f <archivo|url> -o yaml
Como son las diferencias calculadas y unidas por apply
Precaución:
Un patch (parche) es una operación de actualización con alcance a campos específicos de un objeto, y no al objeto completo. Esto permite actualizar únicamente grupos de campos específicos en un objeto sin tener que leer el objeto primero.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.
Calculando la unión de un patch
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:
- Calculo de campos por eliminar. Estos son los campos presentes en
last-applied-configuration
pero ausentes en el archivo de configuración. - Calculo de campos por agregar o definir. Estos son los campos presentes en el archivo de configuración, con valores inconsistentes con la configuración activa.
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
:
- Calcular los campos por eliminar, leyendo los valores de
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ónlast-applied-configuration
. En este ejemplo,minReadySeconds
aparece en la anotaciónlast-applied-configuration
pero no aparece en el archivo de configuración. Acción: LimpiarminReadySeconds
de la configuración activa. - Calcular los campos por ser definidos, al leer los valores del fichero de configuración
y compararlos con los valores en la configuración activa. En este ejemplo, el valor
image
en el archivo de configuración, no coincide con el valor en la configuración activa. Acción: Definir el campoimage
en la configuración activa. - Definir el valor de la anotación
last-applied-configuration
para que sea consistente con el archivo de configuración. - Unir los resultados de 1, 2 y 3, en una única solicitud de patch para enviar al servidor de API.
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
# ...
# ...
# ...
# ...
Como se unen los diferentes tipos de campos
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
yreplicas
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
ymetadata
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
, yargs
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.
Uniendo cambios en campos primitivos
Campos primitivos son limpiados o reemplazados.
Nota:
-
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. |
Uniendo cambios en campos de un mapa
Los campos que conjuntamente representan un mapa, son unidos al comparar cada uno de los subcampos o elementos del mapa:
Nota:
-
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. |
Uniendo cambios en campos de tipo lista
El unir cambios en una lista utiliza una de tres posibles estrategias:
- Reemplazar la lista si todos sus elementos son primitivos.
- Unir elementos individuales en líneas de elementos complejos.
- Unir una lista de elementos primitivos.
Se define la estrategia elegida con base en cada campo.
Reemplazar una lista si todos sus elementos son primitivos
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.
Unir elementos individuales en una lista de elementos complejos
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:
- El contenedor llamado "nginx-helper-a" fué eliminado al no aparecer ningún contenedor llamado "nginx-helper-a" en el archivo de configuración.
- El contenedor llamado "nginx-helper-b" mantiene los cambios existentes en
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 existeargs
en el archivo de configuración). Esto sucede debido a que el valor del campopatchMergeKey
(name) es idéntico en ambos. - El contenedor llamado "nginx-helper-c" fue agregado ya que no existe ningún contenedor con ese nombre en la configuración activa, pero si existe uno con ese nombre en el archivo de configuración.
- El contendor llamado "nginx-helper-d" fue conservado debido a que no aparece ningún elemento con ese nombre en last-applied-configuration.
Unir una lista de elementos primitivos
A partir de Kubernetes 1.5, el unir listas de elementos primitivos no es soportado.
Nota:
La etiquetapatchStrategy
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
.Valores de campo por defecto
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:
- El usuario crea un Deployment sin definir
strategy.type
. - El servidor define
strategy.type
a su valor por defecto deRollingUpdate
y agrega los valores por defecto astrategy.rollingUpdate
. - El usuario cambia
strategy.type
aRecreate
. Los valores destrategy.rollingUpdate
se mantienen en su configuración por defecto, sin embargo el servidor espera que se limpien. Si los valores destrategy.rollingUpdate
hubiesen sido definidos inicialmente en el archivo de configuración, hubiese sido más claro que requerían ser eliminados. - Apply fallará debido a que
strategy.rollingUpdate
no fue eliminado. El campostrategy.rollingupdate
no puede estar definido, si el valor destrategy.type
esRecreate
.
Recomendación: Estos campos deberían de ser definidos de manera explícita en el archivo de configuración:
- Etiquetas de Selectors y PodTemplate en cargas de trabajo como Deployment, StatefulSet, Job, DaemonSet, ReplicaSet, y ReplicationController
- Estrategia de rollout para un Deployment
Como limpiar campos definidos a valores por defecto por el servidor, o definidos por otros escritores
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.
Como cambiar al propietario de un campo entre un archivo de configuración y un escritor imperativo
Estos son los únicos métodos que debe usar para cambiar un campo individual de un objeto:
- Usando
kubectl apply
. - Escribiendo de manera directa a la configuración activa sin modificar el archivo de configuración:
por ejemplo, usando
kubectl scale
.
Cambiando al propietario de un campo de un escritor imperativo a un archivo de configuración
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
.
Cambiando al propietario de un archivo de configuración a un escritor imperativo
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:
- Eliminar el campo del archivo de configuración.
- Eliminar el campo de la anotación
kubectl.kubernetes.io/last-applied-configuration
en el objeto activo.
Cambiando los métodos de gestión
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.
Nota:
Esta bien el usar eliminación imperativa junto a gestión declarativa.Migrando de gestión imperativa con comandos a configuración declarativa de objetos
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.Nota:
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.
Migrando de gestión imperativa de la configuración de objetos a gestión declarativa
-
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.
Definiendo los selectores para el controlador y las etiquetas de PodTemplate
Advertencia:
Se desaconseja encarecidamente actualizar los selectores en controladores.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"
Siguientes pasos
2 - Manejo Declarativo de Objectos de Kubernetes usando Kustomize
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>
Antes de empezar
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:
kubectl version
.
Descripción General de Kustomize
Kustomize es una herramienta para personalizar configuraciones de Kubernetes. Ofrece características para manejar archivos de configuración de aplicaciones, tales como:
- Generar recursos a partir de otras fuentes.
- Establecer campos transversales para los recursos.
- Componer y personalizar colecciones de recursos.
Generando Recursos
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.
configMapGenerator
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
Nota:
Cada variable en el archivo.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
secretGenerator
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
generatorOptions
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
Establecer campos transversales
Es bastante común establecer campos transversales para todos los recursos de Kubernetes en un proyecto. Algunos casos de uso para establecer campos transversales:
- Establecer el mismo espacio de nombres para todos los Recursos
- Agregar el mismo prefijo o sufijo de nombre
- Agregar el mismo conjunto de etiquetas
- Agregar el mismo conjunto de anotaciones
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
Componiendo y Personalizando Recursos
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.
Composición
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.
Personalizando
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
Bases y Overlays
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
Cómo aplicar/ver/eliminar objetos usando Kustomize
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
Kustomize Feature List
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. |
Siguientes pasos
3 - Administración Imperativa de Objetos de Kubernetes Mediante Archivos de Configuración
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.
Antes de empezar
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:
kubectl version
.
Opciones
La herramienta kubectl
admite tres tipos de administración de objetos:
- Comandos imperativos
- Configuración de objeto imperativo.
- Configuración de objeto declarativo
Consulta Administración de objetos de Kubernetes para una discusión de las ventajas y desventajas de cada tipo de administración de objetos.
¿Cómo crear 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>
¿Cómo actualizar objetos?
Advertencia:
La actualización de objetos con el comandoreplace
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>
¿Cómo eliminar objetos?
Puedes usar kubectl delete -f
para eliminar un objeto que se describe en un
archivo de configuración.
kubectl delete -f <filename|url>
Nota:
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>
¿Cómo ver un objeto?
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 yaml
La bandera -o yaml
especifica que se imprime la configuración completa del objeto. Utiliza kubectl get -h
para ver una lista de opciones.
Limitaciones
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:
- Creas un objeto a partir de un archivo de configuración.
- Otra fuente actualiza el objeto cambiando algún campo.
- Reemplaza el objeto del archivo de configuración. Cambios hechos por la otra fuente en el paso 2 se pierden.
Si necesitas admitir varios escritores en el mismo objeto, puede usar kubectl apply
para administrar el objeto.
Crear y editar un objeto desde una URL sin guardar la configuración
Supongamos que tienes la URL de un archivo de configuración de objeto. Puedes usar
- Exporta el objeto en vivo a un archivo de configuración de objeto local. que apuntan a un archivo de configuración que podría ser modificado por el lector.
kubectl create -f <url> --edit
Migración de comandos imperativos a configuración de objetos imperativos
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
Definiendo selectores de controlador y etiquetas PodTemplate
Advertencia:
Se desaconseja encarecidamente actualizar los selectores de los controladores.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.32/)
controller-selector: "apps/v1/deployment/nginx"
Siguientes pasos
4 - Actualiza Objetos del API en su sitio (in Place) usando kubectl patch
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"
Antes de empezar
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:
kubectl version
.
Usa strategic merge patch para actualizar un Deployment
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
...
Notas acerca de strategic merge patch
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
patchStrategy
en 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"`
...
}
Usa JSON merge patch para actualizar un Deployment
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
Usa strategic merge patch para actualizar un Deployment utilizando la estrategia retainKeys
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:
Notas acerca de strategic merge patch utilizando la estrategia retainKeys
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:
- Contiene una lista de strings.
- Todos los campos que necesiten ser preservados deben estar presentes en la lista
$retainKeys
. - Todos los campos que estén presentes serán combinados con el objeto existente.
- Todos los campos faltantes serán removidos o vaciados al momento de la modificación.
- Todos los campos en la lista
$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 patchStrategy
en 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.
Formas alternativas del comando kubectl patch
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"}]}}}}'
Actualiza la cantidad de réplicas de un objeto utilizando kubectl patch
con --subresource
Kubernetes 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
Nota:
Si ejecutaskubectl 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.Resumen
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.