Frage Wie man mit persistentem Speicher (z.B. Datenbanken) in Docker umgeht


Wie gehen Menschen mit persistentem Speicher für Ihre Docker-Container um?

Ich verwende derzeit diesen Ansatz: Erstelle das Bild, z.B. für PostgreSQL, und starten Sie den Container dann mit

docker run --volumes-from c0dbc34fd631 -d app_name/postgres

IMHO, das hat den Nachteil, dass ich niemals (zufällig) den Container "c0dbc34fd631" löschen darf.

Eine weitere Idee wäre, Host-Volumes "-v" in den Container einzubinden Benutzeridentifikation innerhalb des Containers muss nicht unbedingt übereinstimmen Benutzeridentifikation vom Host, und dann möglicherweise Berechtigungen vermurkst.

Hinweis: Statt --volumes-from 'cryptic_id' Sie können auch verwenden --volumes-from my-data-container woher my-data-container ist ein Name, den Sie einem reinen Datencontainer zugewiesen haben, z. docker run --name my-data-container ... (siehe die angenommene Antwort)


837
2017-08-28 19:45


Ursprung


Antworten:


Docker 1.9.0 und höher

Benutzen Datenträger-API

docker volume create --name hello
docker run -d -v hello:/container/path/for/volume container_image my_command

Dies bedeutet, dass das Nur-Daten-Container-Muster zugunsten der neuen Volumes aufgegeben werden muss.

Tatsächlich ist die Volumen-API nur ein besserer Weg, um das zu erreichen, was das Daten-Container-Muster war.

Wenn Sie einen Container mit einem erstellen -v volume_name:/container/fs/path Docker erstellt automatisch ein benanntes Volume für Sie, das:

  1. Durch die aufgelistet werden docker volume ls
  2. Identifiziert werden durch die docker volume inspect volume_name
  3. Als normales Verzeichnis gesichert
  4. Wie zuvor durch eine --volumes-from Verbindung

Die neue Datenträger-API fügt einen nützlichen Befehl hinzu, mit dem Sie dangelnde Datenträger identifizieren können:

docker volume ls -f dangling=true

Und dann entferne es durch seinen Namen:

docker volume rm <volume name>

Wie @mpugach in den Kommentaren hervorhebt, kannst du alle dangling Volumes mit einem schönen One-Liner loswerden:

docker volume rm $(docker volume ls -f dangling=true -q)
# Or using 1.13.x
docker volume prune

Docker 1.8.x und darunter

Der Ansatz, der am besten für die Produktion zu funktionieren scheint, ist die Verwendung eines Daten nur Container.

Der Daten-Only-Container wird auf einem Barebone-Image ausgeführt und tut nichts, außer dass ein Datenvolumen verfügbar gemacht wird.

Dann können Sie jeden anderen Container ausführen, um Zugriff auf die Datenträger des Datencontainers zu haben:

docker run --volumes-from data-container some-other-container command-to-execute
  • Hier Sie können sich ein gutes Bild davon machen, wie Sie die verschiedenen Behälter anordnen.
  • Hier Es gibt einen guten Einblick in die Funktionsweise von Volumes.

Im dieser Blogbeitrag Es gibt eine gute Beschreibung der sogenannten Behälter als Volumenmuster das verdeutlicht den Hauptpunkt des Habens Daten nur Container.

Docker Dokumentation hat jetzt die definitive Beschreibung der Behälter als Volumen / s Muster.

Im Folgenden wird das Sicherungs- / Wiederherstellungsverfahren für Docker 1.8.x und darunter beschrieben.

Sicherung:

sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
  • --rm: Entferne den Container, wenn er beendet wird
  • --volumes-from DATA: Anhängen an die vom DATA-Container freigegebenen Volumes
  • -v $ (pwd): / backup: bind hängt das aktuelle Verzeichnis in den Container ein; um die TAR-Datei zu schreiben
  • busybox: ein kleines, einfacheres Bild - gut für die schnelle Wartung
  • tar cvf /backup/backup.tar/data: erstellt eine unkomprimierte tar-Datei aller Dateien im Verzeichnis / data

WIEDERHERSTELLEN:

# Create a new data container
$ sudo docker run -v /data -name DATA2 busybox true
# untar the backup files into the new container᾿s data volume
$ sudo docker run --rm --volumes-from DATA2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
data/
data/sven.txt
# Compare to the original container
$ sudo docker run --rm --volumes-from DATA -v `pwd`:/backup busybox ls /data
sven.txt

