Nota de traducción.: El ingeniero jefe de la compañía Zalando, Henning Jacobs, ha notado repetidamente que los usuarios de Kubernetes enfrentan problemas para entender el propósito de los liveness (y readiness) probes y su correcta aplicación. Por ello, ha recopilado sus pensamientos en esta concisa nota, que con el tiempo se convertirá en parte de la documentación de K8s.

Las verificaciones de estado, conocidas en Kubernetes como liveness probes (es decir, literalmente, “pruebas de viabilidad” - nota del traductor), pueden ser bastante peligrosas. Recomiendo evitarlas siempre que sea posible; las únicas excepciones son aquellos casos en que realmente son necesarias y usted comprende completamente la especificidad y las consecuencias de su uso. En esta publicación se tratará sobre las verificaciones de liveness y readiness, así como se explicará cuándo debe y no debe aplicarlas.
Un colega mío, Sandor, compartió recientemente en Twitter los errores más comunes que encuentra, incluidos los relacionados con el uso de readiness/liveness probes:
Una livenessProbe mal configurada puede empeorar situaciones de alta carga (una caída en cascada + un posible inicio prolongado del contenedor/aplicación) y llevar a otras consecuencias negativas, como la caída de dependencias. (ver también sobre la limitación del número de solicitudes en la combinación K3s+ACME). Peor aún, cuando el liveness probe se combina con la verificación de la salud de la dependencia (health check), que es una base de datos externa: una única falla en la base de datos reiniciará todos sus contenedores.!
El mensaje general “No use liveness probes” en este caso ayuda poco, así que examinemos para qué se utilizan las verificaciones de readiness y liveness.
Nota: La mayor parte de la prueba a continuación fue inicialmente incluida en la documentación interna para desarrolladores de Zalando.
Verificaciones de Readiness y Liveness
Kubernetes ofrece dos mecanismos importantes, llamados . Estos realizan periódicamente alguna acción, como enviar una solicitud HTTP, abrir una conexión TCP o ejecutar un comando en el contenedor, para confirmar que la aplicación está funcionando correctamente.
Kubernetes utiliza readiness probes, para entender cuándo un contenedor está listo para recibir tráfico. Un pod se considera listo para funcionar si todos sus contenedores están listos. Una de las aplicaciones de este mecanismo es controlar qué pods se utilizan como backend para los servicios de Kubernetes (y especialmente para Ingress).
Sondeos de liveness ayudan a Kubernetes a entender cuándo es el momento de reiniciar un contenedor. Por ejemplo, esta verificación permite interceptar un bloqueo, cuando una aplicación 'se queda atascada' en un lugar. Reiniciar el contenedor en tal estado ayuda a mover la aplicación desde un punto muerto, a pesar de los errores, pero también puede llevar a fallos en cascada (ver más abajo).
Si intentas desplegar una actualización de la aplicación que falla en las verificaciones de liveness/readiness, su implementación se detendrá, ya que Kubernetes esperará el estado Listo de todos los pods.
Ejemplo
Aquí hay un ejemplo de un sondeo de readiness que verifica la ruta /health a través de HTTP con configuraciones por defecto (intervalo: 10 segundos, timeout: 1 segundo, umbral de éxito: 1, umbral de fallo: 3):
# часть общего описания deployment'а/стека
podTemplate:
spec:
containers:
- name: my-container
# ...
readinessProbe:
httpGet:
path: /health
port: 8080Recomendaciones
- Para microservicios con un endpoint HTTP (REST, etc.) siempre define un sondeo de readiness, que verifica si la aplicación (pod) está lista para recibir tráfico.
- Asegúrate de que el sondeo de readiness cubra la disponibilidad del puerto real del servidor web:
- usando puertos para necesidades administrativas, llamados 'admin' o 'management' (por ejemplo, 9090), para
readinessProbe, asegúrate de que el endpoint devuelva OK solo si el puerto HTTP principal (como el 8080) está listo para recibir tráfico*;* Conozco al menos un caso en Zalando donde esto no ocurrió, es decir,
readinessProbeverificó el puerto de 'management', pero el servidor no comenzó a funcionar debido a problemas con la carga de la caché. - colocar un sondeo de readiness en un puerto separado puede llevar a que la sobrecarga en el puerto principal no se refleje en la verificación de salud (es decir, la piscina de hilos en el servidor está llena, pero la verificación de salud sigue mostrando que todo está bien).
- usando puertos para necesidades administrativas, llamados 'admin' o 'management' (por ejemplo, 9090), para
- Asegúrate de que el sondeo de readiness incluya la inicialización/migración de la base de datos;
- la forma más sencilla de lograrlo es acceder al servidor HTTP solo después de que se haya completado la inicialización (por ejemplo, migración de base de datos con etc.); es decir, en lugar de cambiar el estado de la verificación de salud, simplemente no inicies el servidor web hasta que se complete la migración de la base de datos*.
* También se pueden ejecutar migraciones de BD desde contenedores init fuera del pod. Sigo siendo un fanático de las aplicaciones autónomas (self-contained), es decir, aquellas en las que el contenedor de la aplicación sabe cómo llevar la BD al estado deseado sin coordinación externa.
- la forma más sencilla de lograrlo es acceder al servidor HTTP solo después de que se haya completado la inicialización (por ejemplo, migración de base de datos con etc.); es decir, en lugar de cambiar el estado de la verificación de salud, simplemente no inicies el servidor web hasta que se complete la migración de la base de datos*.
- desde cualquier lugar del mundo. Es la solución ideal para crear una oficina en la nube, donde todos los programas y datos de los empleados están en un entorno seguro
httpGetpara las verificaciones de readiness a través de endpoints típicos de health checks (por ejemplo,/health). - Infórmese sobre los parámetros de las comprobaciones configurados por defecto (
interval: 10s,timeout: 1s,successThreshold: 1,failureThreshold: 3):- los parámetros por defecto significan que el pod estará not-ready aproximadamente después de 30 segundos (3 comprobaciones de salud fallidas).
- Utilice un puerto separado para «admin» o «management», si la pila tecnológica (por ejemplo, Java/Spring) lo permite, para separar la gestión de la «salud» y métricas del tráfico habitual:
- pero no olvide el punto 2.
- Si es necesario, la readiness probe se puede utilizar para calentar/cargar la caché y devolver un código de estado 503 mientras el contenedor no esté «calentado»:
- también recomiendo familiarizarse con la nueva verificación
startupProbe, (escribimos sobre ella en ruso) — nota del traductor).
- también recomiendo familiarizarse con la nueva verificación
Advertencias
- No confíe en las dependencias externas (como los almacenes de datos) al ejecutar pruebas de readiness/liveness, ya que esto puede llevar a fallos en cascada:
- tomemos como ejemplo un servicio stateful REST con 10 pods que dependen de una sola base de datos Postgres: cuando la verificación depende de una conexión activa a la BD, todos los 10 pods pueden caer si hay una latencia en la red/o en la BD, lo que normalmente termina peor de lo que podría haber sido;
- tenga en cuenta que Spring Data por defecto verifica la conexión con la BD*;
* Este es el comportamiento predeterminado de Spring Data Redis (al menos, lo era la última vez que lo comprobé), lo que llevó a una falla «catastrófica»: cuando Redis estuvo no disponible por un breve período, todos los pods «cayeron».
- «externo» en este sentido también puede significar otros pods de la misma aplicación, es decir, idealmente la verificación no debería depender del estado de otros pods del mismo clúster para evitar caídas en cascada:
- los resultados pueden variar para aplicaciones con estado distribuido (por ejemplo, almacenamiento en caché en memoria en los pods).
- No use liveness probe para los pods (excepciones son los casos en que realmente son necesarios y usted comprende completamente la especificidad y las consecuencias de su uso):
- el liveness probe puede ayudar a recuperar contenedores "atrapados", pero, dado que tiene el control total sobre su aplicación, tales cosas como procesos "atrapados" y deadlocks no deberían ocurrir idealmente: la mejor alternativa es causar la caída intencional de la aplicación y devolverla a un estado estable anterior;
- un liveness probe fallido llevará a un reinicio del contenedor, potencialmente agravando las consecuencias de errores relacionados con la carga: el reinicio del contenedor provocará inactividad (al menos, durante el tiempo de inicio de la aplicación, digamos, más de 30 segundos), causando nuevos errores, aumentando la carga en otros contenedores y aumentando la probabilidad de que fallen, etc.;
- las liveness checks combinadas con una dependencia externa son la peor de las combinaciones posibles, amenazando con fallos en cascada: ¡un pequeño retraso del lado de la base de datos llevará al reinicio de todos sus contenedores!
- Los parámetros de las liveness y readiness checks deben ser diferentes:
- se puede utilizar un liveness probe con la misma verificación de estado, pero con un umbral de activación más alto (
failureThreshold), por ejemplo, asignar el estado not-ready después de 3 intentos y considerar que el liveness probe ha fallado después de 10 intentos;
- se puede utilizar un liveness probe con la misma verificación de estado, pero con un umbral de activación más alto (
- No use verificaciones exec, ya que están asociadas con problemas conocidos que conducen a la aparición de procesos huérfanos:
- detalles: ver .
Currículum
- Utilice readiness probes para determinar cuándo el pod está listo para recibir tráfico.
- Utilice liveness probes solo cuando realmente sean necesarios.
- El uso incorrecto de readiness/liveness probes puede llevar a una disminución de la disponibilidad y fallos en cascada.
Material adicional sobre el tema
- ;
- ;
- (también habla sobre livenessProbe).
Actualización #1 del 2019-09-29
: se agregó una nota al pie.
sobre PDB: uno de los problemas de las liveness checks es la falta de coordinación entre los pods. En Kubernetes hay para limitar el número de fallos paralelos que una aplicación puede experimentar, pero las verificaciones no tienen en cuenta PDB. Idealmente, podemos ordenar a K8s: «Reinicia un pod si su verificación falla, pero no los reinicies todos para no empeorar la situación».
: «Utiliza sondas de liveness cuando sepas con certeza que lo mejor que se puede hacer es “matar” la aplicación» (una vez más, no hay que exagerar).
Actualización nº 2 del 2019-09-29
: creé una solicitud pertinente () para añadir documentación sobre las sondas de liveness.
P.D. del traductor
También puedes leer en nuestro blog:
- «»;
- «»;
- «».
Fuente: habr.com
