Libérer de l'espace disque utilisé par Docker

Il peut arriver que l’espace alloué à Docker soit plein. Cette page présente des pistes pour résoudre ce problème.

Note:

Traditionnellement, les données de Docker sont stockées dans une partition spécifique (LVM), montée sur /var/lib/docker. On suppose que c’est le cas pour le reste de cette page.

Lien:

Le contexte et les éléments d’ébauche de cette page peuvent être retrouvés sur ce fil Mattermost.

La partition montée sur /var/lib/docker est un volume logique. Nous avons fait le choix de ne pas tout mettre dans une unique partition montée sur / pour éviter que le reste du système ne soit impacté si le stockage de docker explose.

Quand le volume monté sur /var/lib/docker arrive à saturation il y a plusieurs solutions complémentaire :

  1. Supprimer les données non utilisées,
  2. Allouer plus d’espace disque à la partition montée sur /var/lib/docker,
  3. Augmenter la taille des disques de la machine virtuelle.

Important:

Opération destructrice : si vous vous foirez, vous pouvez supprimer des données de production. Faites particulièrement attention avant d’exécuter la commande, qui est sûre en elle même.

Au fil des mises à jour, il y a du stockage pris par Docker qui n’est plus utilisé.

Question:

Quel genre de stockage ?

  • Les images qui ont été récupérées mais ne sont plus utilisées (e.g. ancienne version), les images dites dangling (anciens layers d’un tag qui ont été écrasées par une nouvelle version du même tag).
  • Les conteneurs éteints mais pas supprimés, qui consomment du stockage si des modifications ont été apportées aux images de base.
  • Les volumes Docker qui ne correspondent plus à aucun conteneur.
  • Les réseaux Docker utilisés par aucun conteneur.
  • Le cache des images.

On peut obtenir une estimation de l’espace récupérable avec la commande :

snippet.bash
docker system df

Afin de supprimer l’ensemble de ces données, on lancera la commande suivante.

Note:

Si un conteneur s’est éteint à cause d’un bug, alors cette commande le supprimera. Vérifiez qu’aucun conteneur n’est éteint alors qu’il devrait tourner avec cette commande :

docker ps --filter "status=exited"

On peut utiliser le graphe des services pour savoir ce qui est censé tourner sur la machine.

Note:

Cette commande ne supprime volontairement pas les volumes non-utilisés, pour se laisser une chance en cas de mauvaise manipulation.

snippet.bash
docker system prune

Inspectez le résultat de la commande et vérifiez que ce qui a été supprimé n’était plus utilisé. Une fois que vous en êtes convaincus, vous pouvez supprimer les volumes non-utilisés :

snippet.bash
docker volume prune -a

Il faut aussi rajouter une commande pour supprimer toutes les images non-associées à un conteneur :

snippet.bash
docker image prune -a

Si le stockage récupéré n’est pas suffisant, on peut regarder si un conteneur n’utilise pas plus de stockage que prévu, par exemple à cause d’un bug.

La commande suivante permet de lister le stockage utilisé par chaque conteneur, image et volume :

snippet.bash
docker system df -v

Ensuite, on traite au cas par cas. On peut par exemple découvrir des services qui tournent alors qu’ils n’ont plus rien à faire là (dans ce cas on les éteindra et on relancera un prune), ou des conteneurs qui prennent trop de place (par exemple, parce qu’ils loggent dans un fichier en mode DEBUG).

De manière générale, un conteneur ne devrait jamais utiliser plus Go d’espace : les données volumineuses doivent être dans un volume, il y a donc un problème à investiguer.

Question:

Que faire si l’espace disponible sur /var/lib/docker est anormalement faible, alors que docker system df ne reporte pas de grosse utilisation ?

Franchement, ça ne devrait pas arriver. On peut tout de même regarder à la main ce qui prend le plus de place dans /var/lib/docker, et qui ne serait pas géré ou pris en compte par Docker.

Note:

La commande du -sh <dossier> permet de connaître la taille d’un dossier et de ses sous-dossiers.

Note:

/var/lib/docker est organisé en sous-dossiers : un pour les conteneurs, un pour les images, un pour les volumes…

On cherche donc à savoir ce qui prend le plus de place :

snippet.bash
du -sh /var/lib/docker/*

On voit ainsi quels sont les éléments qui occupent le plus de place en mémoire, par exemple :

  • volumes pour le contenu persistant des conteneurs (bases de données par exemple)
  • overlay2 pour les conteneurs

Une fois que l’on a déterminé le dossier qui prend le plus de place,

On peut regarder par exemple quels sont les dix plus gros fichiers les plus gros dans /var/lib/docker/overlay2 :

du -sh /var/lib/docker/overlay2/* | sort -rh | head -10

Mais cette commande ne nous donne pas d’information exploitable sur les conteneurs qui prennent le plus de place, il faut donc utiliser cette commande pour faire correspondre les noms (à adapter si on regarde plutôt des volumes par exemple) :

for overlayID in $(du -sh /var/lib/docker/overlay2/* | sort -rh | head -10 | grep -P -o "[^/]*$"); do docker ps -a -q | xargs docker inspect | jq --arg ID "$overlayID" '.[] | select(.GraphDriver.Data.LowerDir | contains($ID)) | .Name'; done

On peut utiliser des commandes similaires pour les volumes.

Note:

Cette commande récupère les ID des conteneurs qui prennent le plus de place, puis pour chacun d’eux elle fait correspondre le nom du conteneurs via la sortie JSON de la commande docker inspect.

Si aucune des solutions précédentes n’a fonctionné et que Docker a réellement besoin de plus de place, on suivra la documentation d'augmentation d'une partition.

  • technique/docker/admin/nettoyer_docker.txt
  • de qduchemi