Bien que Docker soit un outil utile pour empaqueter et gérer des applications, il présente également de nombreux défis uniques, tels que le traitement des données stockées. Habituellement, vous ajoutez des volumes aux conteneurs dans le script de création, mais que se passe-t-il si vous devez en créer de nouveaux ?
Ajout d'un volume à un conteneur Docker en cours d'exécution
Malheureusement, ce n'est pas aussi simple que d'ajouter un nouveau volume. Les conteneurs doivent avoir leurs volumes configurés au démarrage, ce qui signifie que pour ajouter un nouveau volume, vous devez redémarrer le conteneur. Bien qu'il existe une solution de piratage (plus d'informations ci-dessous), il est fortement recommandé de redémarrer le conteneur de toute façon.
C'est pour plusieurs raisons. Le redémarrage du conteneur est assez simple et la plupart des mises à jour de code nécessitent de toute façon un redémarrage du service. Le suivi des mises à jour dans Git est un autre facteur important, en particulier si vous utilisez Docker Compose, et la modification du script de lancement est bien meilleure que l'ajout manuel du volume à un conteneur en cours d'exécution.
Si votre service est suffisamment important pour que vous vous inquiétiez de quelques minutes (au plus) de temps d'arrêt planifié potentiel pour redémarrer le conteneur, vous devriez probablement exécuter un déploiement de mise à l'échelle avec plusieurs instances qui peuvent être mises à jour indépendamment. Les systèmes modernes de mise à l'échelle automatique doivent être conçus pour gérer cela, car les déploiements de code se produisent souvent.
Si vous souhaitez ajouter un volume, vous devez arrêter le conteneur en cours d'exécution :
docker stop my_container
Créez un nouveau volume si vous devez :
docker volume create nginx-config
Et puis exécutez-le avec une commande de lancement mise à jour, en ajoutant le --mount
drapeau pour configurer le volume source et la destination cible.
docker run -d --name devtest --mount source=nginx-config,target=/etc/nginx nginx:latest
Si vous utilisez Docker Compose, vous pouvez automatiser et suivre ce processus plus facilement, car la configuration du volume est gérée via un fichier de paramètres. vous devrez ajouter le volume au docker-compose.yml
fichier :
version: "3.0" services: web: image: nginx:latest ports: - "80:80" volumes: - /docker/nginx-config/:/etc/nginx/
Ensuite, vous pouvez redémarrer les services de Docker Compose. Compose a une commande "redémarrer", mais il s'agit en fait de simplement actualiser le service en cours d'exécution sans aucun changement de configuration. Si vous souhaitez mettre à jour les images, vous devrez exécuter docker-compose up
avec le --build
drapeau :
docker-compose up -d --build
Vous pouvez également exécuter manuellement docker-compose down
au préalable pour arrêter les services, mais ce n'est pas nécessaire dans la plupart des cas, sauf si vous souhaitez l'exécuter avec le -v
flag pour détruire les volumes existants.
CONNEXE : Qu'est-ce que Docker Compose et comment l'utiliser ?
Clonage à partir d'un conteneur existant
Dans presque tous les cas, vous ne devriez pas dépendre de l'état d'exécution actuel d'un conteneur. Tout ce qui vous intéresse, comme les données d'application, doit être stocké dans un volume afin qu'il puisse être conservé lors des redémarrages et des reconstructions du conteneur.
Cette méthode n'est probablement pas une bonne idée pour la plupart des gens, car elle vous oblige à créer une nouvelle image à chaque fois que vous voulez le faire, et cela nécessite toujours des temps d'arrêt. Mais, si vous avez besoin d'ajouter un volume à un conteneur en cours d'exécution, vous pouvez utiliser docker commit
pour créer une nouvelle image basée sur ce conteneur, puis la cloner avec le nouveau volume.
Récupérez l'ID du conteneur à partir de docker ps
:
docker ps
Et ensuite, clonez-le avec commit
:
docker commit f88f33c918d2 imagename
Ensuite, vous pouvez exécuter la nouvelle image, en remplaçant l'ancienne image par celle clonée.
docker run -d --name devtest --mount source=nginx-config,target=/etc/nginx imagename
La solution Hacky
Les volumes Docker ne sont en réalité qu'une supercherie que le runtime Docker utilise pour exposer les répertoires hôtes aux conteneurs, et tout dépend de la configuration. Pour cette raison, vous pouvez en fait modifier directement cette configuration et redémarrer l'intégralité du démon Docker pour que votre système applique ces modifications sans redémarrer du tout.
Bien sûr, c'est beaucoup plus compliqué que de simplement gérer un redémarrage de conteneur, donc si vous pouvez gérer une minute d'indisponibilité, nous vous recommandons vivement de le faire à la place.
Vous devrez accéder au répertoire de stockage de Docker :
cd /var/lib/docker/containers
Il y aura ici de nombreux dossiers correspondant aux ID de conteneur Docker, que vous pouvez trouver avec docker ps
. Ouvrez celui du conteneur que vous souhaitez modifier.
Le fichier de configuration est config.v2.json
, mais il est dans un format compact et difficile à modifier. Vous pouvez installer jq
pour joli-imprimer JSON sur la ligne de commande, et dirigez-le vers un nouveau fichier pour l'éditer :
jq . config.v2.json > tmp.json
Vous devrez faire défiler vers le bas pour trouver "MountPoints", qui contient la configuration de tous les volumes et des montages de liaison. Vous pouvez en ajouter un nouveau ici, qui devrait être au format suivant :
"MountPoints": { "/home/container": { "Source": "/var/lib/pterodactyl/volumes/c7fb3a04-e540-48a7-9704-13987f52e933", "Destination": "/home/container", "RW": true, "Name": "", "Driver": "", "Type": "bind", "Propagation": "rprivate", "Spec": { "Type": "bind", "Source": "/var/lib/pterodactyl/volumes/c7fb3a04-e540-48a7-9704-13987f52e933", "Target": "/home/container" }, "SkipMountpointCreation": true } },
Ensuite, une fois que c'est fait, vous pouvez à nouveau minifier le JSON dans le fichier de configuration :
jq -c . tmp.json > config.v2.json
jq
est un utilitaire puissant, donc si vous vouliez automatiser entièrement ce processus, vous pourriez le faire.
CONNEXE : Comment utiliser JSON sur la ligne de commande
Ensuite, redémarrez simplement le service Docker pour appliquer les modifications :
sudo service docker restart