Wie implementiert Docker Swarm die gemeinsame Nutzung von Volumes?

86

Docker Swarm kann zwei Arten von Speicher verwalten:

volume und bind

Die bindDocker-Dokumentation schlägt dies zwar nicht vor, da eine Bindung zwischen einem lokalen Verzeichnis (auf jedem Schwarmknoten) und einer Aufgabe erstellt wird. Die volumeImplementierung wird jedoch nicht erwähnt, sodass ich nicht verstehe, wie Volumes zwischen Aufgaben geteilt werden.

  • Wie teilt Docker Swarm Volumes zwischen Knoten?
  • Wo werden Volumes gespeichert (auf einem Manager? Und wenn es mehr als einen Manager gibt?)
  • Gibt es kein Problem zwischen Knoten, wenn sie auf verschiedenen Computern in verschiedenen Netzwerken ausgeführt werden?
  • Erstellt es ein VPN?
alessandro308
quelle
1
Teilt Swarm Volumen? Es ist ungefähr ein Jahr her, dass ich mich mit Docker-Schwarm befasst habe, aber ich denke, Schwarm ist NICHT dafür verantwortlich, Volumes zwischen Knoten zu teilen. Wenn Sie möchten, dass Ihre Knoten dasselbe Volume verwenden, müssen Sie Volume-Plugins wie Azure Volumedriver verwenden.
Munchkin

Antworten:

62

Was Sie fragen, ist eine häufige Frage. Datenträgerdaten und die Funktionen dieses Datenträgers werden von einem Datenträgertreiber verwaltet. Genau wie Sie unterschiedliche Netzwerktreiber wie verwenden können overlay, bridgeoder hostkönnen Sie verschiedene Lautstärke - Treiber verwenden.

Docker und Swarm werden nur mit dem Standardtreiber ausgeliefert local. Swarm ist nicht bekannt, und es werden lediglich neue Volumes für Ihre Daten auf dem Knoten erstellt, auf dem Ihre Serviceaufgaben geplant sind. Dies ist normalerweise nicht das, was Sie wollen.

Sie möchten ein Treiber-Plugin eines Drittanbieters, das Swarm-fähig ist und sicherstellt, dass das für eine Serviceaufgabe erstellte Volume zur richtigen Zeit auf dem richtigen Knoten verfügbar ist. Zu den Optionen gehören die Verwendung von "Docker für AWS / Azure" und des mitgelieferten CloudStor- Treibers oder die beliebte Open-Source- REX-Ray- Lösung.

Es gibt viele Volume-Treiber von Drittanbietern, die Sie im Docker Store finden .

Bret Fisher
quelle
51

Der Schwarmmodus selbst macht mit Volumes nichts anderes. Er führt jeden Volume-Mount-Befehl aus, den Sie auf dem Knoten bereitstellen, auf dem der Container ausgeführt wird. Wenn Ihr Volume-Mount lokal für diesen Knoten ist, werden Ihre Daten lokal auf diesem Knoten gespeichert. Es gibt keine integrierte Funktion zum automatischen Verschieben von Daten zwischen Knoten.

Es gibt einige softwarebasierte verteilte Speicherlösungen wie GlusterFS, und Docker hat eine mit dem Namen Infinit, die noch nicht GA ist, und die Entwicklung hat die Integration von Kubernetes in EE in den Hintergrund gerückt.

Das typische Ergebnis ist, dass Sie entweder die Replikation des Speichers in Ihrer Anwendung verwalten müssen (z. B. etcd und andere raftbasierte Algorithmen) oder Ihre Bereitstellungen auf einem externen Speichersystem durchführen (hoffentlich mit einem eigenen HA). Das Mounten eines externen Speichersystems bietet zwei Optionen: block- oder dateibasiert. Blockbasierter Speicher (z. B. EBS) bietet normalerweise eine höhere Leistung, kann jedoch nur auf einem einzelnen Knoten bereitgestellt werden. Zu diesem Zweck benötigen Sie normalerweise einen Volume-Plugin-Treiber eines Drittanbieters, um Ihrem Docker-Knoten Zugriff auf diesen Blockspeicher zu gewähren. Dateibasierter Speicher (z. B. EFS) weist eine geringere Leistung auf, ist jedoch portabler und kann gleichzeitig auf mehreren Knoten bereitgestellt werden, was für einen replizierten Dienst nützlich ist.

