Jenkins 构建机器突然空间不足

接收到警告

今天突然收到 Jenkins 的警告提醒,数据目录 "/var/lib/jenkins" 就快要空间不足了。

但我回想了下这台机器只有一个 Jenkins 运行,项目构建也不需要那么多的磁盘空间。因为我每次构建 Dockerfile 后push完就会rm掉。那么磁盘空间怎么会占用那么大呢?

开始排查

带着这个疑问我先排查了 Jenkins 的工作目录,使用 du -h --max-depth=0 统计也只有5.2Gb。 -_-!

[ec2-user@ip-10-16-21-98 ~]$ df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        1.9G     0  1.9G   0% /dev
tmpfs           1.9G     0  1.9G   0% /dev/shm
tmpfs           1.9G  496K  1.9G   1% /run
tmpfs           1.9G     0  1.9G   0% /sys/fs/cgroup
/dev/nvme0n1p1   50G   50G  713M  99% /
tmpfs           389M     0  389M   0% /run/user/1000
[ec2-user@ip-10-16-21-98 ~]$ cd /var/lib/jenkins/
[ec2-user@ip-10-16-21-98 jenkins]$ sudo du -h --max-depth=0
5.2G	.
[ec2-user@ip-10-16-21-98 jenkins]$

看来方向不对,排查下日志的目录

[ec2-user@ip-10-16-21-98 ~]$ cd /var/log/
[ec2-user@ip-10-16-21-98 log]$ sudo du -h --max-depth=0
3.2G	.
[ec2-user@ip-10-16-21-98 log]$

看到日志占用了3.2G,然后进去看到是 journal 占用了比较多。先清理一下日志,给大家列一下常见的日志目录:

/var/log/journal        #日志管理服务
/var/log/messages       #常规日志消息
/var/log/boot           #系统启动日志
/var/log/debug          #调试日志消息
/var/log/auth.log       #用户登录和身份验证日志
/var/log/daemon.log     #运行squid,ntpd等其他日志消息到这个文件
/var/log/dmesg          #Linux内核环缓存日志
/var/log/dpkg.log       #所有二进制包日志都包括程序包安装和其他信息
/var/log/faillog        #用户登录日志文件失败
/var/log/kern.log       #内核日志文件
/var/log/lpr.log        #打印机日志文件
/var/log/mail.*         #所有邮件服务器消息日志文件
/var/log/mysql.*        #MySQL服务器日志文件
/var/log/user.log       #所有用户级日志
/var/log/xorg.0.log     #X.org日志文件
/var/log/apache2/*      #Apache Web服务器日志文件目录
/var/log/lighttpd/*     #Lighttpd Web服务器日志文件目录
/var/log/fsck/*         #fsck命令日志
/var/log/apport.log     #应用程序崩溃报告/日志文件
/var/log/syslog         #系统日志
/var/log/ufw            #ufw防火墙日志
/var/log/gufw           #gufw防火墙日志

OK,清理 journal 日志常用方法就是可直接rm或者通过 journalctl 管理。我就直接通过 journalctl --vacuum-size=500M 限制日志文件为500M

[ec2-user@ip-10-16-21-98 journal]$ sudo journalctl --vacuum-size=500M
Deleted archived journal /var/log/journal/ec220d28f3 ... ea33.journal (72.0M).
Deleted archived journal /var/log/journal/ec220d28f3 ... a884.journal (8.0M).
Deleted archived journal /var/log/journal/ec220d28f3 ... a884.journal (80.0M).
Deleted archived journal /var/log/journal/ec220d28f3 ... a1f5.journal (64.0M).
...
Vacuuming done, freed 2.73G of archived journals on disk.
[ec2-user@ip-10-16-21-98 journal]$ sudo du -h --max-depth=0
473M	.
[ec2-user@ip-10-16-21-98 journal]$ df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        1.9G     0  1.9G   0% /dev
tmpfs           1.9G     0  1.9G   0% /dev/shm
tmpfs           1.9G  496K  1.9G   1% /run
tmpfs           1.9G     0  1.9G   0% /sys/fs/cgroup
/dev/nvme0n1p1   50G   50G  873M  99% /
tmpfs           389M     0  389M   0% /run/user/1000

清理完 journal 日志后想到这台机器还有一个Docker服务在跑。过去看看…

当你cd过去日志目录发现 Permission denied ,这时候只需提一下权限就好了.

[ec2-user@ip-10-16-21-98 ~]$ cd /var/lib/docker/
-bash: cd: /var/lib/docker/: Permission denied
[ec2-user@ip-10-16-21-98 ~]$
[ec2-user@ip-10-16-21-98 ~]$
[ec2-user@ip-10-16-21-98 ~]$ sudo su
[root@ip-10-16-21-98 ec2-user]$ cd /var/lib/docker/
[root@ip-10-16-21-98 docker]$ sudo du -h --max-depth=1
574M	./containers
0	./plugins
32G	./overlay2
75M	./image
24K	./volumes
0	./trust
52K	./network
0	./swarm
16K	./builder
88K	./buildkit
0	./tmp
0	./runtimes
33G	.
[root@ip-10-16-21-98 docker]$

… 通过 du -h --max-depth=1 查看当前目录下所有的文件夹占用空间发现问题了,原来是被 overlay2 占用了,他是Docker的存储驱动目录。

先看看Docker images有没有问题

[root@ip-10-16-21-98 overlay2]$ docker images
REPOSITORY          TAG             IMAGE ID       CREATED             SIZE
<none>              <none>          98b1f4cb968c   42 minutes ago      441MB
<none>              <none>          7bb67c658f3a   About an hour ago   441MB
<none>              <none>          54394879bea5   About an hour ago   441MB
<none>              <none>          b2c53a4b0181   About an hour ago   441MB
<none>              <none>          c6639b736929   About an hour ago   441MB
<none>              <none>          5098dffd5958   About an hour ago   441MB
<none>              <none>          50d9ff11488d   2 hours ago         441MB
<none>              <none>          3e2979f1ff5f   2 hours ago         441MB
<none>              <none>          65f07f7e355b   2 hours ago         441MB
<none>              <none>          8354c49e5fac   3 hours ago         441MB
<none>              <none>          cfe5a4e9565a   3 hours ago         441MB
... 此处省略n个 none:none images ...
golang              alpine          19b59f022241   8 months ago        301MB
nginx               latest          35c43ace9216   9 months ago        133MB
java                8-jre-alpine    fdc893b19a14   4 years ago         108MB

那么问题来了,那么多 none:none 的images是怎么来的?看回构建shell找到问题,因为在构建前原来的images还没有rm,就会出现 none:none 的images了。

清理磁盘

找到问题我们就解决问题,清理 none:none 的images有两种方式,推荐使用第一种:

  1. docker image prune 命令允许您清理未使用的图像

  2. 通过shell删除

    docker images|grep none|awk '{print $3 }'|xargs docker rmi

那么我们就使用 docker image prune 清理

[root@ip-10-16-21-98 docker]$ docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
deleted: sha256:40240973fb3084ed3e2188189ac3f5fa4484aab8e85c647d34ac26e887c02ac4
deleted: sha256:79c97ee91f5159545de1f1e941eae7128151ffee293d599d71564752488ed68f
deleted: sha256:1f0d8929a1f3ae782f8de77acdbe9bdc849c1c89909a43f4bb4b02ed9db37ec4
deleted: sha256:f43b16868618e680843bd71ec210d3afcb8de585481e9b5eb86d637ed1ef1202
...

Total reclaimed space: 30.75GB
[root@ip-10-16-21-98 docker]$

OK,清理完成30.75GB的 dangling images,再看看现在磁盘使用情况

[ec2-user@ip-10-16-21-98 ~]$ df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        1.9G     0  1.9G   0% /dev
tmpfs           1.9G     0  1.9G   0% /dev/shm
tmpfs           1.9G  496K  1.9G   1% /run
tmpfs           1.9G     0  1.9G   0% /sys/fs/cgroup
/dev/nvme0n1p1   50G   20G   31G  39% /
tmpfs           389M     0  389M   0% /run/user/1000
[ec2-user@ip-10-16-21-98 ~]$

防止再次发生思路

  1. 完善部署脚本,在 docker push 完成后删除images与产生的 dangling images
  2. 创建定时任务清理 dangling images

Jenkins 构建机器突然空间不足
https://whh.zone/2021/11/jenkins-disk-cleanup/
作者
Simple
发布于
2021年11月27日
许可协议