Dominando Docker: Definición de health checks en docker compose

JJOC007
7 min readDec 29, 2023

En este artículo, veremos un aspecto importante de Docker Compose, explorando específicamente los health checks, una herramienta esencial para garantizar la fiabilidad y robustez de los servicios en contenedores. Abordaremos desde los fundamentos de qué son y por qué son importantes, hasta cómo implementarlos prácticamente en tus definiciones de Docker Compose.

Contexto sobre Docker y Docker Compose

En el mundo dinámico de la tecnología de la información, la virtualización y la contenerización han revolucionado la manera en que desplegamos y administramos las aplicaciones. Docker emerge como una solución líder, permitiendo a los desarrolladores y administradores de sistemas empaquetar, distribuir y administrar aplicaciones de manera eficiente. Docker encapsula aplicaciones en contenedores, entornos ligeros y portátiles que aseguran consistencia a través de diferentes entornos de desarrollo, prueba y producción.

Docker Compose, una herramienta en el ecosistema de Docker, simplifica el proceso de definir y compartir aplicaciones multi-contenedor. Con Docker Compose, puedes definir todos los servicios que componen tu aplicación en un único archivo docker-compose.yml. Esta herramienta facilita la orquestación de múltiples contenedores, permitiendo que trabajen juntos de manera armónica para formar aplicaciones complejas.

Conceptos Básicos

¿Qué son los Health Checks?

En el contexto de la contenerización y Docker, los health checks son pruebas o verificaciones periódicas utilizadas para determinar si un contenedor está funcionando correctamente. En esencia, un health check es una manera de monitorizar automáticamente el estado de salud de un servicio o aplicación dentro de un contenedor. Si un servicio falla o deja de responder, el health check puede detectarlo y tomar acciones apropiadas, como reiniciar el contenedor o alertar al equipo de operaciones.

Los health checks son esenciales en entornos de producción y desarrollo porque garantizan que las aplicaciones continúen funcionando de manera óptima y fiable. En un entorno con múltiples servicios y contenedores, los health checks proporcionan una capa adicional de seguridad al asegurar que cada servicio individual está funcionando como se espera.

Cómo funcionan en Docker

Docker incorpora un sistema de health checks que permite a los usuarios definir comandos o instrucciones para verificar el estado de un contenedor. Estos comandos pueden ser tan simples como una solicitud HTTP a un endpoint de la aplicación o un script que verifica la disponibilidad de un servicio interno.

Cuando un health check falla, Docker marca el contenedor como unhealthy. Esta información puede ser utilizada por herramientas de orquestación y monitoreo para tomar decisiones automatizadas, como el reinicio del contenedor o la redistribución de carga entre contenedores saludables.

Los health checks de Docker ofrecen flexibilidad en términos de configuración, permitiendo a los usuarios definir intervalos de tiempo entre chequeos, el número de intentos antes de considerar un servicio como no saludable y el tiempo máximo que un chequeo debe tomar antes de considerarse fallido.

Esta funcionalidad es crucial para mantener la alta disponibilidad y la fiabilidad de las aplicaciones, especialmente en entornos de microservicios donde múltiples servicios interdependientes deben funcionar de manera sincronizada.

En la siguiente sección, nos adentraremos en cómo los health checks se integran y se configuran en Docker Compose, proporcionando ejemplos prácticos para su implementación.

Health Checks en Docker Compose

Integración con Docker Compose

Docker Compose, una herramienta para definir y ejecutar aplicaciones Docker multi-contenedor, integra el concepto de health checks de manera nativa en sus configuraciones. A través de archivos docker-compose.yml, Docker Compose permite a los desarrolladores y administradores de sistemas especificar cómo se debe realizar el health check de cada servicio en su entorno.

La integración de health checks en Docker Compose es crucial para automatizar el monitoreo y la gestión de la salud de los servicios. En entornos complejos con múltiples contenedores, los health checks se convierten en una herramienta vital para asegurar que cada servicio está operando correctamente y para facilitar la recuperación automática en caso de fallos.

Parámetros de Configuración

