Tus contenedores docker al día con Watchtower

Permitidme que hoy os hable de Watchtower, una herramienta que nos promete tener al día nuestros contenedores o microservicios en Docker. A estas alturas de la película seguro que ya sabes de que se trata esto de los contenedores, si no sabes de lo que te hablo, puedes consultar las entradas que escribí al respecto en Colaboratorio.net

Implementar los microservicios con Docker es realmente fácil. Utilizando pocos recursos de los sistemas nos puede ofrecer gran cantidad de servicios. Aunque, todo sea dicho, a medida que va creciendo la infraestructura, mantener todo el software actualizado y al día, puede ser un “auténtico cristo”. El uso progresivo de los microservicios y con la consecuente necesidad de aprovisionar nuevos sistemas, tenemos como resultado un galimatías en muchos casos difícil de gestionar. Sin duda, puede ser mucho más crítico no tener actualizado, con los últimos parches de seguridad un entorno, que una posible indisponibilidad de este.

Logo oficial del proyecto

Por lo que, dicho esto, ya sea si solo utilizamos el núcleo principal de Docker, utilicemos Docker Compose, o cualquier herramienta complementaria, seguro que necesitamos una solución que nos ayude a gestionar las actualizaciones del software, para que siempre estén al día. Es justo ahí donde entra al campo de juego Watchtower.

Trabajar con Watchtower

Para poder disponer de nuestra magnífica atalaya, ergo nuestro Watchtower, simplemente debemos lanzarla, similar a lo que haríamos con otro contenedor:

docker run \
‑d ‑‑name watchtower \
‑v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower

Con el resultado:

Desplegamos la imagen del contenedor sin mayor problema

Lo que hacemos aquí es enviar el contenedor iniciado a un segundo plano -d. El nombre escogido es el que nosotros queramos --name y utilizamos el parámetro -v para incluir un volumen de datos en el sistema de ficheros. El comando incluye el propio conector al daemon de docker. Y ya por último, utilizamos la imagen del contenedor ubicada en Docker Hub.

Una vez lanzado Watchtower toma el control y monitorea la disponibilidad de nuevas versiones de imágenes para todos los contenedores en ejecución. Si existe una nueva versión disponible, la descarga y reinicia los contenedores afectados. Los parámetros de todos los contenedores (los que indicamos al iniciarlos la primera vez) se tienen en cuenta y se pasan al reiniciar, de una forma bastante elegante. De esta forma, los volúmenes montados y los puertos compartidos persisten a pesar de la actualización.

Además, la herramienta se encarga de las etiquetas que se adjuntan a las imágenes. La etiqueta más conocida es probablemente la más reciente, lo que permite al creador de una imagen publicar el hecho de que la imagen sea la última versión disponible. Esto hace que se pueda iniciar un contenedor con una versión que quizás no es la que deseamos. Como administrador podemos indicar la versión deseada para cada caso y la estrategia de actualización para Watchtower.

Actualización selectiva

Una de las partes más importantes a la hora de crear los contenedores, es la capacidad de actualización y migración de la aplicación que contenga. Dependiendo del punto de entrada, indicado con el comando RUN en el Dockerfile correspondiente. Lo más probable, si están bien construidos, es que la mayoría de las imágenes más populares tengan esa capacidad.

Lo más seguro es que deseemos únicamente actualizar de forma automática ciertos contenedores. Docker nos permite pasar ciertos argumentos adicionales al lanzar un contenedor con docker run. Watchtower utiliza esta capacidad para pasar los nombres de los contenedores y así definir que contenedores deben actualizarse.

Por ejemplo:

docker run \
‑d ‑‑name watchtower \
‑v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower nextcloud \
mariadb redis wordpress

De hecho, una vez lanzado podemos comprobar que efectivamente los ha «cazado» consultando con docker logs, tal y como se en la siguiente imagen:

Consultamos los registros del contenedor

También podemos indicar que se utilice esta herramienta para actualizar en el caso de lanzar nuevos contenedores, utilizando el parámetro ‑e WATCHTOWER_LABEL_ENABLE=1, cuando utilicemos docker run. Podemos indicar los nombres de los contenedores que queramos.

Programación y ejecuciones de pruebas

Si deseamos administrar los tiempos en que Watchtower verifica los contenedores, podemos utilizar la variable de entorno WATCHTOWER_SCHEDULE, indicando en la cadena la sintaxis extendida de Cron del lenguaje de programación Go. Por ejemplo podemos indicar que funcione cada cinco horas:

‑e WATCHTOWER_SCHEDULE="0 0 */5 * * *"

Este parámetro lo añadimos al lanzar docker run.

Indicamos cada cuanto se ejecuta la actualización

También podemos hacer que Watchtower nos avise únicamente de que contenedores tienen disponible una actualización. Soporta los envíos de diferentes formas, vía correo o herramientas populares como Slack o Microsoft Teams. Para habilitar la notificación por correo electrónico, primero debemos proteger el contenedor correspondiente contra las actualizaciones automáticas, añadiendo esta etiqueta al crear el contenedor:

‑l com.centurylinklabs.watchtower. \  
monitor‑only="true"

De esta manera podemos configurar posteriormente el envío por correo. Y así nos llegará un correo indicando que el «contenedor mengano» tiene una actualización disponible. Podemos añadir unas cuantas variables y etiquetas, entre las que se puede encontrar una que indica una parte de enlace a un correo electrónico.

Aquí tenéis un ejemplo de configuración, extraída de la documentación del proyecto:

docker run -d \
  --name watchtower \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e WATCHTOWER_NOTIFICATIONS=email \
  -e WATCHTOWER_NOTIFICATION_EMAIL_FROM=fromaddress@gmail.com \
  -e WATCHTOWER_NOTIFICATION_EMAIL_TO=toaddress@gmail.com \
  -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER=smtp.gmail.com \
  -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=587 \
  -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=fromaddress@gmail.com \
  -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=app_password \
  -e WATCHTOWER_NOTIFICATION_EMAIL_DELAY=2 \
  containrrr/watchtower

Recuperando espacio

Otra opción muy interesante es indicar que cuando actualice un contenedor elimine las imágenes antiguas y que ya no se van a utilizar. Para ello podemos utilizar el argumento --cleanup o bien la variable de entorno WATCHTOWER_CLEANUP

Existe una larga lista de opciones y argumentos a utilizar. Los podéis consultar todos en la documentación oficial.

Conclusiones

Una vez más se demuestra, que cuando se une el trabajo en equipo, la filosofía de desarrollo del open source y las licencias del software libre, el resultado es una gran obra. Muestra de ello es este proyecto, donde esta involucrado un buen puñado de gente, tal y como se indica en su página en Github. Ya no tenemos excusa para tener nuestros contenedores actualizados y al día.

Espero que esta entrada os haya parecido interesante. Si habéis trabajado con Watchtower o bien tenéis alguna duda al respecto, podéis dejar vuestro comentario en esta entrada.