¿Cómo implementa Docker Swarm el uso compartido de volumen?

93

Docker Swarm puede administrar dos tipos de almacenamiento:

volume y bind

Si bien bindDocker Documentation no lo sugiere, ya que crea un enlace entre un directorio local (en cada nodo de enjambre) a una tarea, la volumeimplementación no se menciona, por lo que no entiendo cómo se comparten los volúmenes entre las tareas.

  • ¿Cómo comparte Docker Swarm volúmenes entre nodos?
  • ¿Dónde se guardan los volúmenes (en un administrador? ¿Y si hay más de un administrador?)
  • ¿No hay ningún problema entre los nodos si se ejecuta en diferentes máquinas en diferentes redes?
  • ¿Crea una VPN?
alessandro308
fuente
1
¿Swarm comparte volúmenes? Hace aproximadamente un año que me ocupé del enjambre de docker, pero creo que swarm NO es responsable de compartir volúmenes entre nodos. Si desea que sus nodos compartan el mismo volumen, debe usar complementos de volumen como azure volumedriver.
Munchkin

Respuestas:

66

Lo que estás preguntando es una pregunta común. Los datos de volumen y las características de lo que puede hacer ese volumen son administrados por un controlador de volumen. Al igual que se pueden utilizar diferentes controladores de red como overlay, bridgeo host, se pueden utilizar diferentes controladores de volumen.

Docker y Swarm solo vienen con el localcontrolador estándar fuera de la caja. No tiene ningún conocimiento de Swarm, y solo creará nuevos volúmenes para sus datos en cualquier nodo en el que estén programadas sus tareas de servicio. Por lo general, esto no es lo que desea.

Desea un complemento de controlador de terceros que sea compatible con Swarm y se asegure de que el volumen que creó para una tarea de servicio esté disponible en el nodo correcto en el momento adecuado. Las opciones incluyen el uso de "Docker para AWS / Azure" y su controlador CloudStor incluido , o la popular solución REX-Ray de código abierto .

Hay muchos controladores de volumen de terceros, que puede encontrar en Docker Store .

Bret Fisher
fuente
¿Hadoop puede actuar como un volumen compartido?
stackit
55

El modo Swarm en sí no hace nada diferente con los volúmenes, ejecuta cualquier comando de montaje de volumen que proporciones en el nodo donde se ejecuta el contenedor. Si su montaje de volumen es local para ese nodo, sus datos se guardarán localmente en ese nodo. No hay una funcionalidad incorporada para mover datos entre nodos automáticamente.

Hay algunas soluciones de almacenamiento distribuido basadas en software como GlusterFS, y Docker tiene una llamada Infinit que aún no es GA y el desarrollo ha pasado a un segundo plano frente a la integración de Kubernetes en EE.

El resultado típico es que necesita administrar la replicación del almacenamiento dentro de su aplicación (por ejemplo, etcd y otros algoritmos basados ​​en balsa) o realiza sus montajes en un sistema de almacenamiento externo (con suerte con su propio HA). El montaje de un sistema de almacenamiento externo tiene dos opciones, basado en bloques o en archivos. El almacenamiento basado en bloques (p. Ej., EBS) suele tener un rendimiento superior, pero está limitado a montarse en un solo nodo. Para esto, normalmente necesitará un controlador de complemento de volumen de terceros para darle acceso a su nodo Docker a ese almacenamiento en bloque. El almacenamiento basado en archivos (por ejemplo, EFS) tiene un rendimiento más bajo, pero es más portátil y puede montarse simultáneamente en varios nodos, lo que es útil para un servicio replicado.