En un archivo docker-compose.yml, la configuración de un health check se realiza dentro de la definición de cada servicio. Los parámetros clave incluyen:

  • test: El comando que se ejecutará para verificar el estado del servicio. Puede ser una cadena o una lista. Por ejemplo, [“CMD”, “curl”, “-f”, “http://localhost/health"] para una aplicación web.
  • interval: El tiempo entre cada chequeo. Por ejemplo, 30s indica que el health check se ejecuta cada 30 segundos.
  • timeout: El tiempo máximo que un health check puede tomar antes de ser considerado como fallido. Por ejemplo, 10s.
  • retries: El número de veces que se intentará un health check fallido antes de marcar el servicio como unhealthy.
  • start_period: Un período inicial durante el cual los resultados de los health checks fallidos no se cuentan hacia el número máximo de reintentos. Esto es útil para aplicaciones que requieren tiempo para iniciarse.

Estos parámetros permiten una configuración detallada y ajustada a las necesidades específicas de cada servicio, brindando un control preciso sobre cómo y cuándo se debe considerar que un servicio no está saludable.

Ejemplo:

  service1:
build: ./web-server
environment:
- PORT=3000
ports:
- "3000:3000"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/ping"]
interval: 2s
timeout: 60s
retries: 20

Este ejemplo de Docker Compose ilustra la configuración de un health check para un servicio denominado service1, que representa un servidor web. La definición del health check se realiza en el archivo docker-compose.yml y está compuesta por varios componentes clave:

Test del Health Check (test):

[“CMD”, “curl”, “-f”, “http://localhost:3004/ping"]: Esta línea define el comando que se ejecutará para el health check. Utiliza curl para hacer una solicitud HTTP GET a la ruta /ping en el puerto 3004 del localhost. La opción -f hace que curl falle si el HTTP status code es 400 o superior, lo que es útil para detectar errores. Este comando verifica si el servicio web está respondiendo correctamente.

Intervalo (interval):

2s: Esto especifica que el health check se ejecutará cada 2 segundos. Es decir, cada 2 segundos, Docker Compose ejecutará el comando de curl para verificar el estado del servicio.

Timeout (timeout):

60s: Este es el tiempo máximo que Docker esperará a que el comando del health check se complete. Si el comando curl no responde dentro de 60 segundos, se considerará un fallo del health check.

Reintentos (retries):

20: Indica el número de veces que Docker re intentará el health check antes de marcar el servicio como unhealthy. En este caso, si el health check falla 20 veces consecutivas, Docker considerará que el servicio service1 no es saludable.

Ejemplo de servicio dependiente de otro:

service2:
build: ./web-server
environment:
- PORT=3001
ports:
- "3001:3001"
depends_on:
service1:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3001/ping"]
interval: 2s
timeout: 60s
retries: 20

En este ejemplo de Docker Compose, tenemos dos servicios: service1 y service2. Ambos están configurados con health checks, pero lo interesante aquí es la dependencia de service2 respecto al estado de salud de service1, indicado por la cláusula depends_on.

Dependencia Basada en Health Check (depends_on):

  • service2 utiliza la opción depends_on para establecer una dependencia en service1.
  • condition: service_healthy: Esta línea especifica que service2 solo debe iniciarse después de que service1 haya sido considerado “healthy” por Docker.

Funcionamiento del Health Check de service1 en relación con service2:

  1. Inicio de service1: Cuando se inicia el conjunto de servicios con Docker Compose, service1 comienza su proceso de inicialización.
  2. Ejecución del Health Check de service1: Mientras service1 se está ejecutando, Docker realiza health checks en intervalos de 2 segundos (según su configuración). Si el servicio responde exitosamente al comando de health check (en este caso, un curl a http://localhost:3000/ping), continua operando normalmente. Si falla, Docker intentará el health check hasta 20 veces, con un timeout de 60 segundos por intento.
  3. Estado de Salud de service1 y Efecto en service2: Si service1 pasa el health check y es marcado como saludable (healthy), entonces Docker procede a iniciar service2. Si service1 falla en sus health checks y es marcado como no saludable (unhealthy), service2 no se iniciará hasta que service1 sea considerado saludable.

Ejemplo de levantamiento cuando Service 1 es healthy:

Ejemplo de levantamiento cuando service 1 es unhealthy:

Este modelo de dependencia basado en la salud es crucial en entornos donde los servicios necesitan interactuar entre sí y donde la disponibilidad de un servicio depende del estado de otro. Asegura que service2 no intentará operar hasta que service1, del cual depende, esté completamente funcional y listo para manejar solicitudes o interactuar con otros servicios. Esto mejora la estabilidad y la confiabilidad del despliegue total de la aplicación.

En este repositorio veras el ejemplo listo para ejecutar, no dudes en descargarlo y probarlo

Referencias:

Si te ha gustado este artículo no dudes en darle 👏 y ⭐ al repositorio.

🤔 ¡Sígueme en las redes sociales! ⏬

Gracias!

--

--