En esta guía, exploraremos en detalle qué es Goss, cómo se utiliza para validar y mantener el estado de salud de los servicios, y cómo puedes integrarlo fácilmente dentro de tus imágenes Docker. Para aquellos que buscan mejorar la calidad de sus desarrollos y despliegues, Goss se presenta como una solución confiable y eficiente.
¿Qué es Goss?
Goss es una herramienta de validación de servicios de infraestructura que se puede utilizar para verificar que un servicio de Docker está funcionando correctamente. Puede utilizar Goss para crear y ejecutar pruebas de integración en su servicio de Docker, lo que le permite asegurarse de que está configurado correctamente y está respondiendo como se espera. Goss es fácil de usar y se integra bien con Docker, lo que lo hace una excelente opción para validar servicios de Docker.
Usos de la herramienta Goss
Goss puede ser utilizado en Linux para validar una variedad de aspectos de la configuración y el comportamiento de los servicios. Algunos ejemplos de usos de Goss en Linux incluyen:
- Validación de configuraciones de red: Goss puede utilizarse para verificar que los servicios de red, como DNS y DHCP, están configurados correctamente y respondiendo a las solicitudes.
- Validación de configuraciones de seguridad: Goss puede utilizarse para verificar que las configuraciones de seguridad, como el firewall y el acceso SSH, están configuradas correctamente.
- Validación de configuraciones de sistema: Goss puede utilizarse para verificar que los servicios de sistema, como la configuración de la memoria y el espacio en disco, están configuradas correctamente.
- Validación de servicios de aplicaciones: Goss puede utilizarse para verificar que los servicios de aplicaciones, como un servidor web o una base de datos, están funcionando correctamente y respondiendo a las solicitudes.
- Validación de configuraciones de monitoreo: Goss puede utilizarse para verificar que los servicios de monitoreo, como Zabbix o Nagios, están configuradas correctamente y recolectando los datos correctos.
Es importante tener en cuenta que estas son solo algunas de las posibles utilizaciones de Goss en Linux, ya que su flexibilidad le permite adaptarse a una amplia variedad de entornos y situaciones.
Instalación y validar servicio: Cómo validar con Goss
Vamos a ver un ejemplo de cómo validar con Goss, para ello seguimos los siguientes pasos generales:
- Instalar Goss: para hacer uso de Goss, primero necesitarás instalarlo en tu sistema Linux. Puedes hacerlo descargando el paquete binario desde la página de descargas de Goss o utilizando un administrador de paquetes como apt o yum.
- Crear las pruebas: Goss utiliza un lenguaje de script YAML para especificar las pruebas a realizar. Crea un archivo YAML con las pruebas que deseas realizar en tu servicio.
- Ejecutar las pruebas: utiliza el comando goss run para ejecutar las pruebas especificadas en el archivo YAML.
- Revisar los resultados: Goss presenta los resultados de las pruebas en un formato estandarizado. Si alguna prueba falla, se informará del error y se detallará el problema.
Ejemplo:
# Instalar Goss curl -fsSL https://goss.rocks/install | sh # Crear un archivo de pruebas para verificar que el servicio web está funcionando correctamente echo "http: # Verificar que el servidor está respondiendo status: 200 # Verificar que el servidor está respondiendo con el contenido esperado body: /Welcome to my website/" > test.yaml # Ejecutar las pruebas goss --gossfile test.yaml validate
En este ejemplo, se verifica que el servicio web está funcionando correctamente, respondiendo con un código de estado 200 y un contenido específico. Si la prueba falla, se informará del error.
Cómo configurar Goss en una imagen docker
Es posible utilizar Goss para validar servicios dentro de un contenedor Docker mediante la adición de las instrucciones necesarias para ejecutarlo en el archivo Dockerfile. Al hacerlo, se ejecutará automáticamente cada vez que se construya o inicie el contenedor.
Cambios en nuestro compose
Lo primero que vamos a hacer es cambiar la forma con la que nuestro docker-compose lee la imagen docker.
Esta es la forma normal de agregar imágenes a un servicio en docker, donde se descarga de los repositorios oficiales de docker.
version: "3" services: odoo14: image: odoo:14.0 ... nginx: image: nginx ... postgres-odoo: image: postgres:12.8 ...
Lo cambiaremos para crear nuestra propia imagen para ello vamos a crear un archivo Dockerfile para cada servicio donde vamos a tener goss.
vagrant@master:~/odoo$ cat dockerfile/odoo14/Dockerfile FROM odoo:14.0
vagrant@master:~/odoo$ cat dockerfile/postgres-odoo/Dockerfile FROM postgres:12.8
vagrant@master:~/odoo$ cat dockerfile/nginx/Dockerfile FROM nginx
Con estos cambios construimos la imagen mediante el Dockerfile creado previamente, con esto conseguimos agregar más parámetros o mejoras.
Levantamos el docker-compose y ya tenemos los contenedores.
vagrant@master:~/odoo$ docker-compose ps Name Command State Ports -------------------------------------------------------------------------------------------------------------------------------- nginx /docker-entrypoint.sh ngin ... Up 0.0.0.0:443->443/tcp,:::443->443/tcp, 0.0.0.0:80->80/tcp,:::80->80/tcp odoo14 /entrypoint.sh odoo Up 0.0.0.0:8069->8069/tcp,:::8069->8069/tcp, 8071/tcp, 8072/tcp portainer-odoo /portainer Up 9000/tcp postgres-odoo docker-entrypoint.sh postgres Up 0.0.0.0:5432->5432/tcp,:::5432->5432/tcp
En la columna del estado vemos que está Up pero no sabemos si está Healthy o no, para ello vamos a configurar goss.
Agregamos goss
Para validar servicios, se deben crear archivos de prueba específicos para cada servicio que se desea validar. Estos archivos deben especificar los parámetros y comportamientos esperados del servicio, y Goss comparará estos parámetros con los valores reales del servicio para determinar si el servicio está funcionando correctamente.
¿Cómo lo vamos a configurar?
- Nginx revisará si tiene abierto su propio puerto y también que estén todos los servicios activos, de lo contrario no iniciará el servicio.
- Odoo comprueba si tiene activo su propio puerto y si responde la llamada a la web, luego va a revisar que tiene conexión con postgres y que puede acceder a la base de datos.
- Postgres revisará solo si tiene abierto su propio puerto.
Las comprobaciones a sí mismo las podemos poner sobre el archivo, goss.yaml. Mientras que las comprobaciones hacia otros servicio lo agregaremos al archivo goss-command.yaml (Este nombre es orientativo y se puede cambiar)
Archivos Goss de Odoo
Este archivo verifica que esté escuchando en el puerto 8069 y hará una llamada a sí mismo este tiene que responder con un código de estado 200 para su correcto funcionamiento.
$ cat dockerfile/odoo/goss/goss.yaml port: tcp:8069: listening: true http: http://localhost:8069/web/database/selector: status: 200 allow-insecure: false no-follow-redirects: false timeout: 5000 body: []
Para el archivo goss-command.yaml, vamos a realizar pruebas para comprobar el funcionamiento de postgres. En primer lugar, si este responde al servicio y después si puede iniciar sesión dentro de la base de datos, para esta opción tenemos que tener instalado el cliente del gestor en la máquina.
$ cat dockerfile/odoo/goss/goss-command.yaml addr: tcp://postgres-odoo:5432: reachable: true timeout: 500 command: PGPASSWORD=${MY_PASSWORD} psql -h postgres-odoo -U ${MY_USER} -d postgres: title: Ensure we have valid credentials exit-status: 0 timeout: 50000 # 5s
Archivos goss de postgres
Postgres solamente va a comprobar si está abierto el puerto 5432.
$ cat dockerfile/postgres/goss/goss.yaml port: tcp:5432: listening: true
Archivos goss de nginx
La primera comprobación que hará nginx será verificar si tiene abierto el puerto 443.
$ cat dockerfile/nginx/goss/goss.yaml port: tcp:443: listening: true
Utilizaremos nginx como servicio principal para comprobar todos los demás servicios, será el último en levantarse completamente ya que tiene que esperar a que los otros servicios hayan realizado sus comprobaciones.
Agregaremos las comprobaciones a los servicios y si algún servicio no funciona dicha comprobación podemos verificar su funcionamiento de otra forma, por ejemplo, el servicio de portainer hemos realizado una llamada a la web y si devuelve un código 200 significa que ha podido levantarse correctamente.
$ cat dockerfile/nginx/goss/goss-command.yaml addr: tcp://postgres-odoo:5432: reachable: true timeout: 500 tcp://odoo14:8069: reachable: true timeout: 500 http: http://portainer-odoo:9000: status: 200 allow-insecure: false no-follow-redirects: false timeout: 5000 body: []
Agregamos goss al dockerfile
Para utilizar Goss desde un Dockerfile, primero se debe añadir la instrucción para instalar en el sistema. Esto se puede hacer utilizando el comando de instalación proporcionado por el proyecto o utilizando una imagen de contenedor previamente construida con Goss ya instalado.
Una vez instalado Goss, se pueden añadir las instrucciones para copiar los archivos de prueba de Goss al contenedor y ejecutar Goss. Por ejemplo, se puede agregar una instrucción COPY para copiar los archivos de prueba desde el sistema de archivos del host al contenedor, y luego una instrucción CMD o ENTRYPOINT para ejecutar y realizar las pruebas.
Vamos a configurar los Dockerfiles de nuestra infraestructura.
Dockerfile de Odoo
FROM odoo:14.0 USER root RUN apt-get update RUN apt-get install curl -y ENV GOSS_VERSION v0.3.11 RUN curl -L https://github.com/aelsabbahy/goss/releases/download/$GOSS_VERSION/goss-linux-amd64 -o /usr/local/bin/goss && \ chmod +rx /usr/local/bin/goss && \ goss --version COPY goss/ /goss USER odoo CMD goss -g /goss/goss-command.yaml validate -r 5m && exec odoo HEALTHCHECK --interval=1s --timeout=6s CMD goss -g /goss/goss.yaml validate
Este ejemplo utiliza una imagen base de Odoo 14, instala Goss, copia el directorio, este tendrá los dos archivos creados previamente, al contenedor y ejecutalo para validar el servicio web.
Realizamos dos comprobaciones primero ejecutamos el archivo goss-command.yaml y tras su verificación inicia Odoo. Luego, realiza un Healthcheck cada segundo con la verificación del archivo goss.yaml.
Dockerfile de postgres
FROM postgres:12.8 USER root RUN apt update RUN apt install curl -y ENV GOSS_VERSION v0.3.11 RUN curl -L https://github.com/aelsabbahy/goss/releases/download/$GOSS_VERSION/goss-linux-amd64 -o /usr/local/bin/goss && \ chmod +rx /usr/local/bin/goss && \ goss --version COPY goss/ /goss HEALTHCHECK --interval=1s --timeout=6s CMD goss -g /goss/goss.yaml validate
Ejemplo similar, pero con la imagen base de postgres pero con sus respectivas comprobaciones.
Es importante mencionar que al ejecutar las pruebas desde dentro de un contenedor, las pruebas estarán validando la configuración y el comportamiento del servicio dentro del contexto del contenedor, en lugar de en el host.
Estado de los servicios
Un contenedor Docker puede tener tres estados de salud diferentes: “healthy”, “unhealthy” o “health: starting”.
- “Healthy” significa que el contenedor se está ejecutando correctamente y cumpliendo con todas las condiciones de salud especificadas.
- “Unhealthy” significa que el contenedor no está cumpliendo con alguna de las condiciones de salud especificadas. Esto puede deberse a un problema con el servicio que se está ejecutando dentro del contenedor o a un problema con el propio contenedor.
- “Health: starting” significa que el contenedor está iniciando y aún no se ha determinado su estado de salud. Puede ser porque el servicio todavía no ha terminado de iniciar o porque aún no se han ejecutado las pruebas de salud.
Levantamos los servicios
Una vez agregadas las instrucciones, se puede utilizar el comando “docker-compose up -d” para iniciar los contenedores y ejecutar las pruebas de Goss automáticamente.
Puedes usar el comando “docker-compose ps” para ver el estado de los contenedores en tu compose file. Si un contenedor está “healthy”, se mostrará junto a “Up”. Si un contenedor está fallando se mostrará como “unhealthy”.
$ docker-compose ps Name Command State Ports --------------------------------------------------------------------------------------------------------------------------------------- metabase /app/run_metabase.sh /bin/ ... Up (healthy) 3000/tcp netdata time bash starter.sh Up (healthy) 0.0.0.0:19999->19999/tcp,:::19999->19999/tcp nginx-odoo /docker-entrypoint.sh /bin ... Up (healthy) 0.0.0.0:443->443/tcp,:::443->443/tcp, 0.0.0.0:80->80/tcp,:::80->80/tcp odoo14 /entrypoint.sh /bin/bash - ... Up (healthy) 0.0.0.0:8069->8069/tcp,:::8069->8069/tcp, 8071/tcp, 8072/tcp portainer-odoo /portainer --admin-passwor ... Up 9000/tcp postgres-odoo docker-entrypoint.sh postgres Up (healthy) 0.0.0.0:5432->5432/tcp,:::5432->5432/tcp
¿Qué pasa si se cae un servicio?
Vamos a parar el servicio de la base de datos simulando que se ha caído la base de datos o directamente no se ha podido levantar por algún motivo.
Para detener un servicio específico en un archivo de compose, puedes usar el comando “docker-compose stop [nombre del servicio]“.
$ docker-compose stop postgres-odoo Stopping postgres-odoo ... done
Una vez que hayas detenido el servicio, puedes verificar de nuevo el estado con docker-compose ps, donde podemos ver que los servicios que tenemos comprobando postgres están unhealthy o intentando iniciar.
devops@chakray:~/gitlab-chakray/chdo/chdo-odoo-platform/odoo14-compose$ docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------------------------------------------------------------------ metabase /app/run_metabase.sh /bin/ ... Up (healthy) 3000/tcp netdata time bash starter.sh Up (health: starting) 0.0.0.0:19999->19999/tcp,:::19999->19999/tcp nginx-odoo /docker-entrypoint.sh /bin ... Up (unhealthy) 0.0.0.0:443->443/tcp,:::443->443/tcp, 0.0.0.0:80->80/tcp,:::80->80/tcp odoo14 /entrypoint.sh /bin/bash - ... Up (health: starting) 0.0.0.0:8069->8069/tcp,:::8069->8069/tcp, 8071/tcp, 8072/tcp portainer-odoo /portainer --admin-passwor ... Up 9000/tcp postgres-odoo docker-entrypoint.sh postgres Exit 0
Si quieres verificar el estado de salud de los contenedores en tiempo real, puedes usar el comando “docker-compose logs -f” para ver los registros de los contenedores mientras están ejecutándose.
nginx-odoo | Attempt #177: nginx-odoo | ...F nginx-odoo | nginx-odoo | Failures/Skipped: nginx-odoo | nginx-odoo | Addr: tcp://postgres-odoo:5432: reachable: nginx-odoo | Expected nginx-odoo | <bool>: false nginx-odoo | to equal nginx-odoo | <bool>: true nginx-odoo | nginx-odoo | Total Duration: 0.010s nginx-odoo | Count: 4, Failed: 1, Skipped: 0 nginx-odoo | Retrying in 1s (elapsed/timeout time: 177.516s/5m0s)
“Count” es el número total de pruebas que se ejecutan. “Failed” es el número de pruebas que fallaron y “Skipped” es el número de pruebas que se saltaron en la ejecución.
Por ejemplo, si el resultado de ejecutar es “Count: 4, Failed: 1, Skipped: 0”, significa que se ejecutaron 4 pruebas en total, una de ellas falló y no se saltó ninguna.
En caso de que haya alguna prueba fallida, te mostrará detalles sobre qué pruebas fallaron y por qué. Puedes usar esta información para corregir los problemas y volver a ejecutar las pruebas fallidas.
El servicio vuelve a funcionar
Una vez que hayas solucionado los problemas que causaron que el servicio cayera y lo iniciamos nuevamente y volvemos a verificar si el contenedor está en un estado saludable.
devops@chakray:~/gitlab-chakray/chdo/chdo-odoo-platform/odoo14-compose$ docker-compose up -d netdata is up-to-date portainer-odoo is up-to-date Starting postgres-odoo ... done metabase is up-to-date odoo14 is up-to-date nginx-odoo is up-to-date
Vemos que ya ha conectado y nos hemos asegurado de que el resultado sea “Count: [x], Failed: 0, Skipped: 0”, lo que indica que todas las pruebas han pasado exitosamente y no hay errores.
nginx-odoo | Attempt #272: nginx-odoo | ...F nginx-odoo | nginx-odoo | Failures/Skipped: nginx-odoo | nginx-odoo | Addr: tcp://postgres-odoo:5432: reachable:
nginx-odoo | Expected nginx-odoo | <bool>: false nginx-odoo | to equal nginx-odoo | <bool>: true nginx-odoo | nginx-odoo | Total Duration: 0.005s nginx-odoo | Count: 4, Failed: 1, Skipped: 0 nginx-odoo | Retrying in 1s (elapsed/timeout time: 273.438s/5m0s) nginx-odoo | nginx-odoo | nginx-odoo | Attempt #273: nginx-odoo | .... nginx-odoo | nginx-odoo | Total Duration: 0.004s nginx-odoo | Count: 4, Failed: 0, Skipped: 0
Si todavía tienes problemas con el contenedor, puedes revisar de nuevo los registros del contenedor con el comando “docker-compose logs [nombre del servicio]” para obtener más información sobre el problema.
Mapear goss
¿Por qué mapear un archivo?
Mapear un archivo goss.yaml en un contenedor de Docker tiene varias ventajas:
- Mejora la flexibilidad: Al mapear un archivo goss.yaml en un contenedor, puedes personalizar la configuración para adaptarse a tus necesidades específicas, en lugar de estar limitado por la configuración predeterminada del Dockerfile.
- Permite la reutilización de la configuración: Al mapear un archivo goss.yaml en un contenedor, puedes reutilizar la misma configuración en varios contenedores o entornos diferentes, en lugar de tener que crear una configuración diferente para cada contenedor o entorno.
- Facilita la actualización de la configuración: Al tener la configuración fuera del contenedor, puedes actualizarla fácilmente sin tener que reconstruir la imagen del contenedor.
En resumen, mapear un archivo goss.yaml en un contenedor de Docker te permite tener un mayor control sobre la configuración , mejorar la flexibilidad y facilitar el desarrollo y la actualización.
Mapeando un archivo de configuración Goss
Puedes mapear un archivo de configuración en un contenedor de Docker al momento de construir la imagen o al momento de ejecutar el contenedor.
Para ello creamos el archivo con el mismo nombre en un directorio. En este archivo agregamos las comprobaciones que necesitemos.
$ cat configs/odoo14/goss-command.yaml addr: tcp://postgres-odoo:5432: reachable: true timeout: 500 command: PGPASSWORD=${MY_PASSWORD} psql -h postgres-odoo -U ${MY_USER} -d postgres: title: Ensure we have valid credentials exit-status: 0 timeout: 50000 # 5s
Al mapear un archivo goss.yaml en un contenedor de Docker, se sobrescribirá cualquier configuración especificada en el archivo Dockerfile original de la imagen. Esto se debe a que el archivo goss.yaml mapeado se vincula con el contenedor en tiempo de ejecución, y tiene prioridad sobre cualquier configuración especificada en el archivo Dockerfile.
Es importante tener en cuenta que esto solo se aplica a la configuración. Si hay algún cambio en el contenedor que no se refiera a Goss, como una dependencia de software, cambios en el sistema de archivos, etc, estos no serán afectados por el archivo goss mapeado.
Configuración del docker-compose.yml
Para mapear un archivo goss.yaml en un contenedor de Docker cuando se utiliza Docker Compose, debes especificar la ruta del archivo goss.yaml en tu sistema de archivos local en el archivo compose y la ruta dentro del contenedor donde se desea colocar el archivo goss.yaml.
Por ejemplo, si tu archivo goss.yaml se encuentra en la ruta “./configs/odoo14/goss-command.yaml” y deseas mapearlo en el contenedor en la ruta “/goss/goss-command.yaml”, en tu archivo compose podrías agregar la siguiente línea en el servicio correspondiente:
volumes: - ./configs/odoo14/goss-command.yaml:/goss/goss-command.yaml
Una vez hecho esto, al ejecutar el comando “docker-compose up -d” se creará un enlace entre el archivo goss.yaml en tu sistema de archivos local y el contenedor, permitiendo a Goss acceder a la configuración especificada en ese archivo.
Conclusión
En resumen, Goss es una herramienta de validación de sistemas que se puede utilizar para verificar si los contenedores de Docker están en un estado saludable. Es una herramienta muy útil para automatizar las pruebas y asegurar que los contenedores cumplen con tus requisitos de configuración.
Puedes utilizar Goss junto con Docker Compose para verificar el estado de salud de tus contenedores, y mapear un archivo goss.yaml en un contenedor de Docker para tener un mayor control sobre la configuración, mejorar la flexibilidad y facilitar el desarrollo y la actualización.
Si necesitas más información sobre cómo utilizar esta herramienta, podemos proporcionarte recursos y asistencia para ayudarte a implementarlo en su proyecto de manera efectiva. Estamos dispuestos a brindarte toda la ayuda necesaria para asegurar que su uso sea un éxito. Si quieres más información contacta con nosotros.