angle-uparrow-clockwisearrow-counterclockwisearrow-down-uparrow-leftatcalendarcard-listchatcheckenvelopefolderhouseinfo-circlepencilpeoplepersonperson-fillperson-plusphoneplusquestion-circlesearchtagtrashx

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.

29 agosto 2023 Actualizado 29 agosto 2023
En Docker
post main image

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

Deje un comentario

Comente de forma anónima o inicie sesión para comentar.

Comentarios

Deje una respuesta.

Responda de forma anónima o inicie sesión para responder.