logo

鱼肚的博客

Don't Repeat Yourself

记一次Gitlab Runner服务器磁盘爆满问题

一早起来就发现有几个CI任务失败了,看docker错误日志是磁盘空间不足。我顿时就纳闷起来了。

因为虽然CI服务器磁盘空间只有500GB,还有大量的docker cache,但是我设置的计划任务每小时都会执行一次docker system prune,不应该会爆满。而且两三天前刚使用docker volume prune清理过一次volume,就更不应该了。

排查问题

再怎么觉得不科学,事实也已经存在了,只好去排查原因。

先登录到CI服务器上,查看磁盘使用量,发现为/var/lib/docker单独设置的分区已经满了。这里还好是单独把它分了出来,不然能不能ssh登录还两说呢。

登录上之后,先手动执行docker system prune,手动挤出来一点空间。

再使用docker system df查看使用量:

TYPETOTALACTIVESIZERECLAIMABLE
Images1669140.6GB133GB (94%)
Containers457290.1GB0B
Local Volumes28286.649GB0B (0%)
Build Cache000B0B

可得到一个类似上表的结果。(因最初的日志已不存在,此处数据是根据当时场景大致伪造的)。

可以看出磁盘主要是被容器使用掉了,RECLAIMABLE为0,是因为容器还在运行中。

检查容器磁盘使用

确定是容器在占用磁盘之后,使用docker ps -s查看运行中的容器列表,输出表格中最后一列是其磁盘占用。分实际体积和Virtual体积两部分。

我理解实际体积为运行时产生数据的体积,Virtual体积是实体体积+基础镜像体积。

找到磁盘占用最大的一个镜像,使用docker exec -it <container id> sh进入镜像的内部。再使用du -h -d 1 .分析各子目录的磁盘占用。

确定原因

占用磁盘最大的容器,是一个runner。通过du命令层层定位之后,最后确定到原因是在一个子工程目录内,其webpack构建失败产生了core dump文件,以.core结尾。因为core dump文件体积很大,且产生了多个,所以占据了很大的体积。

恢复

要恢复磁盘也很简单,直接重启这个容器就可以了。

docker restart <container id>

防止问题再次发生

那如何防止问题再次发生呢?

我第一时间想到的,就是像限制 cpu 和 内存一样,限制容器可使用的磁盘空间。

查了下Docker新版本中真的支持这个选项:

Set storage driver options per container

然而不幸的是,我的CI服务器使用的overlay2存储引擎,搭建在ext4文件系统之上,而这个选项只有在使用搭建在 xfs 上的overlay2、btrfs等存储引擎的时候才支持。

那么暂时只能从程序角度来处理了。