Der am häufigsten verwendete dateibasierte Netzwerkspeicher ist NFS (dies ist das gleiche Protokoll, das von EFS verwendet wird). Und Sie können dies ohne Plugin-Treiber von Drittanbietern bereitstellen. Der leider als "lokal" bezeichnete Volume-Plugin-Treiber, mit dem Docker geliefert wird, bietet Ihnen die Möglichkeit, beliebige Werte mit Treiberoptionen an den Befehl mount zu übergeben. Ohne Optionen werden standardmäßig Volumes im Docker-Verzeichnis / var / lib / gespeichert. Docker / Volumes. Mit Optionen können Sie die NFS-Parameter übergeben, und es wird sogar eine DNS-Suche für den NFS-Hostnamen durchgeführt (etwas, das Sie normalerweise mit NFS nicht haben). Hier ist ein Beispiel für die verschiedenen Möglichkeiten zum Mounten eines NFS-Dateisystems mithilfe des lokalen Volume-Treibers:

  # 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"
  ...

Wenn Sie am Ende das Beispiel für die Erstellungsdatei verwenden, beachten Sie, dass Änderungen an einem Volume (z. B. Aktualisieren des Serverpfads oder der Serveradresse) nicht in vorhandenen benannten Volumes berücksichtigt werden, solange sie vorhanden sind. Sie müssen Ihr Volume entweder umbenennen oder löschen, damit Swarm es mit neuen Werten neu erstellen kann.

Das andere häufige Problem, das ich bei den meisten NFS-Anwendungen sehe, ist das Aktivieren von "Root Squash" auf dem Server. Dies führt zu Berechtigungsproblemen, wenn Container, die als Root ausgeführt werden, versuchen, Dateien auf das Volume zu schreiben. Sie haben auch ähnliche Probleme mit UID / GID-Berechtigungen, bei denen die Container-UID / GID Berechtigungen zum Schreiben auf das Volume benötigt, für die möglicherweise Verzeichnisbesitz und Berechtigungen auf dem NFS-Server angepasst werden müssen.

BMitch
quelle
8

Meine Lösung für AWS EFS, die funktioniert:

  1. EFS erstellen (vergessen Sie nicht, den NFS-Port 2049 in der Sicherheitsgruppe zu öffnen)
  2. Installieren Sie das nfs-common-Paket:

    sudo apt-get install -y nfs-common

  3. Überprüfen Sie, ob Ihr EFS funktioniert:

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

    Verzeichnis muss leer sein

    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/

    Datei 1.txt muss vorhanden sein

  4. Konfigurieren Sie die Datei docker-compose.yml:

    Dienstleistungen:
      Sidekiq:
        Bände:
          - uploads_tmp_efs: / home / application / public / uploads / tmp
      ...
    Bände:
      uploads_tmp_efs:
        Fahrer: lokal
        driver_opts:
          Typ: nfs
          o: addr = [YOUR_EFS_DNS], nfsvers = 4.1, rsize = 1048576, wsize = 1048576, hard, timeo = 600, retrans = 2
          Gerät: [YOUR_EFS_DNS]: /

super_p
quelle
4

Meine Lösung für unseren lokal gehosteten Schwarm: Jeder Worker-Knoten hat eine NFS-Freigabe bereitgestellt, die von unserem Dateiserver bereitgestellt wird /mnt/docker-data. Wenn ich Volumes in den Compose-Dateien meiner Dienste definiere, setze ich das Gerät auf einen Pfad unter /mnt/docker-data, zum Beispiel:

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

Mit dieser Lösung erstellt Docker das Volume auf jedem Knoten, der Dienst wird bereitgestellt, und - überraschenderweise - es sind bereits Daten vorhanden, da es sich um denselben Pfad handelt, der vom Volume auf dem anderen Knoten verwendet wurde.

Wenn Sie sich das Knoten-Dateisystem genauer ansehen, sehen Sie, dass Mounts für meinen Dateiserver-Mount unter erstellt /var/lib/docker/volumeswerden. Siehe hier:

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
quelle