Jenkins和Docker没有设备空间 – 如何正确清理

我们在Ubuntu 16.04.1服务器上运行Jenkins(版本2.60.1)。 我们最近遇到的一个问题是,我们经常会遇到“ 设备上没有空间 ”的错误。

我明白在使用Docker的时候,需要进行严格的清理过程,因为这些文件被遗留下来,占用了不必要的空间。

我们使用CloudBees Docker构build和发布插件来处理构build并推送到AWS ECS。 我想过删除所有未使用的图像。 问题是,如果我login到Jenkins实例(通过SSH)并尝试运行它提供的docker命令 – “无法连接到Docker守护进程,docker守护进程是否在该主机上运行?

我想我需要从Jenkins环境或插件的一部分做到这一点?

有人以前处理过这个问题,还是有一些build议? – 我真的很感激。

Docker <1.13

对于比1.13更早的Docker,您可以按照以下步骤清理设备上的一些空间:

 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 & 

或者,您可以尝试运行以下docker命令:

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

它将清理旧的孤立容器,并删除标有<none>图像。 我在我的一台CI服务器上使用这两个公式,它工作正常。 在此之前,我面临类似的问题(设备上没有剩余空间)。

清理孤立的卷

 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引入了docker system prune命令( https://docs.docker.com/engine/reference/commandline/system_prune/ )。 或者,您可以运行:

  • docker image prune
  • docker volume prune
  • docker container prune

您可以将这些命令作为Jenkinspipe道的一部分运行。 在我工作的其中一个项目中,我们在发布过程中构build新的Docker镜像之后运行清理。 试着修复“无法连接到Docker守护进程,docker守护进程是否在这台主机上运行?” 问题。

您遇到的错误通常是因为用户不被允许使用docker cli或docker被停止。

无论如何,回答你的问题如何正确地进行清理。

  1. 确保你的工作定期放弃旧版本。
  2. 如果你不能运行docker(我不知道为什么)。 然后只需要一个清理你的Jenkins服务器/ var / lib / docker目录的cron。
  3. 最后,使用作为jenkins奴隶运行的docker容器。 这样,构build工件被存储在一个临时文件系统中,如果您重新configuration您的jenkins奴隶,您将不会再遇到磁盘空间问题。

为了通过“无法连接到docker docker守护进程”问题,找出Docker组中的用户

 grep 'docker' /etc/group 

然后运行docker cleanup命令(你可能想把它变成一个你在cron上运行的脚本),作为这些用户之一。 或与其他用户获得sudo访问权限并使用sudo:

 sudo docker rmi [image_name_here] 

这里是一个清理脚本示例( /usr/local/bin/clean_up_docker_stuff_on_ci_agent或类似的)的内容:

 #!/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 

正如Szymon Stepniak在他的回答中提到的,如果你使用docker> = 1.13,那么有更简单的选项。

cron示例(每小时20之后):

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

在使用下面的burnettk提供的脚本之后,似乎有些空间在经过更多的构build之后被释放,但是我回到了同一个地方,在我的EBS卷上没有空间。 根本没有意义,我将不得不增加更多的存储,并在我的月度账单上支付更多的AWS。

在做一些调查时,我发现每个版本都创build了大约7张图像(docker images -a),每张大约1.4GB,即9GB / build。 前两个标记为构build#和最新的标签。

所有这些图像都存储在这个服务器上并不重要,因为这个目的是为了构build,无论如何它们被推送到ECR。 所以我在脚本中添加了以下内容,只保留最新的Docker镜像:

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

最后,我还通过添加–rm参数来调整我的docker build命令,以便在构build之后移除中间容器。

 docker build --rm 

希望这是有帮助的!