Docker-Mounting-Volumes auf dem Host

134

Ich konnte erfolgreich Ordner zwischen einem Docker-Container für Volumes mit freigeben

docker run -v /host/path:/container/path ...

Aber meine Frage ist, was der Unterschied zwischen diesem und der Verwendung des VOLUMEBefehls in der Docker-Datei ist

VOLUME /path

Ich verwende ein Bild mit einem VOLUMEBefehl und möchte wissen, wie ich es mit meinem Host teilen kann. Ich habe es mit dem -vobigen Befehl gemacht, aber ich wusste nicht, ob ich sowohl das -vals auch brauchte VOLUME.

Jeff Storey
quelle

Antworten:

154

Der VOLUMEBefehl stellt ein Verzeichnis in Ihrem Container bereit und speichert alle in diesem Verzeichnis erstellten oder bearbeiteten Dateien auf Ihrer Host-Festplatte außerhalb der Container-Dateistruktur unter Umgehung des Union-Dateisystems.

Die Idee ist, dass Ihre Volumes von Ihren Docker-Containern gemeinsam genutzt werden können und diese so lange bestehen bleiben, wie ein Container (ausgeführt oder gestoppt) auf sie verweist.

Sie können andere Container vorhandene Volumes bereitstellen lassen (indem Sie sie effektiv zwischen Containern teilen), indem Sie den --volumes-fromBefehl verwenden, wenn Sie einen Container ausführen.

Der grundlegende Unterschied zwischen VOLUMEund -vist dies: -vdie bestehenden Dateien von Ihrem Betriebssystem in Ihrem Docker Behälter montiert und VOLUMEwird ein neues, leeres Volume erstellen auf Ihrem Host und montieren Sie es in Ihrem Behälter.

Beispiel:

  1. Sie haben eine Docker-Datei, die a definiert VOLUME /var/lib/mysql.
  2. Sie erstellen das Docker-Image und markieren es some-volume
  3. Sie führen den Container aus

Und dann,

  1. Sie haben ein anderes Docker-Image, das Sie für dieses Volume verwenden möchten
  2. Sie führen den Docker-Container folgendermaßen aus: docker run --volumes-from some-volume docker-image-name:tag
  3. Jetzt läuft ein Docker-Container, in dem das Volume some-volumegemountet ist/var/lib/mysql

Hinweis: Mit using --volumes-fromwird das Volume über den am Speicherort des Volumes vorhandenen Datenträger bereitgestellt. Das heißt, wenn Sie etwas /var/lib/mysqldrin hatten, wird es durch den Inhalt des Bandes ersetzt.

Chris McKinnel
quelle
12
Was passiert, wenn ich -v in einem Verzeichnis verwende, das bereits in VOLUME angegeben wurde?
Jeff Storey
6
--volumes-fromwird Ihre VOLUMEüber alles, was Sie mit angeben, montieren -v. Interessanterweise sieht es so aus, als würde der Container im privilegierten Modus ( docker run --privileged) ausgeführt, und umounting /var/lib/mysqlhinterlässt nur ein leeres Verzeichnis, sodass Ihr -vMount bei Konflikten mit a vollständig ignoriert wird VOLUME.
Chris McKinnel
2
Sie sagen, Volumes werden so lange aufbewahrt, wie ein Container darauf verweist, und das habe ich an anderer Stelle gesehen. In docs.docker.com/userguide/dockervolumes heißt es: " Datenvolumes sind so konzipiert, dass sie Daten unabhängig vom Lebenszyklus des Containers beibehalten . Docker löscht daher niemals automatisch Volumes, wenn Sie einen Container entfernen, und sammelt auch keine Volumes, die nicht mehr vorhanden sind." von einem Container referenziert. " Eine dieser Aussagen muss falsch sein.
mc0e
1
Die Dateien, die sich auf dem Volume befinden, werden auf der Festplatte gespeichert, wenn ein Container nicht mehr darauf verweist, das Volume selbst jedoch nicht mehr verwendet werden kann (es sei denn, Sie wissen genau, wie ein Volume manuell an einen Container angeschlossen wird, aber selbst dann weiß ich es nicht. Ich weiß nicht, ob dies möglich ist. Wenn ich sage, dass es nicht mehr verwendbar ist, können Sie --volumes-from nicht verwenden, um es zu verwenden. Wenn sie oben "Garbage Collect" sagen, bedeutet dies, dass die Dateien von Ihrer Festplatte gelöscht werden, die sich auf dem Volume befanden.
Chris McKinnel
1
Sie können mit -v verwendet werden, aber nicht mit -volumes-from. Volumes-from verwendet einen Containernamen, um Volumendaten abzurufen (ich glaube, es werden ALLE Volume-Punkte benötigt). Für -v selbst wird im Handbuch jedoch erwähnt, dass Sie -v ein benanntes Volume in Form von bereitstellen können named-volume:/path/in/container. Nicht benannte Volumes erhalten Hashes für Namen, und diese Hashes können anstelle eines Hostpfads für den Zugriff auf verwaiste Volumes bereitgestellt werden. :) Seien Sie sich bewusst, dass volume lsmöglicherweise nicht alle angezeigt werden - versuchen Sie es docker volume ls -f dangling=trueauch.
Jasmine Hegman
43

Lassen Sie mich meine eigene Antwort hinzufügen, weil ich glaube, dass die anderen den Punkt von Docker verfehlen.

Die Verwendung VOLUMEin der Docker-Datei ist der richtige Weg ™, da Sie Docker darüber informieren, dass ein bestimmtes Verzeichnis permanente Daten enthält. Docker erstellt ein Volume für diese Daten und löscht sie niemals, selbst wenn Sie alle Container entfernen, die sie verwenden.

Außerdem wird das Union-Dateisystem umgangen, sodass das Volume tatsächlich ein tatsächliches Verzeichnis ist, das in allen Containern, die es gemeinsam nutzen, an der richtigen Stelle bereitgestellt wird (Lese- / Schreibzugriff oder schreibgeschützt).

Um vom Host aus auf diese Daten zugreifen zu können, müssen Sie nur noch Ihren Container überprüfen:

# docker inspect myapp
[{
    .
    .
    .
    "Volumes": {
        "/var/www": "/var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6...",
        "/var/cache/nginx": "/var/lib/docker/vfs/dir/62499e6b31cb3f7f59bf00d8a16b48d2...",
        "/var/log/nginx": "/var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87..."
    },
    "VolumesRW": {
        "/var/www": false,
        "/var/cache/nginx": true,
        "/var/log/nginx": true
    }
}]

Normalerweise erstelle ich Symlinks an einem Standardort wie / srv , damit ich problemlos auf die Volumes zugreifen und die darin enthaltenen Daten verwalten kann (nur für die Volumes, die Sie interessieren):

ln -s /var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6... /srv/myapp-www
ln -s /var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87... /srv/myapp-log
Tobia
quelle
Was ist, wenn der Docker-Host in einer VM ausgeführt wird? Zum Beispiel boot2docker auf dem Mac. Dann sind diese Volumes nur remote verfügbar. Wenn Sie wie beschrieben Volumes in der Docker-Datei verwenden, wird der Inhalt des Bildes auf das Volume kopiert. Beim Mounten in ein lokales Verzeichnis wird dieses Kopieren jedoch nicht durchgeführt. Wissen Sie, warum dies der Fall ist? Gibt es eine Möglichkeit, ein lokal bereitgestelltes Volume zu erstellen, aber dennoch mit den Dateien aus dem Image neu zu beginnen?
LostSalad
4
Mit Docker-Compose können Sie genau das tun, indem Sie ein Volume an einem bestimmten Speicherort des Host-Betriebssystems bereitstellen . Keine Symlinks erforderlich ...
Hugo Koopmans
@Tobia: Beispiel Docker-Compose siehe docs docs.docker.com/compose/compose-file/…
Hugo Koopmans
11

