web-dev-qa-db-fra.com

Comment gérer le stockage persistant (par exemple, les bases de données) dans Docker

Comment les gens gèrent-ils le stockage persistant de vos conteneurs Docker?

J'utilise actuellement cette approche: construire l'image, par exemple. pour PostgreSQL, puis démarrez le conteneur avec

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

IMHO, cela a l'inconvénient, que je ne dois jamais (par accident) supprimer le conteneur "c0dbc34fd631".

Une autre idée serait de monter les volumes de l'hôte "-v" dans le conteneur. Toutefois, le serid du conteneur ne correspond pas nécessairement à serid de l'hôte, puis les autorisations. pourrait être foiré.

Remarque: au lieu de --volumes-from 'cryptic_id', vous pouvez également utiliser --volumes-from my-data-containermy-data-container est un nom que vous avez attribué à un conteneur contenant uniquement des données, par exemple. docker run --name my-data-container ... (voir la réponse acceptée)

951
juwalter

Docker 1.9.0 et au-dessus

Utilisez API de volume

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

Cela signifie que le modèle de conteneur de données uniquement doit être abandonné au profit des nouveaux volumes.

En réalité, l’API de volume n’est qu’un meilleur moyen de réaliser le modèle de conteneur de données.

Si vous créez un conteneur avec un -v volume_name:/container/fs/path, Docker créera automatiquement un volume nommé qui pourra:

  1. Être répertorié via le docker volume ls
  2. Être identifié par le docker volume inspect volume_name
  3. Sauvegardé en tant que répertoire normal
  4. Sauvegardé comme auparavant via une connexion --volumes-from

La nouvelle API de volume ajoute une commande utile qui vous permet d'identifier les volumes en suspens:

docker volume ls -f dangling=true

Et puis supprimez-le par son nom:

docker volume rm <volume name>

Comme @mpugach le souligne dans les commentaires, vous pouvez vous débarrasser de tous les volumes suspendus avec un Nice one-liner:

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

Docker 1.8.x et ci-dessous

L’approche qui semble fonctionner le mieux pour la production consiste à utiliser un conteneur contenant uniquement des données .

Le conteneur de données uniquement est exécuté sur une image barebone et ne fait rien d'autre que d'exposer un volume de données.

Ensuite, vous pouvez exécuter n'importe quel autre conteneur pour accéder aux volumes du conteneur de données:

docker run --volumes-from data-container some-other-container command-to-execute
  • Ici vous pouvez avoir une bonne idée de la manière d’organiser les différents conteneurs.
  • Ici il existe un bon aperçu du fonctionnement des volumes.

Dans cet article de blog , il existe une bonne description du conteneur dit en tant que modèle de volume , qui clarifie le point essentiel de contenant uniquement des données .

La documentation de Docker contient maintenant la description DEFINITIVE du conteneur sous la forme volume/s .

Voici la procédure de sauvegarde/restauration pour Docker 1.8.x et inférieur.

SAUVEGARDE:

Sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
  • --rm: enlève le conteneur quand il sort
  • --volumes-from DATA: attache aux volumes partagés par le conteneur DATA
  • -v $ (pwd):/backup: bind monte le répertoire actuel dans le conteneur; écrire le fichier tar dans
  • busybox: une petite image plus simple - utile pour un entretien rapide
  • tar cvf /backup/backup.tar/data: crée un fichier tar non compressé contenant tous les fichiers du répertoire/data

RESTORE:

# 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

Voici un Nice article de l'excellent Brian Goff expliquant pourquoi il est bon d'utiliser la même image pour un conteneur et un conteneur de données.

959
tommasop

Dans version Docker v1., la liaison du montage d'un fichier ou d'un répertoire sur la machine hôte peut être effectuée à l'aide de la commande suivante:

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

Le volume ci-dessus peut être utilisé comme stockage persistant sur l'hôte exécutant Docker.

70
amitmula

Depuis Docker Compose 1.6, la prise en charge des volumes de données dans Docker Compose est améliorée. Le fichier de composition suivant créera une image de données qui persistera entre les redémarrages (voire la suppression) des conteneurs parents:

Voici l'annonce du blog: Compose 1.6: Nouveau fichier Compose permettant de définir les réseaux et les volumes

Voici un exemple de fichier de composition:

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:

Autant que je puisse comprendre: Cela créera un conteneur de volume de données (db_data) qui persistera entre les redémarrages.

Si vous exécutez: docker volume ls, votre volume devrait apparaître:

local               mypthonapp_db-data
...

Vous pouvez obtenir plus de détails sur le volume de données:

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

Quelques 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).

