Économiser du temps et de la bande passante avec un cache Docker local
Régulièrement, j’utilise Docker 🐳 dans des VMs (vagrant) ou sur d’autres machine de mon réseau local, et je me retrouve à télécharger plusieurs fois la même image sur ces différentes machines. En plus du gâchis de bande passante, ça devient rapidement une grosse perte de temps sur de petites connexions ! Pour régler ce problème j’utilise maintenant un registre (« registry ») Docker qui tourne localalement et qui cache de manières transparentes toutes les images récupérées par Docker. Voici comment mettre cela en place.
D’abord, un peu de préparation. Nous allons créer un dossier qui va être
utilisé par le registre pour stocker toutes ces données. Ce dossier peut-être
n’importe où sur votre machine, personnellement je l’ai mis dans /var/lib
:
1
|
$ sudo mkdir /var/lib/docker-registry |
Nous allons ajouter la configuration par défaut du registre dans ce dossier, et pour cela on va directement l’extraire depuis l’image Docker :
1 2 3 |
$ sudo docker run -it --rm registry:2 \ cat /etc/docker/registry/config.yml \ > /var/lib/docker-registry/config.yml |
La configuration pourra être différente selon le moment ou vous la récupérez, à la création de cet article elle ressemblait à ça :
|
|
Pour activer la fonction de proxy du serveur, il faut ajouter la configuration suivante au fichier yaml:
|
|
La clé remoteurl
peut pointer vers n’importe quel registre, ici j’ai mis
celui de docker par défaut.
La configuration finale ressemble à ça:
|
|
Maintenant que la configuration est finie, on peut démarrer notre registre. À
noter que j’ai utilisé l’option --restart=always
dans la commande suivante
pour m’assurer que le registre démarre automatiquement avec le démon Docker.
1 2 3 |
$ sudo docker run --restart=always -p 5000:5000 \ --name v2-mirror -v /var/lib/docker-registry:/var/lib/registry \ --detach registry:2 serve /var/lib/registry/config.yml |
On utilise -v
pour monter le dossier créé précédemment dans l’image, et on
démarre le registre avec l’option serve
suivit du chemin vers le fichier de
configuration.
Assurons-nous d’abord que le container est bien lancé avec docker ps
:
1 2 3 |
$ sudo docker ps CONTAINER ID IMAGE CREATED STATUS PORTS NAMES 67425da4ea4c registry:2 32 seconds ago Up 29 seconds 0.0.0.0:5000->5000/tcp v2-mirror |
On peut ensuite lister le contenu du registre (vide) via curl
:
1 2 |
$ curl http://localhost:5000/v2/_catalog {"repositories":[]} |
Maintenant que notre registre est actif, on va configurer docker pour qu’il
l’utilise. Pour cela il faut éditer le fichier /etc/docker/daemon.json
pour
ajouter la configuration suivante (qui doit être du JSON valide) :
|
|
Il est possible que ce fichier (voir dossier) n’existe pas sur votre système.
Si c’est le cas, vous pouvez le créer manuellement (avec l’utilisateur root
).
Une fois la configuration changée il faut redémarrer docker. Ici j’assume que
vous avez un système qui utilise Systemd:
1
|
$ sudo systemctl restart docker |
Nous sommes maintenant prêts à réaliser notre premier download pour vérifier que le proxy fonctionne correctement:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ sudo docker pull redis Using default tag: latest latest: Pulling from library/redis f17d81b4b692: Pull complete b32474098757: Pull complete 8980cabe8bc2: Pull complete e614c66c2b9c: Pull complete 6eb43ec9256b: Pull complete 394ecf5f46d4: Pull complete Digest: sha256:f30f134bd475d451ce3207fb128bcef8ff87d0f520a39cac0c4ea285819c42a9 Status: Downloaded newer image for redis:latest ~ took 40s |
Vérifions que l’image est maintenant dans notre registre local:
1 2 |
$ curl http://localhost:5000/v2/_catalog {"repositories":["library/redis"]} |
Et voilà ! Nous venons de cacher notre première image 🎉. Vérifions maintenant que le cache fonctionne comme il faut. En premier lieu, on va effacer l’image de notre démon docker:
1 2 3 4 5 6 7 8 9 10 |
$ sudo docker rmi redis Untagged: redis:latest Untagged: redis@sha256:f30f134bd475d451ce3207fb128bcef8ff87d0f520a39cac0c4ea285819c42a9 Deleted: sha256:415381a6cb813ef0972eff8edac32069637b4546349d9ffdb8e4f641f55edcdd Deleted: sha256:2a5a57892da005399e6ce7166c5521cdca43a07872f23995e210bde5dae2640e Deleted: sha256:85e1fabde4fd4d6df993de44ef3e04d15cd69f9d309c0112c6a5054a6dc8351a Deleted: sha256:2725175b62c7479ee209454110e8293080b9711e4f0a29219e358d1afba88787 Deleted: sha256:7ae66985fd3a3a132fab51b4a43ed32fd14174179ad8c3041262670523a6104c Deleted: sha256:bf45690ef12cc54743675646a8e0bafe0394706b7f9ed1c9b11423bb5494665b Deleted: sha256:237472299760d6726d376385edd9e79c310fe91d794bc9870d038417d448c2d5 |
Et on la récupère de nouveau:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
sudo docker pull redis Using default tag: latest latest: Pulling from library/redis f17d81b4b692: Pull complete b32474098757: Pull complete 8980cabe8bc2: Pull complete e614c66c2b9c: Pull complete 6eb43ec9256b: Pull complete 394ecf5f46d4: Pull complete Digest: sha256:f30f134bd475d451ce3207fb128bcef8ff87d0f520a39cac0c4ea285819c42a9 Status: Downloaded newer image for redis:latest ~ took 13s |
Ce qui nous a pris 3x moins de temps ! 👍 Le téléchargement était quasiment instantané, et seule la décompression a pris du temps.
Avec ça nous avons maintenant un cache local transparent pour toutes les images Docker que l’on télécharge. On peut maintenant pointer les différentes VM ou machine du réseau vers ce cache, et profiter du temps gagné pour faire des choses utiles plutôt que de télécharger des octets depuis internet :)
Un effet secondaire intéressant de ce cache, et que si un docker pull
échoue
au milieu du téléchargement, les images intermédiaires déjà téléchargées seront
conservées dans le cache, et donc il ne sera pas nécessaire de les télécharger
de nouveau. Vous pouvez vérifier ça en stoppant un pull
et en le relançant
avec et sans le proxy.
Did you enjoy this article? Don't want to miss any new posts and get exclusive content? Then hop into my newsletter :)
You can also contact me directly via email: m [-at-] mayeu [-dot-] me