VOLUME wird verwendet Dockerfile, um das Volumen freizulegen, das von anderen Behältern verwendet werden soll. Beispiel: Erstellen Sie Dockerfileals:

AB Ubuntu: 14.04

RUN mkdir /myvol  
RUN echo "hello world" > /myvol/greeting  
VOLUME /myvol

Erstellen Sie das Bild:

$ docker build -t testing_volume .

Führen Sie den Container aus, sagen Sie container1:

$ docker run -it <image-id of above image> bash

Führen Sie nun einen anderen Container mit der Option volume-from als (say-container2) aus.

$ docker run -it --volumes-from <id-of-above-container> ubuntu:14.04 bash

Sie erhalten alle Daten aus dem /myvolVerzeichnis container1 an derselben Stelle in container2.

-vDie Option wird zur Laufzeit des Containers angegeben, mit dem das Containerverzeichnis auf dem Host bereitgestellt wird. Es ist einfach zu bedienen, geben Sie einfach die -vOption mit Argument als an <host-path>:<container-path>. Der gesamte Befehl kann wie folgt lauten$ docker run -v <host-path>:<container-path> <image-id>

Yogesh Jilhawar
quelle
8

Grundsätzlich VOLUMEund -vOption sind fast gleich. Diese bedeuten "spezifisches Verzeichnis in Ihren Container einbinden". Zum Beispiel VOLUME /dataund -v /dataist genau die gleiche Bedeutung. Wenn Sie das Image mit VOLUME /dataoder mit -v /dataOption ausführen ,/data Verzeichnis in Ihrem Container bereitgestellt. Dieses Verzeichnis gehört nicht zu Ihrem Container.

Stellen Sie sich vor, Sie fügen /datadem Container einige Dateien hinzu und übergeben den Container in ein neues Image. Das Datenverzeichnis enthält keine Dateien, da das bereitgestellte /dataVerzeichnis zum Originalcontainer gehört.

$ docker run -it -v /data --name volume ubuntu:14.04 bash
root@2b5e0f2d37cd:/# cd /data
root@2b5e0f2d37cd:/data# touch 1 2 3 4 5 6 7 8 9
root@2b5e0f2d37cd:/data# cd /tmp
root@2b5e0f2d37cd:/tmp# touch 1 2 3 4 5 6 7 8 9
root@2b5e0f2d37cd:/tmp# exit
exit

$ docker commit volume nacyot/volume  
835cfe3d8d159622507ba3256bb1c0b0d6e7c1419ae32751ad0f925c40378945
nacyot $ docker run -it nacyot/volume
root@dbe335c7e64d:/# cd /data
root@dbe335c7e64d:/data# ls
root@dbe335c7e64d:/data# cd /tmp
root@dbe335c7e64d:/tmp# ls
1  2  3  4  5  6  7  8  9
root@dbe335c7e64d:/tmp# 
root@dbe335c7e64d:/tmp# 

Dieses gemountete Verzeichnis wie /datawird zum Speichern von Daten verwendet, die nicht zu Ihrer Anwendung gehören. Und Sie können das Datenverzeichnis, das nicht zum Container gehört, mit vordefinieren VOLUME.

Ein Unterschied zwischen Volumeund -vOption besteht darin, dass Sie die -vOption beim Starten des Containers dynamisch verwenden können. Dies bedeutet, dass Sie ein Verzeichnis dynamisch bereitstellen können. Ein weiterer Unterschied besteht darin, dass Sie Ihr Host-Verzeichnis mithilfe von auf Ihrem Container bereitstellen können-v

Nacyot
quelle
8

Dies stammt aus der Docker-Dokumentation selbst und kann hilfreich sein, einfach und klar:

"Das Hostverzeichnis ist von Natur aus hostabhängig. Aus diesem Grund können Sie kein Hostverzeichnis über Dockerfile bereitstellen. Die Anweisung VOLUME unterstützt die Übergabe eines Hostverzeichnisses nicht, da erstellte Images portabel sein sollten. Ein Host Verzeichnis wäre nicht auf allen potenziellen Hosts verfügbar. "

Vennesa
quelle