El almacenamiento de red basado en archivos más común es NFS (este es el mismo protocolo que usa EFS). Y puede montar eso sin ningún controlador de complemento de terceros. El controlador del complemento de volumen "local", lamentablemente llamado, que viene con la ventana acoplable, le da la opción de pasar los valores que desee al comando de montaje con las opciones del controlador, y sin opciones, por defecto almacena volúmenes en el directorio de la ventana acoplable / var / lib / Docker / volúmenes. Con las opciones, puede pasarle los parámetros de NFS, e incluso realizará una búsqueda de DNS en el nombre de host de NFS (algo que normalmente no tiene con NFS). Aquí hay un ejemplo de las diferentes formas de montar un sistema de archivos NFS usando el controlador de volumen local:

  # create a reusable volume
  $ docker volume create --driver local \
      --opt type=nfs \
      --opt o=nfsvers=4,addr=192.168.1.1,rw \
      --opt device=:/path/to/dir \
      foo

  # or from the docker run command
  $ docker run -it --rm \
    --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,\"volume-opt=o=nfsvers=4,addr=192.168.1.1\",volume-opt=device=:/host/path \
    foo

  # or to create a service
  $ docker service create \
    --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,\"volume-opt=o=nfsvers=4,addr=192.168.1.1\",volume-opt=device=:/host/path \
    foo

  # inside a docker-compose file
  ...
  volumes:
    nfs-data:
      driver: local
      driver_opts:
        type: nfs
        o: nfsvers=4,addr=192.168.1.1,rw
        device: ":/path/to/dir"
  ...

Si usa el ejemplo de archivo de redacción al final, tenga en cuenta que los cambios en un volumen (por ejemplo, la actualización de la ruta o dirección del servidor) no se reflejan en los volúmenes con nombre existentes mientras existan. Debe cambiar el nombre de su volumen o eliminarlo para permitir que swarm lo vuelva a crear con nuevos valores.

El otro problema común que veo en la mayoría de los usos de NFS es que "root squash" está habilitado en el servidor. Esto da lugar a problemas de permisos cuando los contenedores que se ejecutan como root intentan escribir archivos en el volumen. También tiene problemas de permisos de UID / GID similares en los que el UID / GID del contenedor es el que necesita permisos para escribir en el volumen, lo que puede requerir que la propiedad del directorio y los permisos se ajusten en el servidor NFS.

BMitch
fuente
9

Mi solución para AWS EFS, que funciona:

  1. Cree EFS (no olvide abrir el puerto NFS 2049 en el grupo de seguridad)
  2. Instale el paquete nfs-common:

    sudo apt-get install -y nfs-common

  3. Compruebe si su efs funciona:

    mkdir efs-test-point
    sudo chmod go + rw efs-test-point
    sudo mount -t nfs -o nfsvers = 4.1, rsize = 1048576, wsize = 1048576, hard, timeo = 600, retrans = 2, noresvport [YOUR_EFS_DNS]: / efs-test-point
    toque efs-test-point / 1.txt
    sudo umount efs-test-point /
    ls -la efs-test-point /

    el directorio debe estar vacío

    sudo mount -t nfs -o nfsvers = 4.1, rsize = 1048576, wsize = 1048576, hard, timeo = 600, retrans = 2, noresvport [YOUR_EFS_DNS]: / efs-test-point

    ls -la efs-test-point/

    el archivo 1.txt debe existir

  4. Configure el archivo docker-compose.yml:

    servicios:
      sidekiq:
        volúmenes:
          - uploads_tmp_efs: / home / application / public / uploads / tmp
      ...
    volúmenes:
      uploads_tmp_efs:
        conductor: local
        driver_opts:
          tipo: nfs
          o: addr = [YOUR_EFS_DNS], nfsvers = 4.1, rsize = 1048576, wsize = 1048576, hard, timeo = 600, retrans = 2
          dispositivo: [YOUR_EFS_DNS]: /

super_p
fuente
6

Mi solución para nuestro enjambre alojado localmente: cada nodo trabajador ha montado un recurso compartido nfs, proporcionado por nuestro servidor de archivos en /mnt/docker-data. Cuando defino volúmenes en mis archivos de composición de servicios, configuro el dispositivo en alguna ruta /mnt/docker-data, por ejemplo:

volumes:
  traefik-logs:
    driver: local
    driver_opts:
      o: bind
      device: /mnt/docker-data/services/traefik/logs
      type: none

Con esta solución, la ventana acoplable crea el volumen en cada nodo, el servicio se implementa y, sorpresa, ya hay datos, porque es la misma ruta que utilizó el volumen en el otro nodo.

Si observa más de cerca el sistema de archivos de los nodos, verá que los montajes en mi servidor de archivos se crean debajo /var/lib/docker/volumes, vea aquí:

root@node-3:~# df -h
Dateisystem                                                                                                   Größe Benutzt Verf. Verw% Eingehängt auf
[...]
fs.mydomain.com:/srv/shares/docker-data/services/traefik/logs                                 194G    141G   53G   73% /var/lib/docker/volumes/traefik_traefik-logs/_data
tigu
fuente