Realiza actualizaciones progresivas


En esta página, se explica cómo realizar actualizaciones progresivas para aplicaciones en Google Kubernetes Engine.

Descripción general

Puedes realizar una actualización progresiva para actualizar las imágenes, la configuración, las etiquetas, las anotaciones y los límites o solicitudes de recursos de las cargas de trabajo en los clústeres. Las actualizaciones progresivas reemplazan de manera gradual los pods de tus recursos por otros nuevos, que luego se programan en nodos con recursos disponibles. Las actualizaciones progresivas están diseñadas para actualizar las cargas de trabajo sin tiempo de inactividad.

Los siguientes objetos representan las cargas de trabajo de Kubernetes. Puedes activar una actualización progresiva de estas cargas de trabajo si actualizas su plantilla de pods:

  • DaemonSets
  • Deployments
  • StatefulSets

Cada uno de estos objetos tiene una plantilla de pods, representada por el campo spec: template en el manifiesto del objeto. El campo de plantilla de pods contiene una especificación para los pods que crea el controlador a fin de conseguir el estado o comportamiento deseado. Se activa un lanzamiento de actualización si el objeto spec: template se actualiza.

La plantilla de Pods incluye los siguientes campos:

Para obtener más información sobre la plantilla de pods, consulta la documentación de PodTemplateSpec.

Escalar un recurso o actualizar campos fuera de la plantilla de pods no activa un lanzamiento.

Antes de comenzar

Antes de comenzar, asegúrate de haber realizado las siguientes tareas:

  • Habilita la API de Kubernetes Engine de Google.
  • Habilitar la API de Kubernetes Engine de Google
  • Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta gcloud components update para obtener la versión más reciente.

Actualiza una aplicación

En la siguiente sección, se explica cómo puedes actualizar una aplicación con la consola de Google Cloud o kubectl.

kubectl set

Puedes usar kubectl set para realizar cambios en los campos image, resources (recurso de procesamiento, como CPU y memoria) o selector de un objeto.

Por ejemplo, para actualizar una implementación de las versiones 1.7.9 a 1.9.1 de nginx, ejecuta el siguiente comando:

kubectl set image deployment nginx nginx=nginx:1.9.1

El comando kubectl set image actualiza la imagen nginx de los pods de la implementación de uno en uno.

Este es otro ejemplo para configurar las solicitudes y límites de recursos de la implementación:

kubectl set resources deployment nginx --limits cpu=200m,memory=512Mi --requests cpu=100m,memory=256Mi

O bien, para quitar las solicitudes de recursos del Deployment:

kubectl set resources deployment nginx --limits cpu=0,memory=0 --requests cpu=0,memory=0

kubectl apply

Puedes usar kubectl apply para actualizar un recurso si aplicas una configuración nueva o actualizada.

Para aplicar una configuración nueva o actualizada a un recurso, ejecuta el siguiente comando:

kubectl apply -f MANIFEST

Reemplaza MANIFEST por el nombre del archivo de manifiesto. Si no existe el archivo, este comando crea el recurso y aplica la configuración; de lo contrario, se aplica la configuración actualizada.

Console

Para editar la configuración activa de una aplicación, sigue estos pasos:

  1. Ve a la página Cargas de trabajo en la consola de Google Cloud.

    Ir a Cargas de trabajo

  2. Elige la carga de trabajo que deseas actualizar.

  3. En la página Detalles de la implementación, haz clic en Acciones > Actualización progresiva.

  4. En el cuadro de diálogo Actualización progresiva, configura la imagen de la carga de trabajo.

  5. Haz clic en Actualizar.

Administra un lanzamiento de actualizaciones

Puedes usar kubectl rollout para inspeccionar un lanzamiento a medida que ocurre, pausar y reanudarlo, revertir una actualización y ver el historial de lanzamiento de un objeto.

Inspecciona un lanzamiento con kubectl rollout status

Puedes inspeccionar el estado de un lanzamiento mediante el comando kubectl rollout status.

Por ejemplo, puedes ejecutar el siguiente comando para inspeccionar el lanzamiento de la implementación de nginx:

kubectl rollout status deployment nginx

El resultado es similar al siguiente:

Waiting for rollout to finish: 2 out of 3 newreplicas have been updated...
deployment "nginx" successfully rolled out

