Kubernetes · sondas · reinicios

Liveness probe failed: por qué Kubernetes reinicia tu Pod que sí funciona

La columna RESTARTS sube sola, a veces termina en CrashLoopBackOff, y cuando entras al contenedor la aplicación responde bien. Casi nunca es la aplicación: es la sonda de vida, que la mata antes de tiempo o le pregunta lo que no debe.

Paso 1. Confirmar que el reinicio lo pidió la sonda

$ kubectl get pods -n <ns>
NAME                      READY   STATUS    RESTARTS      AGE
tienda-7c9f8d6b5d-x2kqp   1/1     Running   4 (40s ago)   6m
$ kubectl describe pod tienda-7c9f8d6b5d-x2kqp -n <ns> | grep -A3 "Last State"
$ kubectl get events -n <ns> --field-selector reason=Unhealthy

Si en Events aparece Liveness probe failed seguido de "failed liveness probe, will be restarted", el reinicio lo ordenó el kubelet por la sonda. Si en cambio Last State dice OOMKilled, el problema es de memoria y la sonda no tiene la culpa.

Paso 2. Leer el texto exacto del fallo

El final del mensaje dice cuál de las causas tienes:

Lo que dice el eventoCausa más probableCorrección
connection refused solo en los primeros segundosLa aplicación tarda en arrancar más de lo que la sonda esperaUna startupProbe que proteja el arranque (YAML corregido, abajo)
context deadline exceeded o Client.Timeout exceededLa respuesta tarda más de timeoutSeconds, que por defecto es 1 segundo; pasa con carga o con el límite de CPU muy bajoSube timeoutSeconds y revisa el límite de CPU del contenedor
connection refused siemprePuerto equivocado, o la aplicación escucha en 127.0.0.1Usa el puerto por nombre (port: http) y escucha en 0.0.0.0
HTTP probe failed with statuscode: 404La ruta de salud no existe; solo cuentan como éxito los códigos de 200 a 399Corrige path o crea la ruta
statuscode: 500 o 503 cuando falla la base de datosLa sonda de vida revisa dependencias externas, y una caída ajena reinicia todos tus Pods a la vezLa sonda de vida solo mira el proceso; las dependencias van en la readinessProbe

Paso 3. Medir antes de cambiar números

$ kubectl logs tienda-7c9f8d6b5d-x2kqp -n <ns> --previous | tail -20
$ kubectl get pod tienda-7c9f8d6b5d-x2kqp -n <ns> -o jsonpath='{.spec.containers[0].livenessProbe}'

--previous muestra los registros del contenedor que mataron, no del que acaba de nacer: ahí ves cuánto tardó en quedar listo. Con los valores por defecto (periodSeconds: 10, failureThreshold: 3, timeoutSeconds: 1), una aplicación que tarda más de unos 30 segundos en arrancar entra en un ciclo de reinicios sin fin.

El YAML corregido

containers:
  - name: tienda
    ports:
      - name: http
        containerPort: 8080
    startupProbe:            # protege el arranque: hasta 30 x 5 = 150 s
      httpGet: { path: /healthz, port: http }
      periodSeconds: 5
      failureThreshold: 30
    livenessProbe:           # empieza cuando la de arranque pasa
      httpGet: { path: /healthz, port: http }
      periodSeconds: 10
      timeoutSeconds: 3
      failureThreshold: 3
    readinessProbe:          # aquí sí van las dependencias
      httpGet: { path: /ready, port: http }
      periodSeconds: 5

Mientras la startupProbe no pase, Kubernetes no ejecuta la de vida ni la de disponibilidad. Así el arranque lento deja de contar como fallo, y la sonda de vida puede ser estricta el resto del tiempo.

¿Quieres verlo pasar sin romper nada tuyo? El laboratorio 03 del kit rompe una sonda a propósito, te muestra la versión vieja sirviendo mientras el rollout se congela, y en el reto final rompe la sonda de vida para comparar los dos síntomas.

Por qué pasa tanto

Porque la sonda de vida se copia de un tutorial con la misma ruta que la de disponibilidad, y las dos hacen cosas opuestas: la de disponibilidad saca al Pod del reparto, la de vida reinicia el contenedor. Reiniciar arregla un proceso colgado y no arregla una base de datos caída: por eso una sonda de vida que mira dependencias convierte un problema ajeno en una caída tuya.

Practica Kubernetes en tu propio clúster, gratis

Te envío al correo dos laboratorios completos con su solución: el 01 (namespace y deployment) y el 08 (ResourceQuota). Cada uno termina con un comando de verificación, no con "parece que funcionó". Las sondas y el rollout son el laboratorio 03 del kit.

Quiero los 2 laboratorios gratis