Docker Volumes: Eine Übersicht

Docker Volumes: Eine Übersicht

Docker Volumes: Eine Übersicht

Die grundlegende Motivation hinter der Entkopplung von Daten und Containern habe ich in der Zusammenfassung für Bind Mounts erklärt: Sämtliche Modifikationen, die ein Container am Dateisystem seines darunterliegenden Images vornimmt, existieren nur in dem jeweiligen Container und gehen zusammen mit dem Container verloren.

Wer Daten persistieren möchte, die von einem Container generiert wurden, muss diese Daten ins Dateisystem des Hosts auslagern. Der bevorzugte Weg hierfür sind Volumes.

Unterschiede und Vorteile gegenüber Bind Mounts

Im Gegensatz zu Bind Mounts legt der Benutzer bei Volumes kein Verzeichnis auf dem Host fest, das in den Container eingehängt werden soll. Stattdessen gibt er nur an, welches Verzeichnis auf dem Container er als Volume einbinden möchte. Die Daten dieses Volumes liegen dann in einem Bereich auf dem Host, der ausschließlich von Docker verwaltet wird.

volumes-konzept.png


Das offizielle PostgreSQL-Image speichert seine Daten im Verzeichnis /var/lib/postgres/data, welches hier als Volume eingebunden wird. Syntaktisch unterscheidet sich der entsprechende Befehl nur dadurch von einem Bind-Mount, dass das Host-Verzeichnis fehlt:

Bash:
$ docker container run -d --name database -v /var/lib/postgres/data postgres
Welche Vorteile bringt das gegenüber Bind Mounts?
  • Volumes können Namen erhalten und sind dadurch einfacher handhabbar
  • Mit Volumes muss sich der Benutzer nicht mit Speicherort und Implementierung auseinandersetzen
  • Volumes sind First-Class-Citizens in Docker und können über die CLI verwaltet werden
  • Volumes können unterschiedliche Treiber für unterschiedliche Speicherarten und -orte verwenden
  • Mehrere Container können auf ein Volume sicher zugreifen
  • Unter Berücksichtigung der eigenen Konfiguration werden Volumes vollständig von Docker verwaltet

Named Volumes erstellen

Im obigen Beispiel haben wir die PostgreSQL-Daten in ein eigenes Volume auslagert. Da wir keinen expliziten Namen für dieses Volume vergeben haben, handelt es sich um ein anonymes Volume. Es erhielt von Docker eine zufällig generierte ID als "Namen":

Bash:
$ docker volume ls
  DRIVER              VOLUME NAME
  local               21aef22affde3ed4ede8c0d66092f73240147099856688389256c05ddd311da8
Um besser mit Volumes arbeiten zu können, kann ein zusätzlicher Name für das Volume angegeben werden. Im Falle der -v-Option geschieht das, indem man einen beliebigen Namen vor den Dateipfad setzt:

Bash:
$ docker container run -d --name database -v pg-data:/var/lib/postgres/data postgres
In diesem Beispiel wird ein Named Volume mit dem Namen pg-data erstellt. Ein Volume kann aber auch unabhängig vom Start eines Containers erstellt werden:

Bash:
$ docker volume create pg-data
Dieser Befehl erlaubt auch die Angabe von verschiedenen Optionen, wie beispielsweise die Verwendung eines bestimmten Volume-Treibers. Mit docker volume rm pg-data kann das Volume später wieder gelöscht werden. Die Behandlung von Volumes als First-Class-Citizens - neben Images, Containern und Netzwerken - erleichtert die Verwaltung erheblich.

Warum --mount zu bevorzugen ist

Wem die Option -v pg-data:/var/lib/postgres/data bekannt vorkommt, hatte vermutlich bereits Kontakt zu Bind Mounts. Leider unterscheidet sich die Syntax eines Named Volumes durch einen Bind Mount ausschließlich dadurch, dass das erste Argument bei einem Bind Mount ein absoluter Pfad sein muss. Die Option -v $(pwd)/pg-data:/var/lib/postgres/data würde einen Bind Mount erstellen.

Um hier Verwirrung zu vermeiden, ist es sehr ratsam, auf die Option --mount mit ihrer selbsterklärenden Syntax zurückzugreifen. Als Nutzer muss man hier nicht darauf achten, ob das erste Argument ein absoluter Pfad oder ein Volume-Name ist. Stattdessen wird der Typ des Mounts explizit angegeben.

Bash:
$ docker container run -d \
  --name database \
  --mount type=volume,source=pg-data,destination=/var/lib/postgres/data \
  postgres
Als source wird hier einfach der Name des Volumes angegeben. Die explizite Typangabe macht die Natur des Mounts deutlich sichtbar.

Backups mit temporären Containern erstellen

Nur weil alle Volume-Daten ausschließlich von Docker verwaltet werden, bedeutet das nicht, dass wir nicht mit den Daten arbeiten können. Der Name eines Volumes bietet dem Nutzer einen Anhaltspunkt, um beispielsweise Backups dieser Daten zu erstellen.

Die Situation: Der PostgreSQL-Container database speichert seine Daten im Volume pg-data und wir möchten ein Backup im lokalen Verzeichnis db-backup erstellen. Ein geläufiges Pattern hierfür ist die Verwendung eines temporären Containers, der die Volumes vom PostgreSQL-Container einbindet und die Daten in das Zielverzeichnis kopiert.

Bash:
$ docker container run -d \
  --rm \
  --mount type=volume,source=pg-data,destination=/from \
  --mount type=bind,source=$(pwd)/db-backup,destination=/to \
  ubuntu \
  tar cvf /to/backup.tar /from
Dieser temporäre Container hängt das Volume an der Stelle /from ein und erstellt einen Bind Mount auf das lokale Backup-Verzeichnis. Für das Kopieren der Daten ins Backup-Verzeichnis ist der tar-Befehl am Ende verantwortlich.

Neben diesem Pattern gibt es zahlreiche weitere Möglichkeiten, mit Volumes zu arbeiten. Damit eignen sich Volumes hervorragend, um Verzeichnisse und Daten unabhängig vom Lebenszyklus eines Containers zu machen und bieten darüber hinaus auch die Möglichkeit, Daten auf einem anderen Host oder bei Cloud-Diensten wie AWS zu speichern.
  • Like
Reaktionen: JR Cologne und Mat
Autor
dominik
Aufrufe
76
Erstellt am
Letzte Bearbeitung
Bewertung
0,00 Stern(e) 0 Bewertung(en)

Weitere Ressourcen von dominik

Oben Unten