webentwicklung-frage-antwort-db.com.de

Wie implementiert Docker Swarm Volume Sharing?

Docker Swarm kann zwei Arten von Speicher verwalten: Datenträger und Bindung. Die Docker-Dokumentation schlägt zwar keine Bindung vor, da eine Bindung zwischen einem lokalen Verzeichnis (auf jedem Schwarmknoten) und einer Aufgabe erstellt wird. Die Implementierung der Datenträgermethode wird jedoch nicht erwähnt, sodass ich nicht verstehe, wie Datenträger 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 es auf verschiedenen Rechnern in verschiedenen Netzen läuft? Erstellt es ein VPN?

66
alessandro308

Was Sie fragen, ist eine häufige Frage. Volume-Daten und die Funktionen, die dieses Volume ausführen kann, werden von einem Volume-Treiber verwaltet. Genauso wie Sie verschiedene Netzwerktreiber wie overlay, bridge oder Host verwenden können, können Sie auch verschiedene Volume-Treiber verwenden.

Docker und Swarm werden nur mit dem Standardtreiber local ausgeliefert. Es hat keine Kenntnis von Swarm und erstellt lediglich neue Volumes für Ihre Daten auf dem Knoten, 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 zum richtigen Zeitpunkt auf dem richtigen Knoten verfügbar ist. Zu den Optionen gehört die Verwendung von "Docker für AWS/Azure" und des darin enthaltenen Treibers CloudStor oder der beliebten Open Source-Lösung REX-Ray .

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

43
Bret Fisher

Der Schwarmmodus selbst ändert nichts mit Volumes. Er führt jeden Befehl zum Laden von Volumes aus, den Sie auf dem Knoten angeben, auf dem der Container ausgeführt wird. Wenn sich Ihr Volume Mount lokal auf diesem Knoten befindet, 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 vorliegt, und die Entwicklung darauf hat die Kubernetes-Integration 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 Algorithmen auf Raft-Basis) oder Ihre Bereitstellungen auf einem externen Speichersystem durchführen müssen (hoffentlich mit einem eigenen HA). Das Mounten eines externen Speichersystems hat 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 in der Regel einen Volumetreiber 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 auch von EFS verwendet wird). Und Sie können dies ohne Plug-In-Treiber von Drittanbietern bereitstellen. Der unglücklicherweise als "lokal" bezeichnete Volume-Plugin-Treiber, mit dem Docker ausgeliefert wird, bietet Ihnen die Möglichkeit, alle gewünschten Werte mit Treiberoptionen an den Befehl mount zu übergeben. Ohne Optionen werden die Volumes standardmäßig im Docker-Verzeichnis/var/lib/gespeichert. Docker/Volumes. Mit den 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). Im Folgenden finden Sie ein Beispiel für die verschiedenen Möglichkeiten, ein NFS-Dateisystem mithilfe des Treibers für lokale Volumes bereitzustellen:

  # 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

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

  1. EFS erstellen (vergessen Sie nicht, 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-test-point /
     ls -la efs-test-point /

    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:

    services: 
     sidekiq: 
     volume: 
     - uploads_tmp_efs:/home/application/public/uploads/tmp 
     ... 
     volume: 
     uploads_tmp_efs: 
     driver: local 
     driver_opts: 
     type: nfs 
     o: addr = [YOUR_EFS_DNS], nfsvers = 4.1, rsize = 1048576, wsize = 1048576, hard, timeo = 600, retrans = 2 
     device: [YOUR_EFS_DNS]: /
5
super_p