web-dev-qa-db-fra.com

Jenkins et Docker: pas d'espace disponible - comment nettoyer correctement

Nous utilisons Jenkins (version 2.60.1) sur un serveur Ubuntu 16.04.1. L’un des problèmes que nous avons rencontrés récemment est que nous obtenons systématiquement l’erreur " il ne reste plus d’espace sur le périphérique ".

Je comprends que lorsque Docker est utilisé, un processus de nettoyage strict est nécessaire en raison des fichiers laissés sur place et occupant un espace inutile.

Nous utilisons le CloudBees Docker Build and Publish plugin pour gérer la construction et la diffusion dans AWS ECS. J'ai pensé à supprimer toutes les images inutilisées. Le problème est que si je me connecte à l'instance de Jenkins (via SSH) et que j'essaie d'exécuter la commande docker, elle indique - "Impossible de se connecter au démon Docker. Le démon docker est-il exécuté sur cet hôte?"

Je suppose que d’une manière ou d’une autre je dois faire cela depuis l’environnement Jenkins ou une partie du plugin?

Quelqu'un a déjà réglé ce problème ou a un conseil? - Je l'apprécierais vraiment.

5
Aaron

Docker <1.13

Pour Docker plus ancien que 1.13, vous pouvez effectuer les opérations suivantes pour nettoyer de l’espace sur votre appareil:

docker ps -a | grep -i 'exited' | awk '{print $1}' | xargs docker rm > /dev/null 2>&1 &
docker images -a | grep "<none>" | awk '{print $3}' | xargs docker rmi > /dev/null 2>&1 &

Sinon, vous pouvez essayer d'exécuter la commande suivante de docker:

docker rmi $(docker images --filter "dangling=true" -q --no-trunc)

Il nettoiera les anciens conteneurs Orphan et supprimera les images marquées avec <none>. J'utilise ces deux formules sur l'un de mes serveurs CI et cela fonctionne bien. Avant cela, j'étais confronté à un problème similaire à votre problème (il ne restait plus d'espace sur l'appareil).

Nettoyage des volumes orphelins

docker volume rm $(docker volume ls -qf dangling=true)
docker volume ls -qf dangling=true | xargs -r docker volume rm

Docker> = 1.13

Docker 1.13 introduit la commande docker system Prune ( https://docs.docker.com/engine/reference/commandline/system_Prune/ ). Sinon, vous pouvez exécuter:

  • docker image Prune
  • docker volume Prune
  • docker container Prune

Vous pouvez exécuter ces commandes dans le cadre de votre pipeline Jenkins. Dans l'un des projets sur lesquels je travaille, nous exécutons le nettoyage après avoir créé de nouvelles images Docker au cours du processus de publication. Essayez également de corriger "Impossible de se connecter au démon Docker. Le démon docker est-il en cours d'exécution sur cet hôte?" problème.

3
Szymon Stepniak

Après avoir utilisé le script fourni par burnettk ci-dessous, il semblait que, bien que de l'espace ait été libéré après avoir exécuté plus de versions, j'étais de retour au même endroit, pas d'espace sur mon volume EBS. Cela n'a tout simplement aucun sens que je devrais ajouter de l'espace de stockage et payer AWS encore plus sur ma facture mensuelle.

En faisant des recherches, j'ai découvert que pour CHAQUE génération, il y avait environ 7 images créées (images de menu fixe -a) comprenant environ 1,4 Go chacune, soit 9 Go/génération. Les 2 premiers sont étiquetés avec le numéro de construction et sont les derniers, tandis que les autres sont étiquetés.

Il n’est vraiment pas important que toutes ces images soient stockées sur ce serveur car le but est de construire et de toute façon elles sont poussées vers ECR. J'ai donc ajouté ce qui suit dans mon script afin que seule la dernière image du menu fixe soit conservée:

docker rmi $(docker images | sed 1,3d | awk '{print $3}')

Enfin, j'ai également ajusté ma commande de génération de docker en ajoutant l'argument --rm afin qu'il supprime les conteneurs intermédiaires après la construction.

docker build --rm

J'espère que c'est utile!

2
Aaron

pour résoudre le problème "impossible de se connecter au docker docker daemon", déterminez quels utilisateurs sont dans le groupe de dockers

grep 'docker' /etc/group

puis exécutez les commandes de nettoyage de docker (vous voudrez en faire un script que vous exécuterez sur cron ou quelque chose du genre) en tant qu’un de ces utilisateurs. ou obtenez un accès Sudo avec un autre utilisateur et utilisez Sudo:

Sudo docker rmi [image_name_here]

voici le contenu d'un exemple de script de nettoyage (/usr/local/bin/clean_up_docker_stuff_on_ci_agent ou similaire):

#!/bin/bash

# stop containers that have been running for more than a day (may not be valid in your context if you intend run things for a long time)
docker ps -a | egrep " days" | awk '{print $1}' | grep -v CONTAINER | xargs docker stop

# remove all exited containers
docker ps -a | egrep "Exited|Created" | awk '{print $1}' | grep -v CONTAINER | xargs docker rm

# remove old images
docker images | egrep 'weeks|months' | awk '{print $1 ":" $2}' | xargs docker rmi -f
docker images | egrep 'weeks|months' | grep '<none>' | awk '{ print $3 }' | xargs docker rmi -f

# kill stray volumes
docker volume ls -qf dangling=true | xargs -r docker volume rm

Comme Szymon Stepniak le mentionne dans sa réponse, si vous utilisez docker> = 1.13, il existe des options plus simples.

exemple cron (20 après chaque heure):

20 * * * * /usr/local/bin/clean_up_docker_stuff_on_ci_agent > /dev/null 2>&1
1
burnettk

L'erreur que vous rencontrez est généralement due au fait que l'utilisateur n'est pas autorisé à utiliser docker cli ou que docker est arrêté.

Quoi qu'il en soit, pour répondre à votre question, comment effectuer un nettoyage correctement.

  1. Assurez-vous de définir vos tâches pour supprimer régulièrement les anciennes versions.
  2. Si vous ne pouvez pas exécuter docker (je ne sais pas pourquoi). Il suffit ensuite d’un cron qui nettoie le répertoire/var/lib/docker du serveur Jenkins.
  3. Enfin, utilisez le conteneur Docker qui s’exécute en tant qu’esclave jenkins. De cette façon, les artefacts de construction sont stockés dans un système de fichiers temporaire et si vous redéployez vos esclaves jenkins régulièrement, vous ne rencontrerez plus votre problème d'espace disque.
0
bzon