1066 Stimmen

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

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

Derzeit verwende ich diesen Ansatz: Das Image erstellen, z.B. für PostgreSQL, und dann den Container starten mit

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

Meiner Meinung nach hat das den Nachteil, dass ich niemals (aus Versehen) den Container "c0dbc34fd631" löschen darf.

Eine weitere Idee wäre, Host-Volumes "-v" in den Container einzuhängen, jedoch stimmt die Benutzer-ID im Container nicht unbedingt mit der Benutzer-ID des Hosts überein, und dann könnten die Berechtigungen durcheinander geraten.

Anmerkung: Anstelle von --volumes-from 'kryptische_id' können Sie auch --volumes-from my-data-container verwenden, wobei my-data-container ein Name ist, den Sie einem reinen Datencontainer zugewiesen haben, z.B. docker run --name my-data-container ... (siehe die akzeptierte Antwort)

1016voto

tommasop Punkte 17995

Docker 1.9.0 und höher

Verwenden Sie Volume-API

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

Dies bedeutet, dass das Datencontainermuster zugunsten der neuen Volumes aufgegeben werden muss.

Tatsächlich ist die Volume-API nur eine bessere Möglichkeit, das zu erreichen, was das Datencontainermuster war.

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

  1. Kann über das docker volume ls aufgelistet werden
  2. Kann über das docker volume inspect volume_name identifiziert werden
  3. Als normales Verzeichnis gesichert werden
  4. Wie zuvor über eine --volumes-from-Verbindung gesichert werden

Das neue Volume-API fügt einen nützlichen Befehl hinzu, mit dem Sie hängende Volumes identifizieren können:

docker volume ls -f dangling=true

Und dann entfernen Sie es durch seinen Namen:

docker volume rm 

Wie @mpugach in den Kommentaren betont, können Sie alle hängenden Volumes mit einem schönen Einzeiler loswerden:

docker volume rm $(docker volume ls -f dangling=true -q)
# Oder unter Verwendung von 1.13.x
docker volume prune

Docker 1.8.x und darunter

Der Ansatz, der in der Produktion am besten zu funktionieren scheint, besteht darin, einen Datennur-Container zu verwenden.

Der Datennur-Container wird auf einem minimalen Image ausgeführt und tut tatsächlich nichts anderes, als ein Datenvolume freizugeben.

Dann können Sie einen beliebigen anderen Container ausführen, um auf die Datenvolumen des Datencontainers zuzugreifen:

docker run --volumes-from data-container some-other-container command-to-execute
  • Hier erhalten Sie eine gute Vorstellung davon, wie die verschiedenen Container angeordnet sind.
  • Hier gibt es einen guten Einblick, wie Volumes funktionieren.

In diesem Blog-Beitrag gibt es eine gute Beschreibung des sogenannten Container als Volumen-Musters, das den Hauptpunkt der Verwendung von Datennur-Containern klärt.

Die Docker-Dokumentation hat nun die DEFINITIVE Beschreibung des Container als Volumen/s-Musters.

Im Folgenden finden Sie das Backup/Wiederherstellungsverfahren für Docker 1.8.x und niedriger.

BACKUP:

sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
  • --rm: Entfernen Sie den Container beim Beenden
  • --volumes-from DATA: Anhängen an die von dem Datencontainer freigegebenen Volumes
  • -v $(pwd):/backup: Einbinden des aktuellen Verzeichnisses in den Container zum Schreiben der Tar-Datei
  • busybox: ein kleines einfacheres Image - gut für schnelle Wartungsarbeiten
  • tar cvf /backup/backup.tar /data: erstellt eine unkomprimierte Tar-Datei aller Dateien im /data-Verzeichnis

WIEDERHERSTELLUNG:

# Erstellen eines neuen Datencontainers
$ sudo docker run -v /data -name DATA2 busybox true
# entpacken der Backup-Dateien in das Datenvolumen des neuen Containers
$ sudo docker run --rm --volumes-from DATA2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
data/
data/sven.txt
# Vergleich mit dem Originalcontainer
$ sudo docker run --rm --volumes-from DATA -v `pwd`:/backup busybox ls /data
sven.txt

Hier ist ein interessanter Artikel von dem ausgezeichneten Brian Goff, der erklärt, warum es gut ist, dasselbe Image für einen Container und einen Datenspeichercontainer zu verwenden.

82voto

amitmula Punkte 1060

In Docker Version v1.0, kann das Binden eines Mounts einer Datei oder eines Verzeichnisses auf der Host-Maschine mit dem folgenden Befehl durchgeführt werden:

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

Der oben genannte Volume könnte als persistenten Speicher auf dem Host, auf dem Docker läuft, verwendet werden.

38voto

toast38coza Punkte 7911

Ab Docker Compose 1.6 gibt es nun eine verbesserte Unterstützung für Datenvolumes in Docker Compose. Die folgende Kompositionsdatei erstellt ein Datenträgerabbild, das zwischen Neustarts (oder sogar dem Entfernen) von übergeordneten Containern bestehen bleibt:

Hier ist die Blog-Ankündigung: Compose 1.6: Neue Kompositionsdatei zur Definition von Netzwerken und Volumes

Hier ist ein Beispiel für eine Kompositionsdatei:

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:

Soweit ich verstehe: Dies wird einen Daten-Volumen-Container (db_data) erstellen, der zwischen Neustarts bestehen bleibt.

Wenn Sie docker volume ls ausführen, sollte Ihr Volume aufgelistet werden:

local               mypthonapp_db-data
...

Sie können einige Details 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:

# Starten Sie die Container
docker-compose up -d

# .. geben Sie einige Daten in die Datenbank ein
docker-compose run --rm web python manage.py migrate
docker-compose run --rm web python manage.py createsuperuser
...

# Stoppen und entfernen Sie die Container:
docker-compose stop
docker-compose rm -f

# Starten Sie sie erneut
docker-compose up -d

# Überprüfen Sie, ob die Daten noch da sind
...
(sind sie)

# Stoppen und entfernen mit dem -v (Volumes) Tag:

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

# Wieder hochfahren ..
docker-compose up -d

# Überprüfen Sie, ob die Daten noch da sind:
...
(sind sie).

Anmerkungen:

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

    volumes:
      db-data:
        driver: flocker
  • Da sie die Integration zwischen 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 meiner Meinung nach immer leistungsstärker werden.

Haftungsausschluss: Dieser Ansatz ist vielversprechend, und ich verwende ihn erfolgreich in einer Entwicklungsumgebung. In der Produktion wäre ich jedoch noch zurückhaltend!

18voto

ben_frankly Punkte 8992

Falls es aus dem Update 5 der ausgewählten Antwort nicht klar wird, können Sie ab Docker 1.9 Volumes erstellen, die ohne eine spezifische Container-Assoziation existieren können, wodurch das "nur-Daten-Container"-Muster überflüssig wird.

Siehe Sind data-only Container mit Docker 1.9.0 überflüssig geworden? #17798.

Ich denke, die Docker-Verantwortlichen haben erkannt, dass das Muster des nur-Daten-Containers etwas unsauber war und beschlossen, Volumes zu einer separaten Entität zu machen, die ohne einen verbundenen Container existieren kann.

17voto

Czar Pino Punkte 6053

Wenn Sie Docker Compose verwenden, fügen Sie einfach ein benanntes Volume hinzu, zum Beispiel:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X