
Bonjour Habr ! Je vous présente la traduction de l'article l'auteur .
Aujourd'hui, nous allons parler de la maniÚre dont Docker utilise l'espace disque de la machine hÎte, et nous allons également voir comment libérer cet espace des vestiges d'images et de conteneurs inutilisés.

Consommation totale
Docker est un outil formidable, et il y a peu de gens qui en doutent aujourd'hui. Il y a seulement quelques annĂ©es, ce produit nous a donnĂ© une toute nouvelle façon de construire, de livrer et de faire fonctionner n'importe quel environnement, permettant ainsi d'Ă©conomiser considĂ©rablement les ressources processeur et la mĂ©moire vive. En outre (et pour certains, c'est peut-ĂȘtre le plus important), Docker nous a permis de simplifier et d'unifier de maniĂšre incroyable la gestion du cycle de vie des environnements de travail utilisĂ©s.
Cependant, toutes ces merveilles de la vie moderne ont un coût. Lorsque nous lançons des conteneurs, téléchargeons ou créons nos propres images, déployons des écosystÚmes complexes, nous avons un prix à payer. Et ce prix se paie aussi, en partie, en espace disque.
Si vous ne vous ĂȘtes jamais demandĂ© combien d'espace est rĂ©ellement occupĂ© sur votre machine par Docker, vous pourriez ĂȘtre dĂ©sagrĂ©ablement surpris par le rĂ©sultat de cette commande :
$ docker system df 
Cela affiche l'utilisation du disque par Docker sous différents angles :
- images â taille totale des images qui ont Ă©tĂ© tĂ©lĂ©chargĂ©es depuis les dĂ©pĂŽts d'images et construites sur votre systĂšme ;
- conteneurs â volume total d'espace disque utilisĂ© par les conteneurs en cours d'exĂ©cution (c'est-Ă -dire le volume total des couches en lecture-Ă©criture de tous les conteneurs) ;
- volumes locaux â volume des stockages locaux montĂ©s sur les conteneurs ;
- cache de construction â fichiers temporaires gĂ©nĂ©rĂ©s par le processus de construction des images (lors de l'utilisation de l'outil BuildKit, disponible Ă partir de la version 18.09 de Docker).
Je parie qu'aprÚs cette simple énumération, vous brûlez d'envie de nettoyer votre disque de ses déchets et de redonner vie à vos précieux gigaoctets (note de traduction : surtout si vous payez mensuellement pour ces gigaoctets).
Utilisation du disque par les conteneurs
Chaque fois qu'un conteneur est créé sur la machine hÎte, plusieurs fichiers et répertoires sont créés dans le répertoire /var/lib/docker, parmi lesquels il convient de noter les suivants :
- Le rĂ©pertoire /var/lib/docker/containers/ID_conteneur â lorsque vous utilisez le pilote de journalisation standard, c'est ici que les journaux d'Ă©vĂ©nements sont enregistrĂ©s au format JSON. Des journaux trop dĂ©taillĂ©s, ainsi que ceux qui ne sont lus par personne et ne sont pas traitĂ©s d'une autre maniĂšre, deviennent souvent la cause de remplissages de disques.
- Le rĂ©pertoire /var/lib/docker/overlay2 â contient des couches en lecture-Ă©criture des conteneurs (overlay2 est le pilote prĂ©fĂ©rĂ© dans la plupart des distributions Linux). Si le conteneur enregistre des donnĂ©es dans son systĂšme de fichiers, c'est dans ce rĂ©pertoire qu'elles seront placĂ©es.
Imaginons un systÚme sur lequel Docker est installé pour la premiÚre fois, sans jamais avoir exécuté de conteneurs ou construit des images. Son rapport sur l'utilisation de l'espace disque ressemblera à ceci :
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 0 0 0B 0B
Containers 0 0 0B 0B
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0BLançons un conteneur, par exemple, NGINX :
$ docker container run --name www -d -p 8000:80 nginx:1.16Que se passe-t-il avec le disque :
- les images occupent 126 Mo, c'est justement ce NGINX que nous avons lancé dans le conteneur ;
- les conteneurs occupent un ridicule 2 octets.
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 1 1 126M 0B (0%)
Containers 1 1 2B 0B (0%)
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0Bà en juger par la sortie, nous n'avons pas encore d'espace que nous pourrions libérer. Comme 2 octets, c'est manifestement dérisoire, imaginons que notre NGINX ait, à la surprise générale, écrit quelque part 100 Mégaoctets de données et créé un fichier test.img de cette taille.
$ docker exec -ti www
dd if=/dev/zero of=test.img bs=1024 count=0 seek=$[1024*100]Examinons à nouveau l'utilisation de l'espace disque sur l'hÎte. Nous verrons que le conteneur (containers) occupe maintenant 100 Mégaoctets.
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 1 1 126M 0B (0%)
Containers 1 1 104.9MB 0B (0%)
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0BJe pense que votre esprit curieux se demande dĂ©jĂ oĂč se trouve notre fichier test.img. Cherchons-le :
$ find /var/lib/docker -type f -name test.img
/var/lib/docker/overlay2/83f177...630078/merged/test.img
/var/lib/docker/overlay2/83f177...630078/diff/test.imgSans entrer dans les dĂ©tails, il convient de noter que le fichier test.img est commodĂ©ment situĂ© au niveau de lecture-Ă©criture, gĂ©rĂ© par le pilote overlay2. Si nous arrĂȘtons notre conteneur, l'hĂŽte nous indiquera que cet espace peut en principe ĂȘtre libĂ©rĂ© :
# Stopping the www container
$ docker stop www
# Visualizing the impact on the disk usage
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 1 1 126M 0B (0%)
Containers 1 0 104.9MB 104.9MB (100%)
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0BComment pouvons-nous procéder ? En supprimant le conteneur, ce qui entraßnera le nettoyage de l'espace correspondant au niveau de lecture-écriture.
Avec la commande suivante, vous pouvez supprimer tous les conteneurs installés d'un seul coup et nettoyer votre disque de tous les fichiers qu'ils ont créés au niveau de lecture-écriture :
$ docker container prune
AVERTISSEMENT ! Cela supprimera tous les conteneurs arrĂȘtĂ©s.
Ătes-vous sĂ»r de vouloir continuer ? [y/N] y
Conteneurs supprimés :
5e7f8e5097ace9ef5518ebf0c6fc2062ff024efb495f11ccc89df21ec9b4dcc2
Espace total récupéré : 104,9 MoAinsi, nous avons libéré 104,9 Mo en supprimant le conteneur. Mais comme nous n'utilisons plus l'image téléchargée auparavant, celle-ci devient également candidate à la suppression et à la libération de nos ressources :
$ docker system df
TYPE TOTAL ACTIF TAILLE RĂCUPĂRABLE
Images 1 0 126M 126M (100 %)
Conteneurs 0 0 0B 0B
Volumes locaux 0 0 0B 0B
Cache de construction 0 0 0B 0BAttention : tant que l'image est utilisée par au moins un conteneur, vous ne pourrez pas utiliser cette astuce.
La sous-commande prune, que nous avons utilisĂ©e ci-dessus, n'a d'effet que sur les conteneurs arrĂȘtĂ©s. Si nous souhaitons supprimer non seulement les conteneurs arrĂȘtĂ©s, mais aussi les conteneurs en cours d'exĂ©cution, nous devons utiliser l'une de ces commandes :
# Historical command
$ docker rm -f $(docker ps âaq)
# More recent command
$ docker container rm -f $(docker container ls -aq)Remarques : si lors du dĂ©marrage du conteneur vous utilisez le paramĂštre ârm, tout l'espace disque qu'il occupait sera libĂ©rĂ© lors de son arrĂȘt.
Utilisation du disque par les images
Il y a quelques annĂ©es, une taille d'image de plusieurs centaines de mĂ©gaoctets Ă©tait tout Ă fait normale : l'image d'Ubuntu pesait 600 Mo, tandis que l'image de Microsoft .Net pesait plusieurs giga-octets. Ă cette Ă©poque, le tĂ©lĂ©chargement d'une seule image pouvait avoir un impact considĂ©rable sur votre espace libre sur le disque, mĂȘme si vous partagiez des niveaux entre les images. Aujourd'hui â grĂące aux grands â les images pĂšsent beaucoup moins, mais mĂȘme dans ce cas, il est possible de saturer rapidement les ressources disponibles si certaines prĂ©cautions ne sont pas prises.
Il existe plusieurs types d'images qui ne sont pas directement visibles par l'utilisateur final :
- des images intermĂ©diaires, sur lesquelles d'autres images sont basĂ©es â elles ne peuvent pas ĂȘtre supprimĂ©es si vous utilisez des conteneurs basĂ©s sur ces « autres » images;
- les images pendantes â ce sont des images intermĂ©diaires, auxquelles aucun des conteneurs en cours d'exĂ©cution ne fait rĂ©fĂ©rence â elles peuvent ĂȘtre supprimĂ©es.
- Avec la commande suivante, vous pouvez vérifier la présence d'images pendantes dans votre systÚme :
$ docker image ls -f dangling=true
REPOSITORY TAG IMAGE ID CREATED SIZE
none none 21e658fe5351 il y a 12 minutes 71.3MBVous pouvez les supprimer de la maniĂšre suivante :
$ docker image rm $(docker image ls -f dangling=true -q)Nous pouvons également utiliser la sous-commande prune :
$ docker image prune
AVERTISSEMENT ! Cela supprimera toutes les images pendantes.
Ătes-vous sĂ»r de vouloir continuer ? [y/N] y
Images supprimées :
supprimé : sha256:143407a3cb7efa6e95761b8cd6cea25e3f41455be6d5e7cda
supprimé : sha256:738010bda9dd34896bac9bbc77b2d60addd7738ad1a95e5cc
supprimé : sha256:fa4f0194a1eb829523ecf3bad04b4a7bdce089c8361e2c347
supprimé : sha256:c5041938bcb46f78bf2f2a7f0a0df0eea74c4555097cc9197
supprimé : sha256:5945bb6e12888cf320828e0fd00728947104da82e3eb4452f
Espace total récupéré : 12.9kBSi nous voulons par contre supprimer toutes les images (et pas seulement celles pendantes) avec une seule commande, nous pouvons procéder ainsi :
$ docker image rm $(docker image ls -q)Utilisation du disque avec des volumes
Les volumes sont utilisés pour stocker des données en dehors du systÚme de fichiers du conteneur. Par exemple, si nous voulons conserver les résultats d'une application afin de les utiliser par la suite. Un exemple courant est celui des bases de données.
Lançons un conteneur MongoDB, montons un volume externe par rapport au conteneur, et restaurons une sauvegarde de la base de données (nous l'avons disponible dans le fichier bck.json) :
# Running a mongo container
$ docker run --name db -v $PWD:/tmp -p 27017:27017 -d mongo:4.0
# Importing an existing backup (from a huge bck.json file)
$ docker exec -ti db mongoimport
--db 'test'
--collection 'demo'
--file /tmp/bck.json
--jsonArrayLes donnĂ©es seront sur la machine hĂŽte dans le rĂ©pertoire /var/lib/docker/volumes. Mais pourquoi pas en lecture-Ă©criture au niveau du conteneur ? Parce que dans le Dockerfile de l'image MongoDB, le rĂ©pertoire /data/db (oĂč MongoDB stocke ses donnĂ©es par dĂ©faut) est dĂ©fini comme un volume.

Notes en passant : de nombreuses images, dont la mise en Ćuvre nĂ©cessite la crĂ©ation de donnĂ©es, utilisent des volumes pour sauvegarder ces donnĂ©es.
Lorsque nous avons fini de jouer avec MongoDB et que nous arrĂȘtons (ou mĂȘme supprimons) le conteneur, le volume ne sera pas supprimĂ©. Il continuera Ă occuper notre prĂ©cieux espace disque tant que nous ne le supprimerons pas explicitement avec cette commande :
$ docker volume rm $(docker volume ls -q)Ou nous pouvons utiliser la sous-commande prune que nous connaissons déjà :
$ docker volume prune
AVERTISSEMENT ! Cela supprimera tous les volumes locaux non utilisés par au moins un conteneur.
Ătes-vous sĂ»r de vouloir continuer ? [y/N] y
Volumes supprimés :
d50b6402eb75d09ec17a5f57df4ed7b520c448429f70725fc5707334e5ded4d5
8f7a16e1cf117cdfddb6a38d1f4f02b18d21a485b49037e2670753fa34d115fc
599c3dd48d529b2e105eec38537cd16dac1ae6f899a123e2a62ffac6168b2f5f
...
732e610e435c24f6acae827cd340a60ce4132387cfc512452994bc0728dd66df
9a3f39cc8bd0f9ce54dea3421193f752bda4b8846841b6d36f8ee24358a85bae
045a9b534259ec6c0318cb162b7b4fca75b553d4e86fc93faafd0e7c77c79799
c6283fe9f8d2ca105d30ecaad31868410e809aba0909b3e60d68a26e92a094da
Espace total récupéré : 25,82 Go
luc@saturn:~$Utilisation du disque pour le cache de construction d'images
Dans Docker 18.09, le processus de création d'images a subi quelques modifications grùce à l'outil BuildKit. Cet outil augmente la vitesse du processus, optimise la gestion du stockage et la sécurité. Ici, nous ne détaillerons pas toutes les spécificités de cet outil excellent, nous nous concentrerons simplement sur la façon dont il impacte l'utilisation de l'espace disque.
Supposons que nous avons une application Node.Js trĂšs simple :
- le fichier index.js lance un serveur HTTP simple, qui rĂ©pond par une chaĂźne pour chaque requĂȘte reçue :
- le fichier package.json définit les dépendances, dont seule expressjs est utilisée pour exécuter le serveur HTTP :
$ cat index.js
var express = require('express');
var util = require('util');
var app = express();
app.get('/', function(req, res) {
res.setHeader('Content-Type', 'text/plain');
res.end(util.format("%s - %s", new Date(), 'Got Request'));
});
app.listen(process.env.PORT || 80);$ cat package.json
{
"name": "testnode",
"version": "0.0.1",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"express": "^4.14.0"
}
}Le Dockerfile pour construire l'image ressemble Ă ceci :
FROM node:13-alpine
COPY package.json /app/package.json
RUN cd /app && npm install
COPY . /app/
WORKDIR /app
EXPOSE 80
CMD ["npm", "start"]Construisons l'image de la maniĂšre habituelle, sans utiliser BuildKit :
$ docker build -t app:1.0 .Si nous vérifions l'utilisation de l'espace disque, nous verrons que seul l'image de base (node:13-alpine) et l'image finale (app:1.0) occupent de l'espace :
TYPE TOTAL ACTIF TAILLE RĂCUPĂRABLE
Images 2 0 109.3MB 109.3MB (100%)
Conteneurs 0 0 0B 0B
Volumes Locaux 0 0 0B 0B
Cache de Construction 0 0 0B 0BConstruisons la deuxiÚme version de notre application, déjà avec l'utilisation de BuildKit. Pour cela, nous devons simplement définir la variable DOCKER_BUILDKIT sur 1 :
$ DOCKER_BUILDKIT=1 docker build -t app:2.0 .Si nous vérifions maintenant l'utilisation du disque, nous verrons que le cache de construction (build-cache) est impliqué :
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 2 0 109.3MB 109.3MB (100%)
Containers 0 0 0B 0B
Local Volumes 0 0 0B 0B
Build Cache 11 0 8.949kB 8.949kBPour le nettoyer, nous allons utiliser la commande suivante :
$ docker builder prune
WARNING! Cela supprimera tout le cache de construction inutilisé.
Ătes-vous sĂ»r de vouloir continuer ? [y/N] y
Objet du cache de construction supprimé :
rffq7b06h9t09xe584rn4f91e
ztexgsz949ci8mx8p5tzgdzhe
3z9jeoqbbmj3eftltawvkiayi
Espace total récupéré : 8.949kBTout nettoyer !
Ainsi, nous avons examinĂ© le nettoyage de l'espace disque occupĂ© par les conteneurs, images et volumes. Cela est aidĂ© par la sous-commande prune. Mais elle peut Ă©galement ĂȘtre utilisĂ©e au niveau du systĂšme Docker, et elle nettoiera tout ce qu'elle peut :
$ docker system prune
WARNING! Cela supprimera :
- tous les conteneurs arrĂȘtĂ©s
- tous les réseaux non utilisés par au moins un conteneur
- toutes les images inutilisées
- tout le cache de construction inutilisé
Ătes-vous sĂ»r de vouloir continuer ? [y/N]Si pour une raison quelconque vous Ă©conomisez de l'espace disque sur une machine avec Docker, il est conseillĂ© d'adopter l'utilisation rĂ©guliĂšre de cette commande.
Source : habr.com
