Deployment

Deployment

https://kubernetes.io/docs/concepts/workloads/controllers/deployment/

Deployment es el objeto encargado de gestionar las actualizaciones de versiones de los pods y replicasets, por lo tanto es un objeto superior de replicaset y pod, los engloba. Es decir un deployment tiene en su interior un replicaset que este en su interior tiene un pod.

Como gestiona las actualizaciones

Deployment tiene el replicaset versión 1 en su interior, cuando tu le añades una actualización, deployment crea un nuevo replicaset versión 2 y va encendiendo pods del replicaset versión 2 y apagando los de la versión 1, para así asegurar una transición sin interrupciones. Además se guarda por defecto hasta 10 versiones por si quieres hacer un rollback ( ir a una versión anterior por si a habido problemas).

Gestion de manifiesto

Ejemplo manifiesto

En el siguiente manifiesto se especifica, crear un deployment que contenga un replicaset que creara tres replicas de una pod con un container nginx.

Ejemplo deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    kubernetes.io/change-cause: "version inicial nginx"
  name: deployment-test
  labels:
    app: front-nginx
spec:
#   revisionHistoryLimit: 3
  replicas: 3
  selector:
    matchLabels:
      app: front-nginx
  template:
    metadata:
      labels:
        app: front-nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80

Desplegar deployment

sudo kubectl apply -f dep.yaml 
deployment.apps/deployment-test created

sudo kubectl get deployment --show-labels
NAME              READY   UP-TO-DATE   AVAILABLE   AGE   LABELS
deployment-test   3/3     3            3           40s   app=front-nginx

sudo kubectl rollout status deployment deployment-test
deployment "deployment-test" successfully rolled out

Comprobar que ha creado

Efectivamente a creado un resource con tres pods

sudo kubectl get rs
NAME                         DESIRED   CURRENT   READY   AGE
deployment-test-694b78cb4c   3         3         3       6m32s

sudo kubectl get pods
NAME                               READY   STATUS    RESTARTS   AGE
deployment-test-694b78cb4c-mcm27   1/1     Running   0          6m51s
deployment-test-694b78cb4c-r62tx   1/1     Running   0          6m51s
deployment-test-694b78cb4c-w8t2p   1/1     Running   0          6m51s

Actualizar

Actualmente los pods están con la imagen nginx:alpine y voy a cambiar el manifiesto para hacer una actualización con la imagen nginx:latest y así ver como se comporta.

sudo kubectl get pods deployment-test-694b78cb4c-mcm27 -o yaml | grep 'image:'         
  - image: nginx:alpine
    image: nginx:alpine

hago el cambio en el manifiesto, lo despliego y veo el resultado.

sudo kubectl apply -f dep.yaml 
deployment.apps/deployment-test configured

sudo kubectl get pods deployment-test-78895f88b7-2z525 -o yaml | grep 'image:'
  - image: nginx:latest
    image: nginx:latest

Se puede ver que a echo exactamente con describe , se que crea un nuevo replicaset y va encendiendo pods a la vez que los apaga en el antiguo.

sudo kubectl describe deployment deployment-test
Events:
  Type    Reason             Age                    From                   Message
  ----    ------             ----                   ----                   -------
  Normal  ScalingReplicaSet  31m                    deployment-controller  Scaled up replica set deployment-test-694b78cb4c to 3
  Normal  ScalingReplicaSet  10m                    deployment-controller  Scaled up replica set deployment-test-78895f88b7 to 1
  Normal  ScalingReplicaSet  10m                    deployment-controller  Scaled down replica set deployment-test-694b78cb4c to 2
  Normal  ScalingReplicaSet  10m                    deployment-controller  Scaled up replica set deployment-test-78895f88b7 to 2
  Normal  ScalingReplicaSet  10m                    deployment-controller  Scaled down replica set deployment-test-694b78cb4c to 1
  Normal  ScalingReplicaSet  10m                    deployment-controller  Scaled up replica set deployment-test-78895f88b7 to 3
  Normal  ScalingReplicaSet  10m                    deployment-controller  Scaled down replica set deployment-test-694b78cb4c to 0

Ahora ahí dos replicasets, el nuevo y el antiguo se guarda por si quiero volver a una versión anterior a la actual.

sudo kubectl get rs                             
NAME                         DESIRED   CURRENT   READY   AGE
deployment-test-694b78cb4c   3         3         3       35m
deployment-test-78895f88b7   0         0         0       15m