Notes:

  • Vous pouvez également spécifier divers pilotes dans le bloc volumes. Par exemple, vous pouvez spécifier le pilote Flocker pour db_data:

    volumes:
      db-data:
        driver: flocker
    
  • À mesure qu'ils améliorent l'intégration entre Docker Swarm et Docker Compose (et éventuellement l'intégration de Flocker dans l'éco-système Docker (j'ai entendu dire que Docker aurait acheté Flocker), je pense que cette approche devrait devenir de plus en plus puissante.

Avertissement: Cette approche est prometteuse et je l'utilise avec succès dans un environnement de développement. Je serais inquiet de l'utiliser pour la production pour l'instant!

31
toast38coza

Si la mise à jour 5 de la réponse sélectionnée n’est pas claire, à partir de Docker 1.9, vous pouvez créer des volumes qui peuvent exister sans être associés à un conteneur spécifique, rendant ainsi le modèle de "conteneur réservé aux données" obsolète.

Voir conteneurs de données uniquement obsolètes avec docker 1.9.0? # 17798.

Je pense que les responsables de Docker ont compris que le modèle de conteneur de données uniquement était un peu une odeur de conception et ont décidé de transformer les volumes en une entité distincte pouvant exister sans conteneur associé.

17
ben_frankly

Bien que cela fasse toujours partie de Docker qui nécessite un peu de travail , vous devez placer le volume dans le fichier Docker avec l'instruction VOLUME , de sorte que vous n'avez pas besoin de copier les volumes de un autre conteneur.

Cela rendra vos conteneurs moins interdépendants et vous n’aurez plus à vous soucier de la suppression d’un conteneur qui en affecte un autre.

13
Tim Dorr

Lorsque vous utilisez Docker Compose, attachez simplement un volume nommé, par exemple,

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

La réponse de @ tommasop est bonne et explique certains des mécanismes de l'utilisation de conteneurs de données uniquement. Mais comme quelqu'un qui pensait au départ que les conteneurs de données étaient idiots quand on pouvait simplement lier un volume à l'hôte (comme suggéré par plusieurs autres réponses), se rend compte maintenant qu'en fait les conteneurs contenant uniquement des données sont plutôt bien, je peux suggérer le mien. article de blog sur ce sujet: Pourquoi les conteneurs de données Docker (les volumes!) sont-ils bons

Voir aussi: ma réponse à la question " Quel est le meilleur moyen de gérer les autorisations pour les volumes partagés Docker? " pour un exemple d'utilisation des conteneurs de données à éviter des problèmes tels que les autorisations et le mappage uid/gid avec l'hôte.

Pour répondre à l'une des préoccupations initiales du PO: le conteneur de données ne doit pas être supprimé. Même si le conteneur de données est supprimé, les données elles-mêmes ne seront pas perdues tant qu'un conteneur contient une référence à ce volume, c'est-à-dire tout conteneur ayant monté le volume via --volumes-from. Donc, à moins que tous les conteneurs associés ne soient arrêtés et supprimés (on pourrait considérer cela comme l'équivalent d'un rm -fr / accidentel _), les données sont en sécurité. Vous pouvez toujours recréer le conteneur de données en effectuant --volumes-from tout conteneur contenant une référence à ce volume.

Comme toujours, faites des sauvegardes!

MISE À JOUR: Docker a maintenant des volumes qui peuvent être gérés indépendamment des conteneurs, ce qui facilite encore la gestion.

9
Raman

Il existe plusieurs niveaux de gestion des données persistantes, en fonction de vos besoins:

  • Stockez-le sur votre hôte
    • Utilisez l'indicateur -v Host-path:container-path pour conserver les données du répertoire du conteneur dans un répertoire de l'hôte.
    • Les sauvegardes/restaurations se font en exécutant un conteneur de sauvegarde/restauration (tel que tutumcloud/dockup) monté dans le même répertoire.
  • Créez un conteneur de données et montez ses volumes sur votre conteneur d'applications
    • Créez un conteneur qui exporte un volume de données, utilisez --volumes-from pour monter ces données dans votre conteneur d'application.
    • Sauvegarde/restauration identique à la solution ci-dessus.
  • Utilisez un plug-in de volume Docker qui sauvegarde un service externe/tiers
    • Les plugins de volume Docker permettent à votre source de données de venir de n'importe où: NFS, AWS (S3, EFS et EBS).
    • Selon le plugin/service, vous pouvez attacher un ou plusieurs conteneurs à un seul volume.
    • Selon le service, les sauvegardes/restaurations peuvent être automatisées pour vous.
    • Bien que cela puisse être fastidieux à faire manuellement, certaines solutions d’orchestration - telles que Rancher - l’intègrent et sont simples à utiliser.
    • Convoy est la solution la plus simple pour le faire manuellement.
9
Will Stern

Si vous souhaitez déplacer vos volumes, vous devez également consulter Flocker.

Du README:

Flocker est un gestionnaire de volume de données et un outil de gestion de grappes multi-hôtes Docker. Avec lui, vous pouvez contrôler vos données en utilisant les mêmes outils que vous utilisez pour vos applications sans état en exploitant la puissance de ZFS sur Linux.

Cela signifie que vous pouvez exécuter vos bases de données, files d'attente et magasins de valeurs-clés dans Docker et les déplacer aussi facilement que le reste de votre application.

8
Johann Romefort

Cela dépend de votre scénario (cela ne convient pas vraiment à un environnement de production), mais voici un moyen:

Création d'un conteneur MySQL Docker

En résumé, l’utilisation d’un répertoire sur votre hôte pour la persistance des données.

5
ben schwartz

J'ai récemment écrit sur une solution potentielle et une application démontrant la technique. Je trouve cela assez efficace lors du développement et de la production. J'espère que cela aidera ou suscitera quelques idées.

Repo: https://github.com/LevInteractive/docker-nodejs-example
Article: http://lev-interactive.com/2015/03/30/docker-load-balanced -mongodb-persistence /

3
slth

J'utilise simplement un répertoire prédéfini sur l'hôte pour conserver les données pour PostgreSQL. En outre, il est également possible de migrer les installations PostgreSQL existantes vers les conteneurs Docker: https://crondev.com/persistent-postgresql-inside-docker/

1
Alen Komljen

Ma solution consiste à utiliser le nouveau docker cp, qui permet désormais de copier des données à partir de conteneurs, qu'il soit actif ou non, et de partager un volume hôte au même emplacement où l'application de base de données crée ses fichiers. fichiers de base de données à l'intérieur du conteneur. Cette double solution fonctionne sans conteneur contenant uniquement des données, directement à partir du conteneur de base de données d'origine.

Donc, mon script d'initialisation systemd prend le travail de sauvegarde de la base de données dans une archive sur l'hôte. J'ai placé un horodatage dans le nom du fichier pour ne jamais réécrire un fichier.

Il le fait sur le ExecStartPre:

ExecStartPre=-/usr/bin/docker cp lanti-debian-mariadb:/var/lib/mysql /home/core/sql
ExecStartPre=-/bin/bash -c '/usr/bin/tar -zcvf /home/core/sql/sqlbackup_$$(date +%%Y-%%m-%%d_%%H-%%M-%%S)_ExecStartPre.tar.gz /home/core/sql/mysql --remove-files'

Et il fait la même chose sur ExecStopPost:

ExecStopPost=-/usr/bin/docker cp lanti-debian-mariadb:/var/lib/mysql /home/core/sql
ExecStopPost=-/bin/bash -c 'tar -zcvf /home/core/sql/sqlbackup_$$(date +%%Y-%%m-%%d_%%H-%%M-%%S)_ExecStopPost.tar.gz /home/core/sql/mysql --remove-files'

De plus, j'ai exposé un dossier de l'hôte en tant que volume au même emplacement exact où la base de données est stockée:

mariadb:
  build: ./mariadb
  volumes:
    - $HOME/server/mysql/:/var/lib/mysql/:rw

Cela fonctionne très bien sur mon VM (je construis une pile LEMP pour moi-même): https://github.com/DJviolin/LEMP

Mais je ne sais tout simplement pas s’il s’agit d’une solution "à toute épreuve" lorsque votre vie en dépend réellement (par exemple, une boutique en ligne avec des transactions en moins de mille secondes)?

À 20 minutes 20 secondes de cette vidéo officielle du discours principal de Docker, le présentateur fait la même chose avec la base de données:

Premiers pas avec Docker

"Pour la base de données, nous avons un volume. Ainsi, nous pouvons nous assurer que, lorsque la base de données ne cesse de monter et de descendre, nous ne perdons pas de données lorsque le conteneur de la base de données est arrêté."

0
Lanti

Utilisez les revendications de volume persistant (PVC) de Kubernetes, un outil de gestion et de planification de conteneurs Docker:

Volumes persistants

L'utilisation de Kubernetes à cette fin présente les avantages suivants:

  • Vous pouvez utiliser n'importe quel stockage tel que NFS ou un autre stockage. Même lorsque le nœud est en panne, le stockage n'est pas nécessaire.
  • De plus, les données contenues dans ces volumes peuvent être configurées pour être conservées même après la destruction du conteneur lui-même, afin de pouvoir être récupérées, si nécessaire, par un autre conteneur.
0
Santanu Dey