Einführung
Docker ist ein beliebtes Containerisierungstool, mit dem Softwareanwendungen ein Dateisystem erhalten, das alles enthält, was sie zum Ausführen benötigen. Durch die Verwendung von Docker-Containern wird sichergestellt, dass sich die Software unabhängig von ihrem Bereitstellungsort gleich verhält, da ihre Laufzeitumgebung konsistent ist.
Im Allgemeinen sind Docker-Container kurzlebig und werden nur so lange ausgeführt, wie der im Container ausgegebene Befehl ausgeführt wird. Manchmal müssen Anwendungen jedoch den Zugriff auf Daten freigeben oder Daten beibehalten, nachdem ein Container gelöscht wurde. Datenbanken, benutzergenerierte Inhalte für eine Website und Protokolldateien sind nur einige Beispiele für Daten, die in einem Docker-Image nicht oder nur unpraktisch enthalten sind, auf die Anwendungen jedoch zugreifen müssen. Der permanente Zugriff auf Daten wird über Docker Volumes bereitgestellt.
Docker-Volumes können mit demselben Befehl erstellt und angehängt werden, mit dem ein Container erstellt wird, oder sie können unabhängig von Containern erstellt und später angehängt werden. In diesem Artikel werden vier verschiedene Möglichkeiten für die gemeinsame Nutzung von Daten zwischen Containern beschrieben.
Voraussetzungen
Um diesem Artikel zu folgen, benötigen Sie einen Ubuntu 18.04-Server mit folgenden Eigenschaften:
-
Ein Benutzer ohne Rootberechtigung mit sudo-Berechtigungen. Das Handbuch Initial Server Setup with Ubuntu 18.04 erklärt, wie Sie dies einrichten.
-
Docker installiert mit den Anweisungen aus * Schritt 1 * und * Schritt 2 * von https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04 [ So installieren und verwenden Sie Docker unter Ubuntu 18.04]
Schritt 1 - Erstellen eines unabhängigen Volumes
Mit dem in Docker 1.9 eingeführten Befehl + docker volume create +
können Sie ein Volume erstellen, ohne es einem bestimmten Container zuzuordnen. Mit diesem Befehl fügen wir ein Volume mit dem Namen "+ DataVolume1 +" hinzu:
docker volume create --name DataVolume1
Der Name wird angezeigt und zeigt an, dass der Befehl erfolgreich war:
OutputDataVolume1
Um das Volume zu nutzen, erstellen wir einen neuen Container aus dem Ubuntu-Image und verwenden das Flag "+ - rm ", um es beim Beenden automatisch zu löschen. Wir werden auch " -v " verwenden, um das neue Volume bereitzustellen. ` -v +` erfordert den Namen des Volumes, einen Doppelpunkt und den absoluten Pfad zu der Stelle, an der das Volume im Container erscheinen soll. Wenn die Verzeichnisse im Pfad nicht als Teil des Images vorhanden sind, werden sie bei Ausführung des Befehls erstellt. Wenn sie do vorhanden sind, wird der vorhandene Inhalt auf dem bereitgestellten Volume ausgeblendet:
docker run -ti --rm -v DataVolume1:/datavolume1 ubuntu
Schreiben Sie im Container einige Daten auf das Volume:
echo "Example1" > /datavolume1/Example1.txt
Da wir das Flag "+ - rm +" verwendet haben, wird unser Container beim Verlassen automatisch gelöscht. Unser Band wird jedoch weiterhin zugänglich sein.
exit
Wir können überprüfen, ob das Volume auf unserem System vorhanden ist mit + docker volume inspect +
:
docker volume inspect DataVolume1
Output[
{
"CreatedAt": "2018-07-11T16:57:54Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/DataVolume1/_data",
"Name": "DataVolume1",
"Options": {},
"Scope": "local"
}
]
Beginnen wir als nächstes einen neuen Container und fügen "+ DataVolume1 +" hinzu:
docker run --rm -ti -v DataVolume1:/datavolume1 ubuntu
Überprüfen Sie den Inhalt:
cat /datavolume1/Example1.txt
OutputExample1
Verlasse den Container:
exit
In diesem Beispiel haben wir ein Volume erstellt, es an einen Container angehängt und dessen Persistenz überprüft.
Schritt 2 - Erstellen eines Volumes, das beim Entfernen des Containers erhalten bleibt
In unserem nächsten Beispiel erstellen wir ein Volume zur gleichen Zeit wie der Container, löschen den Container und hängen das Volume an einen neuen Container an.
Wir werden den Befehl + docker run +
verwenden, um einen neuen Container mit dem Ubuntu-Basis-Image zu erstellen. + -t +
gibt uns ein Terminal und + -i +
erlaubt uns, mit ihm zu interagieren. Der Übersichtlichkeit halber verwenden wir "+ - name +", um den Container zu identifizieren.
Mit dem Flag "+ -v " können wir ein neues Volume erstellen, das wir " DataVolume2 " nennen. Wir verwenden einen Doppelpunkt, um diesen Namen vom Pfad zu trennen, in dem das Volume im Container bereitgestellt werden soll. Schließlich geben wir das Basis-Ubuntu-Image an und verwenden den Standardbefehl in der Docker-Datei des https://github.com/dockerfile/ubuntu/blob/master/Dockerfile#L32[Ubuntu-Basis-Images], ` bash +`, bis Lass uns in eine Shell fallen:
docker run -ti --name=Container2 -v DataVolume2:/datavolume2 ubuntu
Im Container werden einige Daten auf das Volume geschrieben:
echo "Example2" > /datavolume2/Example2.txt
cat /datavolume2/Example2.txt
OutputExample2
Verlassen wir den Container:
exit
Wenn wir den Container neu starten, wird das Volume automatisch bereitgestellt:
docker start -ai Container2
Vergewissern wir uns, dass das Volume tatsächlich aktiviert wurde und unsere Daten noch vorhanden sind:
cat /datavolume2/Example2.txt
OutputExample2
Zum Schluss beenden wir und räumen auf:
exit
Docker lässt uns ein Volume nicht entfernen, wenn es von einem Container referenziert wird. Mal sehen, was passiert, wenn wir versuchen:
docker volume rm DataVolume2
Die Nachricht teilt uns mit, dass das Volume noch verwendet wird, und liefert die Langversion der Container-ID:
OutputError response from daemon: unable to remove volume: remove DataVolume2: volume is in use - []
Mit dieser ID können wir den Container entfernen:
docker rm
Outputd0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63
Das Entfernen des Containers hat keinen Einfluss auf das Volumen. Wir können sehen, dass es immer noch auf dem System vorhanden ist, indem wir die Volumes mit + docker volume ls +
auflisten:
docker volume ls
OutputDRIVER VOLUME NAME
local DataVolume2
Und wir können + docker volume rm +
verwenden, um es zu entfernen:
docker volume rm DataVolume2
In diesem Beispiel haben wir gleichzeitig mit dem Erstellen eines Containers ein leeres Datenvolumen erstellt. In unserem nächsten Beispiel werden wir untersuchen, was passiert, wenn wir ein Volume mit einem Containerverzeichnis erstellen, das bereits Daten enthält.
Schritt 3 - Erstellen eines Volumes aus einem vorhandenen Verzeichnis mit Daten
Im Allgemeinen ist das unabhängige Erstellen eines Volumes mit "+ docker volume create +" und das Erstellen eines Volumes beim Erstellen eines Containers mit einer Ausnahme äquivalent. Wenn wir ein Volume gleichzeitig mit dem Erstellen eines Containers erstellen und den Pfad zu einem Verzeichnis angeben, das Daten im Basisimage enthält, werden diese Daten in das Volume kopiert.
Als Beispiel erstellen wir einen Container und fügen das Datenvolumen unter "+ / var +" hinzu, einem Verzeichnis, das Daten im Basis-Image enthält:
docker run -ti --rm -v DataVolume3:/var ubuntu
Der gesamte Inhalt aus dem Basis-Image-Verzeichnis "+ / var" wird in das Volume kopiert, und wir können dieses Volume in einem neuen Container bereitstellen.
Verlasse den aktuellen Container:
exit
Dieses Mal verwenden wir nicht den Standardbefehl "+ bash " des Basis-Images, sondern geben unseren eigenen Befehl " ls +" aus, der den Inhalt des Volumes anzeigt, ohne die Shell aufzurufen:
docker run --rm -v DataVolume3:/datavolume3 ubuntu ls datavolume3
Das Verzeichnis "+ datavolume3 " enthält jetzt eine Kopie des Inhalts des " / var +" - Verzeichnisses des Basisimages:
Outputbackups
cache
lib
local
lock
log
mail
opt
run
spool
tmp
Es ist unwahrscheinlich, dass wir "+ / var / +" auf diese Weise mounten möchten. Dies kann jedoch hilfreich sein, wenn wir ein eigenes Image erstellt haben und auf einfache Weise Daten aufbewahren möchten. In unserem nächsten Beispiel zeigen wir, wie ein Volume von mehreren Containern gemeinsam genutzt werden kann.
Schritt 4 - Daten zwischen mehreren Docker-Containern austauschen
Bisher haben wir jeweils ein Volume an einen Container angehängt. Häufig möchten wir, dass mehrere Container an dasselbe Datenvolumen angehängt werden. Dies ist relativ einfach zu bewerkstelligen, aber es gibt eine wichtige Einschränkung: Derzeit behandelt Docker die Dateisperrung nicht. Wenn Sie mehrere Container benötigen, die auf das Volume schreiben, müssen die Anwendungen, die in diesen Containern ausgeführt werden, so konzipiert sein, dass sie in gemeinsam genutzte Datenspeicher schreiben, um eine Beschädigung der Daten zu verhindern.
Erstellen Sie Container4 und DataVolume4
Verwenden Sie "+ docker run ", um einen neuen Container mit dem Namen " Container4 +" und einem angehängten Datenvolumen zu erstellen:
docker run -ti --name=Container4 -v DataVolume4:/datavolume4 ubuntu
Als Nächstes erstellen wir eine Datei und fügen Text hinzu:
echo "This file is shared between containers" > /datavolume4/Example4.txt
Dann verlassen wir den Container:
exit
Dadurch kehren wir zur Host-Eingabeaufforderung zurück, in der wir einen neuen Container erstellen, der das Datenvolumen von "+ Container4 +" bereitstellt.
Erstellen Sie Container5 und hängen Sie Volumes von Container4 ein
Wir werden + Container5 +
erstellen und die Volumes von + Container4 +
mounten:
docker run -ti --name=Container5 --volumes-from Container4 ubuntu
Überprüfen wir die Datenpersistenz:
cat /datavolume4/Example4.txt
OutputThis file is shared between containers
Hängen wir nun einen Text aus "+ Container5 +" an:
echo "Both containers can write to DataVolume4" >> /datavolume4/Example4.txt
Zum Schluss verlassen wir den Container:
exit
Als nächstes prüfen wir, ob Ihre Daten in "+ Container 4" noch vorhanden sind.
In Container5 vorgenommene Änderungen anzeigen
Lassen Sie uns nach den Änderungen suchen, die von "+ Container5 " in das Datenvolumen geschrieben wurden, indem Sie " Container4 +" neu starten:
docker start -ai Container4
Überprüfen Sie die Änderungen:
cat /datavolume4/Example4.txt
OutputThis file is shared between containers
Both containers can write to DataVolume4
Nachdem wir überprüft haben, dass beide Container vom Datenvolumen lesen und schreiben konnten, verlassen wir den Container:
exit
Auch hier verarbeitet Docker keine Dateisperrung, daher müssen Anwendungen die Dateisperrung selbst berücksichtigen. Es ist möglich, ein Docker-Volume schreibgeschützt bereitzustellen, um sicherzustellen, dass keine Datenbeschädigung versehentlich auftritt, wenn ein Container schreibgeschützten Zugriff benötigt, indem Sie "+: ro +" hinzufügen. Schauen wir uns an, wie das funktioniert.
Starten Sie Container 6 und stellen Sie das Volume schreibgeschützt bereit
Nachdem ein Volume in einem Container bereitgestellt wurde, können Sie statt wie bei einem typischen Linux-Dateisystem einen neuen Container erstellen, der wie gewünscht bereitgestellt wird, und bei Bedarf den vorherigen Container entfernen. Um das Volume schreibgeschützt zu machen, fügen wir "+: ro +" an das Ende des Containernamens an:
docker run -ti --name=Container6 --volumes-from Container4:ro ubuntu
Wir überprüfen den schreibgeschützten Status, indem wir versuchen, unsere Beispieldatei zu entfernen:
rm /datavolume4/Example4.txt
Outputrm: cannot remove '/datavolume4/Example4.txt': Read-only file system
Schließlich verlassen wir den Container und bereinigen unsere Testcontainer und -volumina:
exit
Nun, da wir fertig sind, bereinigen wir unsere Container und unser Volumen:
docker rm Container4 Container5 Container6
docker volume rm DataVolume4
In diesem Beispiel wird gezeigt, wie Daten mithilfe eines Datenvolumes zwischen zwei Containern geteilt werden und wie ein Datenvolumen als schreibgeschützt bereitgestellt wird.
Fazit
In diesem Lernprogramm haben wir ein Datenvolumen erstellt, mit dem Daten auch nach dem Löschen eines Containers beibehalten werden können. Wir haben Datenvolumen zwischen Containern geteilt, mit dem Vorbehalt, dass Anwendungen für die Dateisperrung entwickelt werden müssen, um eine Beschädigung der Daten zu verhindern. Abschließend wurde gezeigt, wie ein freigegebenes Volume im schreibgeschützten Modus bereitgestellt wird. Wenn Sie mehr über den Datenaustausch zwischen Containern und dem Hostsystem erfahren möchten, lesen Sie https://www.digitalocean.com/community/tutorials/how-to-share-data-between-the-docker-container-and- the-host [So geben Sie Daten zwischen dem Docker-Container und dem Host frei].