Hier ist ein schönes Artikel vom ausgezeichneten Brian Goff zu erklären, warum es sinnvoll ist, dasselbe Bild für einen Container und einen Datencontainer zu verwenden.


885
2017-12-18 07:50



Im Docker Release v1.0Das Binden eines Mount einer Datei oder eines Verzeichnisses auf dem Hostcomputer kann mit dem angegebenen Befehl erfolgen:

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

Das obige Volume könnte als persistenter Speicher auf dem Host verwendet werden, auf dem Docker läuft.


58
2017-10-29 10:30



Ab Docker Compose 1.6 wurde die Unterstützung für Datenvolumen in Docker Compose verbessert. Die folgende Compose-Datei erstellt ein Datenabbild, das zwischen Neustarts (oder sogar Entfernen) von übergeordneten Containern bestehen bleibt:

Hier ist die Blog-Ankündigung: Verfassen von 1.6: New Compose-Datei zum Definieren von Netzwerken und Volumes

Hier ist ein Beispiel für eine Datei:

version: "2"

services:
  db:
    restart: on-failure:10
    image: postgres:9.4
    volumes:
      - "db-data:/var/lib/postgresql/data"
  web:
    restart: on-failure:10
    build: .
    command: gunicorn mypythonapp.wsgi:application -b :8000 --reload
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    links:
      - db

volumes:
  db-data:

So weit ich das verstehe: Dadurch wird ein Datenvolumen-Container erstellt (db_data) die zwischen den Neustarts bestehen bleiben.

Wenn du läufst: docker volume ls Sie sollten Ihr Volumen aufgelistet sehen:

local               mypthonapp_db-data
...

Sie können weitere Informationen zum Datenvolumen erhalten:

docker volume inspect mypthonapp_db-data
[
  {
    "Name": "mypthonapp_db-data",
    "Driver": "local",
    "Mountpoint": "/mnt/sda1/var/lib/docker/volumes/mypthonapp_db-data/_data"
  }
]

Einige Tests:

# Start the containers
docker-compose up -d

# .. input some data into the database
docker-compose run --rm web python manage.py migrate
docker-compose run --rm web python manage.py createsuperuser
...

# Stop and remove the containers:
docker-compose stop
docker-compose rm -f

# Start it back up again
docker-compose up -d

# Verify the data is still there
...
(it is)

# Stop and remove with the -v (volumes) tag:

docker-compose stop
docker=compose rm -f -v

# Up again ..
docker-compose up -d

# Check the data is still there:
...
(it is).

Anmerkungen:

  • Sie können im Treiber auch verschiedene Treiber angeben volumes Block. Zum Beispiel könnten Sie den Flocker-Treiber für db_data angeben:

    volumes:
      db-data:
        driver: flocker
    
  • Da sie die Integration von Docker Swarm und Docker Compose verbessern (und möglicherweise Flocker in das Docker-Ökosystem integrieren) (ich habe das Gerücht gehört, dass Docker Flocker gekauft hat), sollte dieser Ansatz immer stärker werden.

Haftungsausschluss: Dieser Ansatz ist vielversprechend und ich verwende ihn erfolgreich in einer Entwicklungsumgebung. Ich wäre besorgt, dies bereits in der Produktion zu verwenden!


23
2018-04-15 08:15



Wenn in Update 5 der ausgewählten Antwort nicht klar ist, wie in Docker 1.9, können Sie Volumes erstellen, die existieren können, ohne mit einem bestimmten Container verknüpft zu sein, wodurch das Muster "Nur-Daten-Container" obsolet wird.

Sehen Data-Only-Container mit Docker 1.9.0 veraltet? # 17798.

Ich denke, dass die Docker-Betreuer erkannt haben, dass das reine Data-Container-Muster ein Designgeruch ist, und beschlossen, Volumes zu einer separaten Entität zu machen, die ohne einen zugehörigen Container existieren kann.


15
2018-02-15 16:47



Während dies immer noch ein Teil von Docker ist das braucht etwas Arbeit, solltest du das Volume in die Dockerfile legen die VOLUME-Anweisung Sie müssen also die Volumes nicht aus einem anderen Container kopieren.

Dadurch werden Ihre Container weniger voneinander abhängig und Sie müssen sich nicht darum kümmern, dass ein Container einen anderen Container beeinträchtigt.


11
2017-09-12 19:10