sudo kubectl rollout history deployment deployment-test
deployment.apps/deployment-test 
REVISION  CHANGE-CAUSE
2         <none>
3         <none>
History

El historial de versiones por defecto no añade ninguna anotación y en el caso de tener diferentes versiones, es difícil saber cual es cual. para solucionar esto existen diferentes maneras de añadir un comentario.

  • --record al lanzar la actualización, se añade la misma linea del comando.
  • con metadata annotations en el archivo yaml ( es la mas practica )
  • Manualmente desde linea de commando ( muy engorrosa )

Este es un ejemplo por defecto:

sudo kubectl rollout history deployment deployment-test
deployment.apps/deployment-test 
REVISION  CHANGE-CAUSE
1         <none>
Metadata

Esta es la manera más agradable de insertar los comentarios del historial, desde la metadata del archivo yaml en la sección deploymet.

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    kubernetes.io/change-cause: "cambio puerto a 110"
  name: deployment-test
  labels:
    app: front-nginx
[ texto recortado ]    

Al desplegar se ve de la siguiente manera.

sudo kubectl apply -f deployment/dep.yaml              
deployment.apps/deployment-test configured

sudo kubectl rollout history deployment deployment-test
deployment.apps/deployment-test 
REVISION  CHANGE-CAUSE
1         <none>
2         cambio puerto a 110
Cambio manual

El cambio manual de anotación de versión es muy engorroso, pero útil si te has olvidado cambiarlo anteriormente o era erróneo.

sudo kubectl annotate deployment.v1.apps/deployment-test kubernetes.io/change-cause="cambio manual de anotacion"

sudo kubectl rollout history deployment deployment-test
deployment.apps/deployment-test 
REVISION  CHANGE-CAUSE
1         <none>
2         cambio manual de anotacion
Record

El modo record, no es del todo útil ya que no de una descripción como tal.

sudo kubectl apply -f deployment/dep.yaml --record              
deployment.apps/deployment-test configured

sudo kubectl rollout history deployment deployment-test
deployment.apps/deployment-test 
REVISION  CHANGE-CAUSE
1         <none>
2         cambio puerto a 110
3         kubectl apply -f deployment/dep.yaml --record=True
Roll-back

Roll-back permite regresar a una versión anterior con la siguiente sintaxis: kubectl rollout undo deployment deployment-test --to-revision=2 . Esto es muy útil si al desplegar una nueva versión a habido algún tipo de error y se quiere volver a una versión estable.

En el siguiente ejemplo muestro como añado una versión con una imagen inexistente, dará errores y volveré a la anterior estable.

# lanzo nueva versión
sudo kubectl apply -f deployment/dep.yaml 
deployment.apps/deployment-test configured

# veo como se añade la nueva versión
sudo kubectl rollout history deployment deployment-test             
deployment.apps/deployment-test 
REVISION  CHANGE-CAUSE
1         <none>
2         cambio manual de anotacion
3         cambio version imagen fake

# al ver el estado del proceso de cambio, veo que no avanza
sudo kubectl rollout status deployment deployment-test
Waiting for deployment "deployment-test" rollout to finish: 1 out of 3 new replicas have been updated...

# y veo que no puede hacer la transicion de pods, porque no puede descargar la imagen
sudo kubectl get pods                                               
NAME                               READY   STATUS             RESTARTS   AGE
deployment-test-64bcc5dd9c-4b9rk   1/1     Running            0          21m
deployment-test-64bcc5dd9c-bkp5v   1/1     Running            0          21m
deployment-test-64bcc5dd9c-rlc6l   1/1     Running            0          21m
deployment-test-7b799b8bcf-gw9nl   0/1     ImagePullBackOff   0          3m49s

# vuelvo a la versión 2 que era estable
sudo kubectl rollout undo deployment deployment-test --to-revision=2
deployment.apps/deployment-test rolled back

# parece haber ido bien
sudo kubectl rollout status deployment deployment-test 
deployment "deployment-test" successfully rolled out

# los pods vuleven a estar correctos
sudo kubectl get pods                                               
NAME                               READY   STATUS    RESTARTS   AGE
deployment-test-64bcc5dd9c-4b9rk   1/1     Running   0          24m
deployment-test-64bcc5dd9c-bkp5v   1/1     Running   0          24m
deployment-test-64bcc5dd9c-rlc6l   1/1     Running   0          24m

# compruevo que su versión de imagen es la correcta
sudo kubectl describe pod deployment-test-64bcc5dd9c-bkp5v | grep -i image:
    Image:          nginx:alpine