You are viewing documentation for Kubernetes version: v1.30
Kubernetes v1.30 ya no mantiene activamente la documentación. La versión que está viendo actualmente es una instantánea estática. Para la documentación actualizada, visita la última versión.
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 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"` ... } 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
$retainKeysdeberá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.
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.