@ Tommasops Antwort ist gut und erklärt einige der Mechanismen der Verwendung von Nur-Daten-Containern. Aber als jemand, der anfänglich dachten, dass Datencontainer albern wären, wenn man einfach einen Datenträger an den Host binden könnte (wie von mehreren anderen Antworten vorgeschlagen), aber jetzt merkt, dass Datencontainer ziemlich ordentlich sind, kann ich meinen eigenen vorschlagen Blogpost zu diesem Thema: Warum Docker Data Container (Volumes!) Sind gut

Siehe auch: meine Antwort zur Frage "Was ist die (beste) Möglichkeit, Berechtigungen für freigegebene Docker-Volumes zu verwalten?"Für ein Beispiel, wie Datencontainer verwendet werden, um Probleme wie Berechtigungen und die UID / GID-Zuordnung mit dem Host zu vermeiden.

Um eines der ursprünglichen Anliegen des OP zu adressieren: Der Datencontainer darf nicht gelöscht werden. Selbst wenn der Datencontainer gelöscht wird, gehen die Daten selbst nicht verloren, solange ein Container einen Verweis auf dieses Volumen hat, d. H. Einen Container, über den das Volumen eingehängt wurde --volumes-from. Es sei denn, alle verwandten Container werden gestoppt und gelöscht (man könnte dies als das Äquivalent eines Zufalls betrachten) rm -fr /) die Daten sind sicher. Sie können den Datencontainer jederzeit neu erstellen --volumes-from jeder Container, der einen Verweis auf dieses Volume hat.

Machen Sie wie immer Backups!

UPDATE: Docker verfügt jetzt über Volumes, die unabhängig von Containern verwaltet werden können, was die Verwaltung vereinfacht.


8
2017-11-21 15:32



Wenn Sie Docker Compose verwenden, hängen Sie einfach ein benanntes Volume an, z. B.

version: '2'
services:
  db:
    image: mysql:5.6
    volumes:
      - db_data:/var/lib/mysql:rw
    environment:
      MYSQL_ROOT_PASSWORD: root
volumes:
  db_data:

8
2018-01-31 09:27



Wenn Sie Ihre Volumes verschieben möchten, sollten Sie sich das auch ansehen Flocker.

Aus der README:

Flocker ist ein Daten-Volume-Manager und ein Multi-Host-Docker-Cluster-Management-Tool. Damit können Sie Ihre Daten mit den gleichen Tools steuern, die Sie für Ihre zustandslosen Anwendungen verwenden, indem Sie die Leistungsfähigkeit von ZFS unter Linux nutzen.

Dies bedeutet, dass Sie Ihre Datenbanken, Warteschlangen und Schlüsselwertspeicher in Docker ausführen und sie so einfach wie den Rest Ihrer Anwendung verschieben können.


7
2018-04-02 11:58



Je nach Ihren Anforderungen gibt es mehrere Ebenen für die Verwaltung persistenter Daten:

  • Speichern Sie es auf Ihrem Host
    • Verwende die Flagge -v host-path:container-path Containerverzeichnisdaten in einem Hostverzeichnis beibehalten.
    • Sicherungen / Wiederherstellungen erfolgen durch Ausführen eines Sicherungs- / Wiederherstellungscontainers (z. B. tutumcloud / dockup), der im selben Verzeichnis bereitgestellt wird.
  • Erstellen Sie einen Datencontainer und stellen Sie seine Datenträger in Ihrem Anwendungscontainer bereit
    • Erstellen Sie einen Container, der ein Datenvolumen exportiert, verwenden Sie --volumes-from um diese Daten in Ihren Anwendungscontainer zu laden.
    • Sichern / Wiederherstellen der gleichen wie die obige Lösung.
  • Verwenden Sie ein Docker-Volume-Plug-in, das einen externen / Drittanbieter-Dienst unterstützt
    • Docker-Volume-Plugins ermöglichen es Ihrer Datenquelle, von überall her zu kommen - NFS, AWS (S3, EFS und EBS)
    • Je nach Plugin / Dienst können Sie einzelne oder mehrere Container an ein einzelnes Volume anhängen.
    • Je nach Service können Backups / Restores für Sie automatisiert werden.
    • Obwohl dies manuell mühsam sein kann, sind einige Orchestrierungslösungen - wie z Rancher - es gebacken und einfach zu bedienen.
    • Konvoi ist die einfachste Lösung, um dies manuell zu tun.

5
2018-02-07 19:28