Probes

Probes

Probe es una test que ejecuta kubelet cada cierto tiempo sobre un contenedor para comprobar su estado, en caso de no dar lo acordado ejecuta una acción configurada.

Las tres formas de ejecutar test que tiene kubelet son:

  • Mediante un comando, si retorna 0 todo correcto.
  • Por puerto, verifica que cierto puerto este abierto.
  • Desde HTTP, si la respuesta esta entre 200-399 todo correcto, si es superior a 400 error.

Tipos

Los tipos de pruebas que tiene kubelet para asegurar el funcionamiento de una aplicación son:

liveness Comprueba que esta funcionando el contenedor como debe cada x tiempo, si la prueba falla, liveness reinicia el contenedor.

readines hace un test cada x tiempo par ver que el contenedor funciona correctamente, si falla la prueba, readiness desregistra la ip del contenedor del endpoint para no recibir mas carga, hasta que el contenedor este en buen estado.

startup se utiliza para aplicaciones que tardan bastante en configurarse y arrancar. Mientras una aplicación está en modo startup, liveness y readiness permanecen desactivadas hasta que startup la da por buena.

Nota: readiness y liveness es bueno que trabajen juntos, ya que si se envía una petición a un pod mientras este se esta reiniciando, la petición fallara.

liveness

cmd

Ejemplo comando tipo liveness, en este yaml el contenedor ejecuta un comando de crear un archivo y borrarlo en 30 segundos para provocar un fallo.

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 10
      periodSeconds: 5

El livenessProbe una vez arrancado el contenedor espera 10 segundos, y ejecuta un comando cada 5 segundos para verificar que el archivo /tmp/healthyexiste, en caso contrario reinicia el contenedor.

➜ sudo kubectl get pods                  
NAME            READY   STATUS    RESTARTS   AGE
liveness-exec   1/1     Running   3          3m52s

➜ sudo kubectl describe pod liveness-exec
...
  Normal   Started    62s                kubelet, pc02      Started container liveness
  Warning  Unhealthy  20s (x3 over 30s)  kubelet, pc02      Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
  Normal   Killing    20s                kubelet, pc02      Container liveness failed liveness probe, will be restarted
tcp

Este es un ejemplo de probe en readness y liveness que comprueban que el puerto 8080 del contenedor este abierto.

apiVersion: v1
kind: Pod
metadata:
  name: goproxy
  labels:
    app: goproxy
spec:
  containers:
  - name: goproxy
    image: k8s.gcr.io/goproxy:0.1
    ports:
    - containerPort: 8080
    readinessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
    livenessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 20
http

En este ejemplo liveness hace una consulta a una ruta de un servidor web y según el estado de la respuesta lo da por bueno o no.

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/liveness
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3

Cualquier código mayor o igual a 200 y menor a 400 indica éxito. Cualquier otro código indica falla.

Durante los primeros 10 segundos que el contenedor está vivo, el controlador / healthz devuelve un estado de 200. Después de eso, el controlador devuelve un estado de 500.

http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
    duration := time.Now().Sub(started)
    if duration.Seconds() > 10 {
        w.WriteHeader(500)
        w.Write([]byte(fmt.Sprintf("error: %v", duration.Seconds())))
    } else {
        w.WriteHeader(200)
        w.Write([]byte("ok"))
    }
})
➜ sudo kubectl get pod liveness-http
NAME            READY   STATUS    RESTARTS   AGE
liveness-http   1/1     Running   1          28s

➜ sudo kubectl describe pod liveness-http        
...
Events:
  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Warning  Unhealthy  11s (x3 over 17s)  kubelet, pc02      Liveness probe failed: HTTP probe failed with statuscode: 500
  Normal   Killing    11s                kubelet, pc02      Container liveness failed liveness probe, will be restarted
  Normal   Pulled     10s (x2 over 29s)  kubelet, pc02      Successfully pulled image "k8s.gcr.io/liveness"
  Normal   Created    10s (x2 over 29s)  kubelet, pc02      Created container liveness
  Normal   Started    10s (x2 over 29s)  kubelet, pc02      Started container liveness