Betrachten Sie den folgenden Docker-Container:
docker run --rm -it -v /tmp:/mnt/tmp alpine sh
Dadurch wird das Hostverzeichnis / tmp in / mnt / tmp im alpinen Container bereitgestellt.
Jetzt mounte ich auf dem Host-System ein NFS-Volume in das Verzeichnis / tmp:
mkdir /tmp/nfs
mount -t nfs4 192.168.1.100:/data /tmp/nfs
Der Mount funktioniert auf dem Host-System, und ich sehe Folgendes:
# ls /tmp/nfs
file1 file2 file3
#
Aber auf dem Docker Container sehe ich ein leeres Verzeichnis:
# ls /mnt/tmp/nfs
#
Ich weiß, dass ich das umgehen kann, indem ich den Mount direkt im Docker Container mache. Aber ich bin wirklich interessiert zu wissen, warum der Mount auf dem Host-Container funktioniert, aber nicht auf dem Docker-Container?
Antworten:
Dies liegt daran, dass das Volume die
private
Mount-Weitergabe verwendet. Dies bedeutet, dass nach dem Mount keine Änderungen auf der Ursprungsseite (z. B. auf der "Host" -Seite im Fall von Docker) unter dem Mount sichtbar sind.Es gibt verschiedene Möglichkeiten, damit umzugehen:
Führen Sie zuerst die NFS-Bereitstellung durch und starten Sie dann den Container. Die Bereitstellung wird auf den Container übertragen, jedoch werden Änderungen an der Bereitstellung nach wie vor vom Container nicht gesehen (einschließlich Aufheben der Bereitstellung).
Verwenden Sie die "Slave" -Verbreitung. Dies bedeutet, dass nach dem Erstellen des Mount alle Änderungen auf der Ursprungsseite (Docker-Host) im Ziel (im Container) angezeigt werden können. Wenn Sie zufällig verschachtelte Bereitstellungen durchführen, sollten Sie diese verwenden
rslave
(r
für rekursiv).Es gibt auch eine "gemeinsame" Verbreitung. In diesem Modus werden Änderungen am Mountpunkt innerhalb des Containers vorgenommen, die auf den Host übertragen werden, und umgekehrt. Da Ihr Benutzer nicht einmal die Berechtigung hätte, solche Änderungen vorzunehmen (es sei denn, Sie fügen CAP_SYS_ADMIN hinzu), ist dies wahrscheinlich nicht das, was Sie möchten.
Sie können den Ausbreitungsmodus beim Erstellen des Mount wie folgt einstellen:
Die andere Alternative wäre die Verwendung eines Volumes anstelle eines Host-Mount. Sie können dies folgendermaßen tun:
Dadurch wird sichergestellt, dass die Bereitstellung immer im Container für Sie erfolgt. Sie müssen den Host nicht auf eine bestimmte Weise einrichten oder sich mit der Weitergabe von Bereitstellungen befassen.
Hinweis : Der
:
Pfad an der Vorderseite des Gerätepfads ist erforderlich, nur etwas Seltsames am nfs-Kernelmodul.Hinweis : Docker wird derzeit nicht
<nfs host>
von einem DNS-Namen aufgelöst (dies wird in 1.13 der Fall sein ), daher müssen Sie hier die IP-Adresse angeben.Weitere Details zu "Shared Subtree" -Mounts: https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt
quelle
Aktivieren Sie die Shared-Mount-Weitergabe auf dem Volume, indem Sie das Flag: shared am Ende des Volume-Arguments hinzufügen:
Wenn Docker über einen Paketmanager oder ein Installationsskript für systemd installiert wurde, müssen Sie möglicherweise das MountFlags-Daemon-Argument anpassen. Suchen Sie dazu die Datei docker.service:
In meinem Fall unter Ubuntu 16.04 befand es sich unter /etc/systemd/system/multi-user.target.wants/docker.service. Bearbeiten Sie diese Datei mit vi oder nano und stellen Sie sicher, dass die Option MountFlags lautet:
Speichern Sie die Datei, laden Sie die Daemon-Argumente neu und starten Sie Docker neu:
Jetzt sollten Sie in der Lage sein, das Flag für die gemeinsame Mount-Weitergabe auf Volumes zu setzen, wenn Sie "Docker Run" verwenden.
quelle
Ab Docker 17.06 können Sie NFS-Freigaben direkt beim Ausführen in den Container einbinden, ohne dass zusätzliche Funktionen erforderlich sind
Alternativ können Sie das Volume vor dem Container erstellen:
Ich habe den Hinweis von https://github.com/moby/moby/issues/28809 erhalten
quelle