web-dev-qa-db-fra.com

Comment Docker Swarm implémente-t-il le partage de volume?

Docker Swarm peut gérer deux types de stockage: le volume et la liaison. Bien que la liaison ne soit pas suggérée par la documentation Docker car elle crée une liaison entre un répertoire local (sur chaque nœud en essaim) et une tâche, l'implémentation de la méthode de volume n'est pas mentionnée. Je ne comprends donc pas comment les volumes sont partagés entre les tâches.

Comment Docker Swarm partage les volumes entre les nœuds? Où les volumes sont-ils sauvegardés (sur un responsable? Et s’il en existe plusieurs)?

Il n'y a pas de problème entre les noeuds s'il tourne sur différentes machines dans différents réseaux? Crée-t-il un VPN?

66
alessandro308

Ce que vous demandez est une question commune. Les données de volume et les fonctionnalités de ce volume peuvent être gérées par un pilote de volume. Tout comme vous pouvez utiliser différents pilotes réseau, tels que overlay, bridge ou Host, vous pouvez utiliser différents pilotes de volume.

Docker et Swarm sont uniquement livrés avec le pilote standard local. Swarm n'est pas au courant et crée simplement de nouveaux volumes pour vos données, quel que soit le nœud sur lequel les tâches de service sont planifiées. Ce n'est généralement pas ce que vous voulez.

Vous souhaitez un plug-in de pilote tiers compatible avec Swarm et veillant à ce que le volume que vous avez créé pour une tâche de service soit disponible sur le bon nœud au bon moment. Les options incluent l’utilisation de "Docker pour AWS/Azure" et de son pilote CloudStor inclus, ou de la solution Open Source populaire REX-Ray .

Il existe de nombreux pilotes de volume tiers, que vous pouvez trouver sur le Docker Store .

43
Bret Fisher

Le mode Swarm lui-même ne fait rien de différent avec les volumes, il exécute toute commande de montage de volume que vous fournissez sur le nœud sur lequel le conteneur est en cours d'exécution. Si votre montage de volume est local sur ce nœud, vos données seront enregistrées localement sur ce nœud. Aucune fonctionnalité intégrée ne permet de déplacer automatiquement les données entre les nœuds.

Il existe des solutions de stockage distribuées basées sur des logiciels, telles que GlusterFS, et Docker en propose une, appelée Infinit, qui n’est pas encore GA, et le développement de cette solution a cédé le pas à l’intégration de Kubernetes dans EE.

Le résultat typique est que vous devez gérer la réplication du stockage au sein de votre application (par exemple, etcd et d'autres algorithmes basés sur un radeau) ou bien effectuer vos montages sur un système de stockage externe (avec son propre HA, si tout va bien). Le montage sur un système de stockage externe comporte deux options: bloc ou fichier. Le stockage basé sur les blocs (par exemple, EBS) est généralement plus performant, mais il est limité pour ne pouvoir être monté que sur un seul nœud. Pour cela, vous aurez généralement besoin d'un pilote de plug-in de volume tiers pour donner à votre nœud de docker un accès à ce bloc de stockage. Le stockage basé sur fichiers (par exemple, EFS) offre des performances inférieures, mais est plus portable et peut être monté simultanément sur plusieurs nœuds, ce qui est utile pour un service répliqué.

Le stockage réseau basé sur fichier le plus courant est NFS (il s'agit du même protocole utilisé par EFS). Et vous pouvez monter cela sans aucun pilote de plug-in tiers. Le pilote de plug-in de volume malheureusement nommé "local" fourni avec docker vous permet de transmettre les valeurs de votre choix à la commande mount avec les options du pilote. Sans option, il stocke par défaut les volumes dans le répertoire docker/var/lib/menu fixe/volumes. Avec les options, vous pouvez lui transmettre les paramètres NFS, et il effectuera même une recherche DNS sur le nom d’hôte NFS (ce que vous n’avez pas normalement avec NFS). Voici un exemple des différentes manières de monter un système de fichiers NFS à l'aide du pilote de volume 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"
  ...
30
BMitch

Ma solution pour AWS EFS, qui fonctionne:

  1. Create EFS (n'oubliez pas d'ouvrir le port NFS 2049 sur le groupe de sécurité)
  2. Installez le paquet nfs-common:

    Sudo apt-get install -y nfs-common

  3. Vérifiez si votre efs fonctionne:

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

    le répertoire doit être vide

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

    ls -la efs-test-point/

    le fichier 1.txt doit exister

  4. Configurez le fichier docker-compose.yml:

    services: 
     sidekiq: 
     volumes: 
     - uploads_tmp_efs:/home/application/public/uploads/tmp 
     ... 
     volumes: 
     uploads_tmp_efs: 
     pilote: local 
     driver_opts: 
     type: nfs 
     o: addr = [VOTRE_EFS_DNS], nfsvers = 4.1, rsize = 1048576, wsize = 1048576, difficile, temps = 600, retransfert = 2 
     périphérique: [YOUR_EFS_DNS]: /
5
super_p