Lorsqu'on utilise docker pour déployer une application, la routine de maintenance des machines hébergeant les containers doit inclure un ramasse-miette dont la tâche est de se débarrasser des images obsolètes devenues inutiles. Si cet aspect de la maintenance est ignoré, en fonction de la fréquence des déploiements, de la taille des images et de l'espace disque disponible, le disque peut se remplir en quelques semaines voire en quelques heures.
Pour résoudre ce problème une bonne fois pour toutes, j'ai écrit un ramasse-miette très flexible pour docker. La procédure suit deux étapes. Dans la première, les containers qui ne sont pas marqués running sont effacés ; dans la seconde une règle de nettoyage est appliquée pour déterminer quelles images présentes dans la bibliothèque locale sont obsolètes et doivent être effacées. Les règles de nettoyage associent des prédicats sur les images à des actions, et peuvent être librement fixées. Il est facile d'inscrire le ramasse-miette dans le crontab(5) ou bien de le lancer avant les procédures préparant les nouvelles images.
Règles de nettoyage
Voici un exemple de règles de nettoyage, à inscrire dans le fichier ~/.docker/docker_gc.conf
:
Dandling : Delete
Not(Age(3)) : PreserveAll
Repository("organisation/repo") : PreserveRecent(3)
True : Delete
elles demandent:
- L'effacement toutes les images feuilles qui ne sont pas associées à un repository.
- La préservation de toutes les images crées il y a moins de trois jours.
- La préservation d'au plus 3 images dans le repository
organisation/repo
— les images préservées par la règle précédente participent au comptage. - L'effacement de toutes les autres images.
Les prédicats (membres de gauche dans le fichier de configuration ci-dessus) peuvent-être combinés arbitrairement à l'aide des connecteurs Or
et And
.
Utilisation dans le crontab
J'utilise ce programme en production sur des clusters dédiés au déploiement avec docker, en déclenchant le ramasse-miette toutes les heures:
CAML_LD_LIBRARY_PATH=/opt/opam/system/lib/stublibs:/usr/lib64/ocaml/stublibs
12 * * * * docker-user env HOME=/home/docker-user /opt/local/bin/docker_gc -v >> /opt/local/var/log/docker_gc.log 2>&1
(La ligne CAML_LD_LIBRARY_PATH
doit diriger vers le dossier approprié de votre installation opam.)
Utilisation dans la production des images
Le ramasse-miette n'interagit pas bien avec la production d'images. Sur les serveurs dédiés à la préparation des images, il est facile et préférable d'intégrer le ramasse-miette comme préliminaire à la procédure de production des images.
Installation
Pour installer, le plus simple est d'utiliser opam. Comme quelques PRs sont en retard, il faut installer les paquets lemonade, rashell, gasoline, à partir du repository, la petite boucle shell suivante automatise tout cela:
for repo in lemonade rashell gasoline dockertk; do
git clone "https://github.com/michipili/${repo}" "${repo}"
(cd "${repo}" && autoconf)
opam pin add "${repo}" "${repo}"
done
# Plus on est de fous ;-)
Posté par Mimoza . Évalué à 5.
fous => fois
[^] # Re: Plus on est de fous ;-)
Posté par Michaël (site web personnel) . Évalué à 3.
Ça m'étonnerait bien que ce soit la seule faute d'orthographe! :D Merci!
[^] # Re: Plus on est de fous ;-)
Posté par Benoît Sibaud (site web personnel) . Évalué à 4.
Corrigé, merci.
# Alternative de chez Spotify
Posté par Adrien BUSTANY (site web personnel) . Évalué à 4.
Pas essayé, et apparemment moins flexible que ta solution: https://github.com/spotify/docker-gc
[^] # Re: Alternative de chez Spotify
Posté par Michaël (site web personnel) . Évalué à 6.
Oui, j'aurais dû mentionner leur travail, qui est à ma connaissance le seul programme remplissant cette tâche. C'est un script shell, qui a donc l'avantage de la portabilité et de la facilité de déploiement, mais rend la généralisation de la tâche particulièrement ardue. J'ai donc écrit un autre ramasse miette, qui est un chouette petit projet de ouiquende! :)
# Mesos comme ramasse-miette
Posté par Tangi Colin . Évalué à 3.
J'utilise Mesos pour gérer mon déploiement de containeurs docker, il s'occupe alors lui même de supprimer les containers qui ne sont plus utilisés (voir l'option --docker_remove_delay).
[^] # Re: Mesos comme ramasse-miette
Posté par Narmer . Évalué à -2.
ça fait pas un peu j'utilise un tank pour mettre une punaise « Mesos comme ramasse-miette » ?
[^] # Re: Mesos comme ramasse-miette
Posté par Sufflope (site web personnel) . Évalué à 7.
S'il utilise déjà Mesos pour des raisons qui le regardent, et que Mesos peut le faire, autant utiliser cette option ?
# race condition?
Posté par Yann Hodique (site web personnel) . Évalué à 4.
Le passage suivant me perplexifie:
Qu'est-ce que ça veut dire au juste? Si ça se réfère au fait que la production d'images entraîne la création temporaire d'objets "Dangling" (ce qui est vraiment un bug particulièrement énervant de Docker), je vois mal pourquoi rendre le processus synchrone ou asynchrone changerait quoi que ce soit au problème, sauf à imposer une seule image en cours de création à un instant T, ou à stopper complètement le processus de création le temps d'un "gc". Dans les 2 cas, ça ne me semble pas particulièrement réaliste comme contrainte, pour un serveur dédié à cette activité.
Est-ce qu'il ne vaudrait pas mieux suggérer une configuration fiable pour ces cas? (quitte à prendre une hypothèse sur le temps maximal de construction d'une image par exemple)
Et si je suis complètement à côté de la plaque, une explication (voire un ajout au README) serait bienvenue ! :)
Projet sympa sinon. Si je peux me permettre une suggestion, des instructions pour construire une image statique de ton programme lui donnerait de la visibilité: la plupart des systèmes pour lesquels il serait vraiment utiles n'ont pas OCaml, et souvent aucun moyen (simple) de l'installer (immutable infrastructure et tout ça).
Ou encore mieux… fournir une image docker de ton programme (dans le style docker-in-docker)
[^] # Re: race condition?
Posté par Michaël (site web personnel) . Évalué à 4.
C'est effectivement l'hypothèse implicite que je fais dans cette phrase, mais comme tu le soulignes, ce n'est pas particulièrement réaliste en production.
non, non tu es au bon endroit! :)
Cela fait partie des mes projets, ce sera effectivement plus facile à utiliser pour ceux qui ne sont pas encore familiers avec OCaml et son écosystème.
[^] # Re: race condition?
Posté par Michaël (site web personnel) . Évalué à 2.
Ça y est, j'ai décrit la procédure de préparation des images dans le README du projet et un petit script a été ajouté pour utiliser facilement cette image.
# Volumes?
Posté par Romuald Brunet (site web personnel) . Évalué à 1.
Vu que j'ai découvert cette blague hier …
Une option sympathique à ajouter pourrait être le ramasse-miettage des anciens volumes également (qui ne sont pas effacés par défaut, et qui peuvent donc prendre pas mal de place au bout d'un moment)
cf http://stackoverflow.com/questions/27812807/orphaned-docker-mounted-host-volumes
[^] # Re: Volumes?
Posté par Michaël (site web personnel) . Évalué à 2.
Excellent idée, j'ai ouvert un ticket! Merci pour la référence.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.