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


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

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

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

À mon humble avis, qui a l'inconvénient, que je ne dois jamais (par accident) supprimer le conteneur "c0dbc34fd631".

Une autre idée serait de monter les volumes hôtes "-v" dans le conteneur, cependant, le identifiant d'utilisateur dans le conteneur ne correspond pas nécessairement à la identifiant d'utilisateur à partir de l'hôte, puis les autorisations peuvent être foiré.

Note: Au lieu de --volumes-from 'cryptic_id' vous pouvez aussi utiliser --volumes-from my-data-container où my-data-container est un nom que vous avez attribué à un conteneur de données uniquement, par ex. docker run --name my-data-container ... (voir la réponse acceptée)


837
2017-08-28 19:45


origine


Réponses:


Docker 1.9.0 et supérieur

Utilisation 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é en faveur des nouveaux volumes.

En fait, l'API de volume est seulement un meilleur moyen de réaliser ce qui était 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é pour vous:

  1. Être listé à travers le docker volume ls
  2. Être identifié à travers le docker volume inspect volume_name
  3. Sauvegardé comme un répertoire normal
  4. Soutenu comme avant à travers un --volumes-from connexion

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

docker volume ls -f dangling=true

Et puis supprimez-le par son nom:

docker volume rm <volume name>

Comme le souligne @mpugach dans les commentaires, vous pouvez vous débarrasser de tous les volumes qui pendent avec un joli doublage:

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 est d'utiliser un conteneur de données seulement.

Le conteneur de données uniquement est exécuté sur une image barebones et ne fait réellement rien sauf exposer un volume de données.

Vous pouvez ensuite exécuter tout 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 obtenir une bonne image de la façon d'organiser les différents conteneurs.
  • Ici il y a un bon aperçu du fonctionnement des volumes.

Dans ce blog il y a une bonne description de la soi-disant conteneur comme modèle de volume ce qui clarifie le point principal d'avoir conteneurs de données seulement.

La documentation Docker a maintenant la description DEFINITIVE de la récipient comme volume / s modèle.

Voici la procédure de sauvegarde / restauration pour Docker 1.8.x et ci-dessous.

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 courant dans le conteneur; écrire le fichier tar à
  • busybox: une petite image plus simple - bonne pour une maintenance rapide
  • tar cvf /backup/backup.tar / data: crée un fichier tar non compressé de tous les fichiers du répertoire / data

RESTAURER:

# 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 une belle article de l'excellent Brian Goff Expliquer pourquoi il est bon d'utiliser la même image pour un conteneur et un conteneur de données.


885
2017-12-18 07:50



Dans Docker version v1.0, la liaison d'un montage d'un fichier ou d'un répertoire sur la machine hôte peut être effectuée par la commande donnée:

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

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


58
2017-10-29 10:30



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

Voici l'annonce du blog: Composer 1.6: Nouveau fichier de composition pour la définition de réseaux et de 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 peux 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 vous devriez voir votre volume listé:

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"
  }
]

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

Remarques:

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

    volumes:
      db-data:
        driver: flocker
    
  • Comme ils améliorent l'intégration entre Docker Swarm et Docker Compose (et peut-être commencer à intégrer Flocker dans l'écosystème Docker (j'ai entendu une rumeur selon laquelle Docker a 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 dans la production pour l'instant!


23
2018-04-15 08:15



Dans le cas où cela ne ressort pas de la mise à jour 5 de la réponse sélectionnée, à partir de Docker 1.9, vous pouvez créer des volumes qui peuvent exister sans être associés à un conteneur spécifique, rendant le modèle "conteneur de données uniquement" obsolète.

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

Je pense que les mainteneurs de Docker ont réalisé que le modèle de conteneur de données uniquement était un peu une odeur de conception et ont décidé de faire des volumes une entité distincte qui peut exister sans conteneur associé.


15
2018-02-15 16:47



Bien que cela fasse toujours partie de Docker cela a besoin de travail, vous devriez mettre le volume dans le Dockerfile avec l'instruction VOLUME vous n'avez donc pas besoin de copier les volumes d'un autre conteneur.

Cela rendra vos conteneurs moins interdépendants et vous n'aurez pas à vous soucier de la suppression d'un conteneur affectant un autre.


11
2017-09-12 19:10



La réponse de @ tommasop est bonne, et explique certains des mécanismes d'utilisation des conteneurs de données uniquement. Mais comme quelqu'un qui pensait initialement que les conteneurs de données étaient stupides quand on pouvait simplement lier un volume à l'hôte (comme suggéré par plusieurs autres réponses), mais réalise maintenant qu'en fait les conteneurs de données seulement sont assez soignés, je peux suggérer mes propres article de blog sur ce sujet: Pourquoi les conteneurs de données Docker (Volumes!) Sont bons

Voir également: ma réponse À la question "Quelle est la meilleure façon de gérer les autorisations pour les volumes partagés Docker?"pour un exemple d'utilisation des conteneurs de données pour éviter les problèmes tels que les permissions 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 a une référence à ce volume, c'est-à-dire n'importe quel conteneur qui a monté le volume via --volumes-from. Donc, à moins que tous les conteneurs liés sont arrêtés et supprimés (on pourrait considérer cela comme l'équivalent d'un accident rm -fr /) les données sont sûres. Vous pouvez toujours recréer le conteneur de données en faisant --volumes-from tout conteneur ayant une référence à ce volume.

Comme toujours, faites des sauvegardes!

UPDATE: Docker a maintenant des volumes qui peuvent être gérés indépendamment des conteneurs, ce qui rend la gestion plus facile.


8
2017-11-21 15:32



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:

8
2018-01-31 09:27



Si vous voulez déplacer vos volumes, vous devriez aussi regarder Flocker.

À partir du fichier README:

Flocker est un gestionnaire de volume de données et un outil de gestion de cluster Docker multi-hôte. 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 sous Linux.

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


7
2018-04-02 11:58



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

  • Stockez-le sur votre hôte
    • Utilisez le drapeau -v host-path:container-path pour conserver les données du répertoire du conteneur dans un répertoire hôte.
    • Les sauvegardes / restaurations se produisent 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 dans votre conteneur d'applications
    • Créer un conteneur qui exporte un volume de données, utilisez --volumes-from pour monter ces données dans votre conteneur d'application.
    • Sauvegarder / restaurer le même que la solution ci-dessus.
  • Utiliser un plugin de volume Docker qui soutient 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 Propriétaire de ranch - le faire cuire et simple à utiliser.
    • Convoi est la solution la plus simple pour le faire manuellement.

5
2018-02-07 19:28



Cela dépend de votre scénario (ce n'est pas vraiment adapté à un environnement de production), mais voici un moyen:

Créer un conteneur MySQL Docker

Cette idée est d'utiliser un répertoire sur votre hôte pour la persistance des données.


4
2017-12-14 23:12



J'ai récemment écrit sur une solution potentielle et une application démontrant la technique. Je trouve que c'est très efficace pendant le développement et la production. J'espère que cela aide ou suscite des idées.

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


2
2018-04-02 12:29