Después de que el lanzamiento se realice con éxito, ejecuta kubectl get deployment nginx para verificar que todos los pods estén en ejecución. El resultado es similar al siguiente:

NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx              3         3         3            3           36s

Detén y reanuda un lanzamiento

Puedes usar kubectl rollout pause para pausar un lanzamiento.

Por ejemplo, para pausar el lanzamiento de la implementación de nginx, ejecuta el siguiente comando:

kubectl rollout pause deployment nginx

Para reanudar, ejecuta el siguiente comando:

kubectl rollout resume deployment nginx

Visualiza el historial de lanzamiento con kubectl rollout history

Puedes usar kubectl rollout history para ver el historial de lanzamiento de un objeto.

Por ejemplo, para ver el historial de lanzamiento de la implementación de nginx, ejecuta el siguiente comando:

kubectl rollout history deployment nginx

Para ver el historial de la tercera revisión, ejecuta el siguiente comando:

kubectl rollout history deployment nginx --revision 3

Revierte una actualización con kubectl rollout undo

Puedes revertir el lanzamiento de un objeto con el comando kubectl rollout undo.

Por ejemplo, para revertir la implementación de nginx a la versión anterior, ejecuta el siguiente comando:

kubectl rollout undo deployments nginx

Como otro ejemplo, ejecuta el siguiente comando para revertir la implementación a la tercera revisión:

kubectl rollout undo deployment nginx --to-revision 3

Consideraciones para StatefulSets y DaemonSets

StatefulSets desde Kubernetes 1.7 y DaemonSets desde Kubernetes 1.6 usan una estrategia de actualización a fin de configurar además de inhabilitar actualizaciones progresivas y automatizadas de contenedores, etiquetas, solicitudes o límites de recursos y anotaciones para sus pods. La estrategia de actualización se configura mediante el campo spec.updateStrategy.

El campo spec.updateStrategy.type acepta OnDelete o RollingUpdate como valores.

OnDelete es el comportamiento predeterminado cuando spec.updateStrategy.type no se especifica. OnDelete evita que el controlador actualice de manera automática sus pods. Debes borrar los pods de forma manual para que el controlador cree pods nuevos que reflejen los cambios. OnDelete es útil si prefieres actualizar los pods de forma manual.

RollingUpdate implementa actualizaciones progresivas y automáticas para los Pods en StatefulSet. RollingUpdate hace que el controlador borre y vuelva a crear todos sus pods uno a la vez. Espera hasta que un pod actualizado esté en ejecución y listo antes de actualizar a su predecesor.

El controlador de StatefulSet actualiza todos los pods en orden inverso y respeta las garantías de StatefulSet.

Usa la estrategia de RollingUpdate

Puedes usar la estrategia de RollingUpdate para actualizar de manera automática todos los pods en un StatefulSet o DaemonSet.

Por ejemplo, para aplicar un parche al StatefulSet de web a fin de aplicar la estrategia de RollingUpdate, ejecuta el siguiente comando:

kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate"}}}'

Luego, realiza un cambio en el spec.template de StatefulSet. Por ejemplo, puedes usar kubectl set para cambiar la imagen del contenedor. En el siguiente ejemplo, el StatefulSet de web está configurado para que su contenedor nginx ejecute la imagen nginx-slim:0.7:

kubectl set image statefulset web nginx=nginx-slim:0.7

Para comprobar que los pods del StatefulSet que ejecutan el contenedor nginx se actualicen, ejecuta el siguiente comando:

kubectl get pods -l app=nginx -w

El resultado es similar al siguiente:

NAME      READY     STATUS              RESTARTS  AGE
web-0     1/1       Running             0         7m
web-1     1/1       Running             0         7m
web-2     1/1       Running             0         8m
web-2     1/1       Terminating         0         8m
web-2     1/1       Terminating         0         8m
web-2     0/1       Terminating         0         8m
web-2     0/1       Terminating         0         8m
web-2     0/1       Terminating         0         8m
web-2     0/1       Terminating         0         8m
web-2     0/1       Pending             0         0s
web-2     0/1       Pending             0         0s
web-2     0/1       ContainerCreating   0         0s
web-2     1/1       Running             0         19s
web-1     1/1       Terminating         0         8m
web-1     0/1       Terminating         0         8m
web-1     0/1       Terminating         0         8m
web-1     0/1       Terminating         0         8m
web-1     0/1       Pending             0         0s
web-1     0/1       Pending             0         0s
web-1     0/1       ContainerCreating   0         0s
web-1     1/1       Running             0         6s
web-0     1/1       Terminating         0         7m
web-0     1/1       Terminating         0         7m
web-0     0/1       Terminating         0         7m
web-0     0/1       Terminating         0         7m
web-0     0/1       Terminating         0         7m
web-0     0/1       Terminating         0         7m
web-0     0/1       Pending             0         0s
web-0     0/1       Pending             0         0s
web-0     0/1       ContainerCreating   0         0s
web-0     1/1       Running             0         10s

