De Docker-Composer a Docker Swarm: Configs
Docker Configs vamos a Docker Swarm gestionar nuestra configuración (estática), no requiere almacenamiento de volumen compartido.
Tiene una aplicación que consta de varios proyectos Docker-Compose y utiliza Docker-Compose para compilar, iniciar y desplegar.
Ahora quiere ir un paso más allá y mover algunos de los proyectos Docker-Compose a otro servidor. La opción más obvia para hacer esto, bueno para probar primero, es Docker Swarm. Aprendes unos pocos comandos más Docker y listo. ¿Es realmente tan fácil?
Spoiler alert. No, no es fácil si tienes contenedores que usan volúmenes, por ejemplo, para datos de configuración, datos de alto rendimiento, datos persistentes. Muchos ejemplos en Internet evitan este tema por completo, o mencionan casualmente el uso de soluciones de almacenamiento compartido como NFS (no cifrado) o GlusterFS, o utilizan soluciones de almacenamiento de proveedores en la nube. Todas estas soluciones de almacenamiento tienen la misma característica: Están basadas en red y son muy lentas en comparación con el almacenamiento nativo. Sí, puedes ir más rápido, pero pagarás más.
Antes incluso de considerar Docker Swarm, te recomiendo que leas sobre este tema para entender si tu caso de uso es adecuado para Docker Swarm. Por ejemplo aquí hay una discusión sobre esto, 'Data(base) persistence in docker swarm mode', ver enlaces más abajo. Y a partir de esta respuesta Stackoverflow 'How does Docker Swarm implement volume sharing?', ver enlaces más abajo:
Swarm El modo en sí no hace nada diferente con los volúmenes, ejecuta cualquier comando de montaje de volumen que proporciones en el nodo donde se está ejecutando el contenedor. Si su volumen de montaje es local a ese nodo, entonces sus datos se guardarán localmente en ese nodo. No hay funcionalidad integrada para mover datos entre nodos automáticamente.
Esto significa que es posible preparar una estructura de directorios en un nodo trabajador, y asegurarse de ejecutar un contenedor sólo en este nodo utilizando los parámetros de ubicación de despliegue. Opciones ...
En este post usamos Docker Swarm Configs para pasar datos de configuración (estáticos) a contenedores en nodos trabajadores. Esto es un poco anti-patrón, pero lo bueno es que eliminamos un requisito de almacenamiento.
Como siempre estoy corriendo en Ubuntu 22.04. Por el momento no estoy usando Docker Desktop. He utilizado VirtualBox para crear un servidor Ubuntu VM y utilizarlo como trabajador.
Docker Swarm no gestiona datos de volumen.
Docker Swarm es un gestor de servicios y los servicios son contenedores (basados en images), no datos de volumen. Esto significa que debe gestionar los datos de volumen usted mismo.
Como ejemplo, considere un contenedor de servidor DSN. Con Docker Swarm, podemos desplegar este contenedor, especificar réplicas, fácil lo hace.
Ahora, queremos que el mismo contenedor servidor DSN se conecte al servicio DNS B en internet. Seguimos las instrucciones del mantenedor del contenedor, creamos dos ficheros (de configuración), creamos un mapeo de volúmenes, y listo.
Parte del archivo Docker-Compose:
...
services:
dns_service:
image: ...
volumes:
- ./config/definitions1.conf:/opt/dns_server/config/definitions1.conf:ro
- ./config/definitions2.conf:/opt/dns_server/config/definitions2.conf:ro
...
Pero ahora tenemos un problema con Docker Swarm porque ¡no gestiona nuestros datos de volumen! Si desplegamos el servicio en un nodo trabajador, los datos, los archivos de configuración, ¡no están ahí!
Horneando' datos de configuración en el servicio
Cuando usamos Docker Swarm, no tenemos datos en nuestros volúmenes... si no hacemos nada. Hay una manera de evitar esto, llamada 'Configs', no disponible en Docker-Compose. Podemos usar esto para especificar archivos que serán montados en el contenedor como podemos hacer con volúmenes. Primero veremos la solución Docker-Compose y luego la cambiaremos por Docker Swarm.
Utilización de Docker-Compose
Al utilizar Docker-Compose, el archivo 'docker-compose.yml' para nuestro proyecto de servidor DNS, véase más arriba,
utiliza volúmenes y tiene un aspecto similar:
# docker-compose.yml, using volumes
version: '3.7'
services:
app:
image: busybox_volumes
build: .
volumes:
- ./config/definitions1.conf:/opt/dns_server/config/definitions1.conf:ro
- ./config/definitions2.conf:/opt/dns_server/config/definitions2.conf:ro
command: sh -c "ls -l /opt/dns_server/config && cat /opt/dns_server/config/definitions*.conf && tail -f /dev/null"
Añadimos un 'Dockerfile':
# Dockerfile
FROM busybox
Y construimos la imagen:
docker-compose build
Y luego la ejecutamos:
docker-compose up
El texto impreso en la pantalla es:
app_1 | total 8
app_1 | -rw-rw-r-- 1 1000 1000 14 Aug 29 08:06 definitions1.conf
app_1 | -rw-rw-r-- 1 1000 1000 14 Aug 29 08:06 definitions2.conf
app_1 | definitions=1
app_1 | definitions=2
Esto es lo esperado. Pero si Docker Swarm desplegara este servicio en otro host, un nodo trabajador, faltarían nuestros archivos.
Usando Docker Swarm
Aquí eliminamos la sección 'volumes' y añadimos la nueva sección 'configs' :
# docker-compose.yml, using configs
version: '3.7'
services:
app:
image: busybox_configs
build: .
configs:
- source: definitions1
target: /opt/dns_server/config/definitions1.conf
- source: definitions2
target: /opt/dns_server/config/definitions2.conf
command: sh -c "ls -l /opt/dns_server/config && cat /opt/dns_server/config/definitions*.conf && tail -f /dev/null"
configs:
definitions1:
file: ./config/definitions1.conf
definitions2:
file: ./config/definitions2.conf
Construimos la imagen:
docker-compose build
Y desplegamos:
docker stack deploy -c docker-compose.yml configs
El resultado del comando deploy muestra la creación del 'configs':
Creating network configs_default
Creating config configs_definitions2
Creating config configs_definitions1
Creating service configs_app
No se imprime nada en pantalla, para ver que está pasando miramos el log de este servicio:
docker service logs configs_app
El resultado:
configs_app.1.vqumgq21leq8@myra | total 8
configs_app.1.vqumgq21leq8@myra | -r--r--r-- 1 root root 14 Aug 29 09:58 definitions1.conf
configs_app.1.vqumgq21leq8@myra | -r--r--r-- 1 root root 14 Aug 29 09:58 definitions2.conf
configs_app.1.vqumgq21leq8@myra | definitions=1
configs_app.1.vqumgq21leq8@myra | definitions=2
Esto significa que el gestor Docker Swarm ha añadido correctamente nuestros ficheros.
En mi caso el servicio fue desplegado en el nodo gestor Docker Swarm , no en el nodo trabajador. Para ejecutarlo en el nodo trabajador, añadimos lo siguiente a 'docker-compose.yml':
deploy:
placement:
constraints:
- node.role == worker
replicas: 1
Etiquete su imagen y envíela a su registro Docker .
Sólo si utiliza un registro privado
Si está utilizando un registro privado, no seguro, debe indicar a todos los nodos Docker que no es seguro añadiendo esta información
{
"insecure-registries":[
"<your registry ip address>:<your registry port>"
],
}
al archivo:
/etc/docker/daemon.json
Reinicie Docker una vez que haya hecho esto:
sudo systemctl restart docker
Importante: Debe hacer esto en todos los nodos.
Ahora, edita tu archivo 'docker-compose.yml' para decirle a Docker Swarm dónde puede obtener tu imagen.
De:
...
services:
app:
image: busybox_configs:latest
...
Para:
...
services:
app:
image: <registry host>:<registry port>/busybox_configs:latest
...
Despliega el servicio en el nodo trabajador
Elimine el servicio de este nodo, si todavía está allí:
docker stack rm configs_app
Y despliega de nuevo:
docker stack deploy -c docker-compose.yml configs
Ahora puedes comprobar que el servicio se está ejecutando en el nodo trabajador:
docker service ps configs_app
El resultado contiene el nodo, ver 'NODE':
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
xotczxp65lub configs_app.1 ... vmubs2204a Running Running 9 minutes ago
Puedes obtener más información por ejemplo con el comando:
docker service inspect --pretty configs_app
Y lo más importante, ¿qué hizo exactamente nuestro servicio? No se imprime nada en la pantalla, debemos mirar los logs:
docker service logs configs_app
El resultado es exactamente el mismo que antes. Lo que significa que Docker Swarm no sólo desplegó nuestro servicio (contenedor), sino que también puso nuestros archivos 'configs' a disposición de nuestro contenedor que se ejecuta en el nodo trabajador. Listo.
Resumen
En este post, hemos utilizado Docker Configs para pasar datos de configuración (estáticos) a los contenedores. En 'docker-compose.yml', hemos eliminado la sección 'volumes' y la hemos sustituido por la sección 'configs' . Ahora Docker Swarm gestiona estos datos y no necesitamos un volumen de almacenamiento compartido para ello. Lo molesto es que 'configs' no funciona en Docker-Compose, lo que significa que nos estamos alejando de un único 'docker-compose.yml' que puede ser utilizado por Docker-Compose y Docker Swarm.
Enlaces / créditos
Data(base) persistence in docker swarm mode
https://forums.docker.com/t/data-base-persistence-in-docker-swarm-mode/20665
Deploy a stack to a swarm
https://docs.docker.com/engine/swarm/stack-deploy
Docker - configs
https://docs.docker.com/compose/compose-file/compose-file-v3/#configs
Docker Swarm Tutorial | Code Along | Zero to Hero under 1 Hour
https://takacsmark.com/docker-swarm-tutorial-for-beginners
How does Docker Swarm implement volume sharing?
https://stackoverflow.com/questions/47756029/how-does-docker-swarm-implement-volume-sharing
Leer más
Docker Docker-compose
Recientes
- Uso de Ingress para acceder a RabbitMQ en un clúster Microk8s
- Galería de vídeo simple con Flask, Jinja, Bootstrap y JQuery
- Programación básica de trabajos con APScheduler
- Un conmutador de base de datos con HAProxy y el HAProxy Runtime API
- Docker Swarm rolling updates
- Cómo ocultar las claves primarias de la base de datos UUID de su aplicación web
Más vistos
- Usando PyInstaller y Cython para crear un ejecutable de Python
- Reducir los tiempos de respuesta de las páginas de un sitio Flask SQLAlchemy web
- Usando Python's pyOpenSSL para verificar los certificados SSL descargados de un host
- Conectarse a un servicio en un host Docker desde un contenedor Docker
- Usando UUIDs en lugar de Integer Autoincrement Primary Keys con SQLAlchemy y MariaDb
- SQLAlchemy: Uso de Cascade Deletes para eliminar objetos relacionados