You are viewing documentation for Kubernetes version: v1.32

Kubernetes v1.32 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

Usa kubectl para actualizar objetos del API de kubernetes sin reemplazarlos. Usa strategic merge o JSON merge .

Esta tarea muestra cómo utilizar kubectl para actualizar un objeto del API sin reemplazarlo. Los ejercicios de esta tarea demuestran el uso de "strategic merge " y "JSON merge "

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:

Para comprobar la versión, introduzca kubectl version.

Usa strategic merge 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: -demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: -demo-ctr
        image: nginx
      tolerations:
      - effect: NoSchedule
        key: dedicated
        value: test-team

Crea el Deployment:

kubectl apply -f https://k8s.io/examples/application/deployment-.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
-demo-28633765-670qr   1/1       Running   0          23s
-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 -file.yaml con el siguiente contenido:

spec:
  template:
    spec:
      containers:
      - name: -demo-ctr-2
        image: redis

Modifica tu Deployment usando :

kubectl  deployment -demo ---file -file.yaml

Revisa el Deployment modificado:

kubectl get deployment -demo --output yaml

El resultado muestra que el PodSpec del Deployment tiene dos contenedores:

containers:
- image: redis
  imagePullPolicy: Always
  name: -demo-ctr-2
  ...
- image: nginx
  imagePullPolicy: Always
  name: -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
-demo-1081991389-2wrn5   2/2       Running   0          1m
-demo-1081991389-jmg7b   2/2       Running   0          1m

Un vistazo más de cerca a uno de los Pods del -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

El que hiciste en el ejercicio anterior se llama strategic merge . 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 fue agregada a la lista ya existente. Esto no es lo que pasa siempre que se utiliza strategic merge en una lista. En algunos casos la lista existente podría ser reemplazada en lugar de unir ambas.

Con strategic merge , la lista existente puede ser reemplazada o unida con la nueva dependiendo de la estrategia de . La estrategia de se especifica en el valor de la clave Strategyen 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 Strategy:

type PodSpec struct {
  ...
  Containers []Container `json:"containers" Strategy:"merge" MergeKey:"name" ...`
  ...
}

También puedes consultar la estrategia de en OpenApi spec:

"io.k8s.api.core.v1.PodSpec": {
    ...,
    "containers": {
        "description": "List of containers belonging to the pod.  ...."
    },
    "x-kubernetes--merge-key": "name",
    "x-kubernetes--strategy": "merge"
}

Y puedes consultar la estrategia de en la Documentación del API Kubernetes.

Crea un archivo llamado -file-tolerations.yaml que tenga el siguiente contenido:

spec:
  template:
    spec:
      tolerations:
      - effect: NoSchedule
        key: disktype
        value: ssd

Modifica tu Deployment utilizando :

kubectl  deployment -demo ---file -file-tolerations.yaml

Revisa el Deployment modificado:

kubectl get deployment -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 Strategy en su campo de tag. por lo tanto strategic merge utiliza la estrategia de por defecto, la cual es replace.

type PodSpec struct {
  ...
  Tolerations []Toleration `json:"tolerations,omitempty" protobuf:"bytes,22,opt,name=tolerations"`
  ...
}

Usa JSON merge para actualizar un Deployment

Un strategic merge es distinto a un JSON merge .

Con JSON merge , 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 tiene un parámetro type que acepta los siguientes valores:

Valor del parámetrotipo de unión
jsonJSON , RFC 6902
mergeJSON Merge , RFC 7386
strategicStrategic merge

Para una comparación entre JSON y JSON merge , revisa JSON y JSON Merge .

El valor predeterminado para el parámetro type es strategic. Entonces en el ejercicio anterior hiciste un strategic merge .

A continuación haz un JSON merge path en el mismo Deployment. Crea un archivo llamado -file-2.yaml que tenga el siguiente contenido:

spec:
  template:
    spec:
      containers:
      - name: -demo-ctr-3
        image: gcr.io/google-samples/node-hello:1.0

En el comando configura el valor de type como merge

kubectl  deployment -demo --type merge ---file -file-2.yaml

Revisa el Deployment modificado:

kubectl get deployment -demo --output yaml

La lista containers que especificaste en el 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: -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
-demo-1307768864-69308   1/1       Running   0          1m
-demo-1307768864-c86dc   1/1       Running   0          1m

Usa strategic merge 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 -file-no-retainkeys.yaml con el siguiente contenido:

spec:
  strategy:
    type: Recreate

Modifica tu Deployment:

kubectl  deployment retainkeys-demo --type strategic ---file -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 -file-retainkeys.yaml con el siguiente contenido:

spec:
  strategy:
    $retainKeys:
    - type
    type: Recreate

Con este 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 :

kubectl  deployment retainkeys-demo --type strategic ---file -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 utilizando la estrategia retainKeys

La modificación realizada en el ejercicio anterior tiene el nombre de strategic merge 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 .

La estrategia retainKeys no funciona para todos los objetos. Solo funciona cuando el valor de la key Strategyen 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 Strategy

type DeploymentSpec struct {
  ...
  // +Strategy=retainKeys
  Strategy DeploymentStrategy `json:"strategy,omitempty" Strategy:"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--strategy": "retainKeys"
    },
    ....
}

Además puedes revisar la estrategia retainKeys en la documentación del API de k8s.

Formas alternativas del comando kubectl

El comando kubectl 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 -file.json que contenga lo siguiente:

{
   "spec": {
      "template": {
         "spec": {
            "containers": [
               {
                  "name": "-demo-ctr-2",
                  "image": "redis"
               }
            ]
         }
      }
   }
}

Los siguientes comandos son equivalentes:

kubectl  deployment -demo ---file -file.yaml
kubectl  deployment -demo -- 'spec:\n template:\n  spec:\n   containers:\n   - name: -demo-ctr-2\n     image: redis'

kubectl  deployment -demo ---file -file.json
kubectl  deployment -demo -- '{"spec": {"template": {"spec": {"containers": [{"name": "-demo-ctr-2","image": "redis"}]}}}}'

Actualiza la cantidad de réplicas de un objeto utilizando kubectl con --subresource

FEATURE STATE: Kubernetes v1.24 [alpha]

La bandera --subresource=[subresource-name] es utilizada con comandos de kubectl como get, 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 con la bandera --subresource=[subresource-name]:

kubectl  deployment nginx-deployment --subresource='scale' --type='merge' -p '{"spec":{"replicas":3}}'

El resultado es :

scale.autoscaling/nginx-deployment ed

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

Resumen

En este ejercicio utilizaste kubectl 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.

Siguientes pasos

Última modificación May 17, 2024 at 3:52 PM PST: changes for electrocucaracha suggestions (77ef891682)