Los pods en el StatefulSet se actualizan en orden inverso. El controlador del StatefulSet finaliza cada pod y espera a que pase a los estados “En ejecución” y “Listo” antes de actualizar el siguiente pod.

Particiona un RollingUpdate

Puedes especificar un parámetro de partition en el campo RollingUpdate del StatefulSet.

Si especificas un partition, se actualizarán todos los pods con un número ordinal mayor o igual al valor partition. Todos los pods con un número ordinal menor al valor partition no se actualizarán y se volverán a crear en la versión anterior, incluso si se borran.

Si un valor partition es mayor que su número de replicas, las actualizaciones no se propagan a sus pods. La partición es útil si deseas habilitar por etapas una actualización, implementar una compilación Canary o realizar una implementación por fases.

Por ejemplo, para particionar el StatefulSet de web, ejecuta el siguiente comando:

kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":3}}}}'

Esto hace que se actualicen los pods con un número ordinal mayor o igual que 3.

Parámetros maxUnavailable y maxSurge de DaemonSet

El parámetro maxUnavailable y maxSurge opcional de DaemonSet son elementos secundarios del campo rollingUpdate de DaemonSet.

maxUnavailable determina la cantidad máxima de pods de DaemonSet que pueden no estar disponibles durante las actualizaciones. El valor predeterminado es 1, si se omite.

maxSurge es la cantidad máxima de Pods que se pueden escalar verticalmente durante las actualizaciones. El valor predeterminado es 0, si se omite.

Ninguno de los valores puede ser 0 si el otro valor es 0. Ambos valores pueden ser un número absoluto o un porcentaje.

Para obtener más información, consulta DaemonSetSpec.

Actualiza con la estrategia de OnDelete

Si prefieres actualizar un StatefulSet o DaemonSet de forma manual, puedes omitir el campo spec.updateStrategy, que le indica al controlador que use la estrategia de OnDelete.

Para actualizar un controlador que usa la estrategia de OnDelete, debes borrar sus pods de forma manual después de hacer cambios en su plantilla de pods.

Por ejemplo, puedes configurar el StatefulSet de web para usar la imagen nginx-slim:0.7:

kubectl set image statefulset web nginx=nginx-slim:0.7

Luego, para borrar el primer pod de web, ejecuta el siguiente comando:

kubectl delete pod web-0

Para mirar cómo se vuelve a crear el pod mediante el StatefulSet y su estado cambia de “En ejecución” a “Listo”, ejecuta el siguiente comando:

kubectl get pod web-0 -w

El resultado de este comando es similar al siguiente:

NAME      READY     STATUS               RESTARTS  AGE
web-0     1/1       Running              0         54s
web-0     1/1       Terminating          0         1m
web-0     0/1       Terminating          0         1m
web-0     0/1       Terminating          0         1m
web-0     0/1       Terminating          0         1m
web-0     0/1       Pending              0         0s
web-0     0/1       Pending              0         0s
web-0     0/1       ContainerCreating    0         0s
web-0     1/1       Running              0         3s

Cómo actualizar un trabajo

Cuando actualizas la configuración de un trabajo, el trabajo nuevo y sus pods se ejecutan con la configuración nueva. Después de actualizar un trabajo, debes borrar de forma manual el trabajo anterior y sus pods, si es necesario.

Para borrar un trabajo y todos sus pods, ejecuta el siguiente comando:

kubectl delete job my-job

Para borrar un trabajo y mantener sus pods en ejecución, especifica la marca --cascade=false:

kubectl delete job my-job --cascade=false

También puedes ejecutar kubectl describe deployment nginx, lo que genera aún más información sobre la implementación.

¿Qué sigue?