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-container
où my-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)
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:
docker volume ls
docker volume inspect volume_name
--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
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
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 .
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
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.
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.
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
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!
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é.
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.
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:
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.
Il existe plusieurs niveaux de gestion des données persistantes, en fonction de vos besoins:
-v Host-path:container-path
pour conserver les données du répertoire du conteneur dans un répertoire de l'hôte.--volumes-from
pour monter ces données dans votre conteneur d'application.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.
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.
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 /
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/
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:
"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é."
Utilisez les revendications de volume persistant (PVC) de Kubernetes, un outil de gestion et de planification de conteneurs Docker:
L'utilisation de Kubernetes à cette fin présente les avantages suivants: