Saltar al contenido principal

Actualización de un Deployment (rollout y rollback)

El ciclo de vida del desarrollo de aplicaciones con contenedores facilita la labor de versionar nuestros desarrollos. Por cada nueva versión de nuestra aplicación, podemos crear una nueva imagen del contenedor y versionarla utilizando la etiqueta del nombre de la imagen.

Al crear un Deployment, indicaremos la imagen desde la que se crearán los Pods, especificando la etiqueta que indica la versión de la aplicación que vamos a desplegar.

Una vez creado un Deployment a partir de una imagen de una versión determinada, los Pods ejecutarán la versión indicada de la aplicación.

¿Cómo actualizar a una nueva versión de la aplicación?

  1. Modificar el valor del parámetro image para indicar una nueva imagen, especificando la nueva versión mediante el cambio de etiqueta.
  2. El Deployment se actualizará, creando un nuevo ReplicaSet que generará nuevos Pods con la nueva versión de la aplicación.
  3. Según la estrategia de despliegue indicada, se irán eliminando los antiguos Pods y creando los nuevos.
  4. El Deployment guardará el ReplicaSet antiguo, por si en algún momento queremos volver a la versión anterior.

Veamos este proceso con más detalle mediante un ejemplo de despliegue:

Desplegando la aplicación MediaWiki

Partimos del archivo mediawiki-deployment.yaml para desplegar la aplicación:

apiVersion: apps/v1
kind: Deployment
metadata:
name: mediawiki
labels:
app: mediawiki
spec:
replicas: 1
selector:
matchLabels:
app: mediawiki
template:
metadata:
labels:
app: mediawiki
spec:
containers:
- name: contenedor-mediawiki
image: mediawiki:1.31
ports:
- containerPort: 80

Desplegamos la versión 1.31 de MediaWiki con la siguiente instrucción:

kubectl apply -f mediawiki-deployment.yaml

Podemos "anotar" en el despliegue la causa del nuevo despliegue para visualizar el historial de modificaciones:

kubectl annotate deployment/mediawiki kubernetes.io/change-cause="Primer despliegue. Desplegamos versión 1.31"

Comprobamos los recursos creados:

kubectl get all

Accedemos al Pod con un port-forward para verificar que la versión actual de MediaWiki es la 1.31:

kubectl port-forward deployment/mediawiki 8080:80

mediawiki

Actualizar un Deployment

Para desplegar una versión más reciente de MediaWiki, modificamos el campo image de nuestro Deployment. Esto se puede hacer de varias formas:

  1. Modificando el archivo YAML y ejecutando kubectl apply.
  2. Ejecutando la siguiente instrucción:
kubectl set image deployment/mediawiki contenedor-mediawiki=mediawiki:1.34

Al actualizar el Deployment, se creará un nuevo ReplicaSet que generará los nuevos Pods con la versión modificada de la imagen. La creación y eliminación de Pods dependerá de la estrategia de despliegue:

  • La estrategia por defecto es RollingUpdate, que crea los nuevos Pods, verifica su funcionamiento y luego elimina los antiguos.
  • La estrategia Recreate elimina los Pods antiguos y crea los nuevos.

Anotamos el motivo del cambio del despliegue:

kubectl annotate deployment/mediawiki kubernetes.io/change-cause="Segundo despliegue. Actualizamos a la versión 1.34"

Comprobamos los recursos creados en la actualización:

kubectl get all

Kubernetes utiliza el término rollout para la gestión de diferentes versiones de despliegues. Podemos ver el historial de actualizaciones:

kubectl rollout history deployment/mediawiki

Las anotaciones de cada despliegue aparecerán:

deployment.apps/mediawiki 
REVISION CHANGE-CAUSE
1 Primer despliegue. Desplegamos versión 1.31
2 Segundo despliegue. Actualizamos a la versión 1.34

Accedemos a la aplicación con un port-forward para verificar que se ha desplegado la versión 1.34.

Rollback del Deployment

El despliegue de una nueva versión de una aplicación es una labor crítica. Si estamos sirviendo una aplicación web utilizada por muchos usuarios, no podemos permitir cortes en el servicio por problemas en el despliegue de una nueva versión.

Si surge algún problema durante el despliegue, debemos tener un proceso que nos permita volver rápidamente a la versión anterior de la aplicación que funcionaba bien. Este proceso se llama rollback, o en Kubernetes, "deshacer" un rollout. Kubernetes ofrece un mecanismo sencillo para volver a versiones anteriores activando uno de los ReplicaSet antiguos.

Desplegamos una versión que da error (la versión 2 de la aplicación no existe):

kubectl set image deployment mediawiki contenedor-mediawiki=mediawiki:2

Anotamos el cambio:

kubectl annotate deployment/mediawiki kubernetes.io/change-cause="Tercer despliegue. Actualizamos a la versión 2"

Comprobamos el historial de despliegues:

kubectl rollout history deployment/mediawiki

Dependiendo de la estrategia de despliegue, esto puede provocar que la aplicación se quede en la versión anterior (RollingUpdate) o que no haya ningún Pod válido desplegado (Recreate). En cualquier caso, se puede volver a la versión anterior del despliegue mediante rollout:

kubectl rollout undo deployment/mediawiki
kubectl get all

Comprobamos el historial de actualizaciones:

kubectl rollout history deployment mediawiki

Las anotaciones de cada despliegue aparecerán:

deployment.apps/mediawiki
REVISION CHANGE-CAUSE
1 Primer despliegue. Desplegamos versión 1.31
3 Tercer despliegue. Actualizamos a la versión 2
4 Segundo despliegue. Actualizamos a la versión 1.34