/

Docker y runit

Created 2020-01-21 Modifyed 2020-01-21
533 Words

Cuando creamos un contenedor docker personalizado en el que levantamos una aplicación, puede darse el caso de que esa aplicacion “crashee” y por ende el contenedor se pare.

Para solucionar el problema, podemos usar un supervisor, que monitorice el proceso y en caso de que el proceso “caiga”, el supervisor vuelva a ejecutarlo.

Vamos a utilizar runit para dicho cometido.

En el siguiente ejemplo vamos a crear una imagen que partirá de un ubuntu:18.04 y levantará un apache2.

Para esto crearemos un Dockerfile con el siguiente contenido

FROM ubuntu:18.04
RUN apt update && apt install -y apache2
CMD apache2ctl -D FOREGROUND

Ahora vamos hacer el build de la imagen y lanzarla

athos@athos-Z97P-D3:~/Desktop/pruebarunit$ docker build -t pruebarunit .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM ubuntu:18.04
 ---> ccc6e87d482b
Step 2/3 : RUN apt update && apt install apache2  -y
 ---> Using cache
 ---> 9534f2a8d627
Step 3/3 : CMD apache2ctl -D FOREGROUND
 ---> Using cache
 ---> 27219926e625
Successfully built 27219926e625
Successfully tagged pruebarunit:latest
athos@athos-Z97P-D3:~/Desktop/pruebarunit$ docker run -p 8080:80 pruebaru
nit
AH00558: apache2: Could not reliably determine the server's fully qualifi
ed domain name, using 172.17.0.2. Set the 'ServerName' directive globally
 to suppress this message

En este momento, tenemos un apache que podremos acceder mediante localhost:8080, hasta ahí todo perfecto.

¿Pero qué pasa si matamos el proceso apache?

docker-y-runit-1

Como se puede ver en la parte izquierda de la imagen superior, cuando matamos el proceso el contenedor docker se para, y hace que tengamos que lanzar el contenedor otra vez para que la aplicación siga funcionando.

Vamos a instalar en el contenedor runit y runit-systemd, y añadiremos unas lineas al Dockerfile para solucionar el problema, quedando del Dockerfile de la siguiente manera:

FROM ubuntu:18.04
RUN apt update && apt install apache2  -y
RUN apt install -y runit runit-systemd -y
COPY ./apache2/run /etc/service/apache2/
RUN chmod +x /etc/service/apache2/run
COPY ./entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT [ "/entrypoint.sh" ]

En la linea 3 hemos añadido la instalación de runit, seguidamente copiamos el script run (ver más abajo) al directorio /etc/service/apache2, le damos permisos ejecución, copiamos el entrypoint (ver más abajo) y tambien le damos permisos de ejecución.

El contenido del archivo run es el siguiente:

#!/bin/sh
exec apache2ctl -D FOREGROUND

Y el contenido del entrypoint es:

#!/bin/sh
exec /usr/bin/runsvdir /etc/service

Ahora vamos a construir la imagen, y la lanzamos.

Nos metemos en el contenedor para simular la caida del servicio (parte derecha de la imagen) y como se ven en la parte izquierda, el servicio automaticamente se vuelve a lanzar

docker-y-ru2

De esta forma podemos controlar que el servicio se vuelve a levantar en caso de un fallo.

En este caso lo hemos aplicado a apache, pero podemos aplicarlo a cualquier otro servicio.