前言
今天突然收到测试服务器的磁盘空间不足的报警,处理这种报警还是比较有经验的,肯定是docker
的日志占用了太多的磁盘空间导致,
之前处理后,比较懒,没有记录下来。
根据以往的处理经验,这种情况就很好解决,找到日志比较大的容器,删除日志,并调整日志级别即可解决。
我兼职打杂运维工作,我们团队所有组件都在云上飘着, 有很多的微服务组件,就需要使用服务发现,链路跟踪等配套设施,也少不了使用docker
。
最近为了能够方便的扩容,我们决定使用HashiCorp
家的轻量级的服务编排,安装了他家的几个docker服务,并把服务发现替换成了consul
。
运行了几天后,出现磁盘空间不足的报警。
当你使用docker
,并且容器运行比较久,程序又疯狂的输入后,就会导致docker
的日志占用磁盘空间太大,这时候就需要清理一下了。
根据以住的解决问题的思路,这次记录下来,方便以后查阅,也给其遇到此问题的小伙伴一个参考。
查看磁盘空间
输出
1
2
3
4
5
6
7
8
9
10
11
|
Filesystem Size Used Avail Use% Mounted on
tmpfs 794M 5.3M 789M 1% /run
/dev/vda1 148G 73G 69G 52% /
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 794M 0 794M 0% /run/user/0
overlay 148G 73G 69G 52% /var/lib/docker/overlay2/cb00c5676cee609000b56c66a73799105a373aad0700c5568f3d361a38089b78/merged
overlay 148G 73G 69G 52% /var/lib/docker/overlay2/64abd807c2a1b351718b5a3ddacd81ff65cb8a93b350a8ca7739a297b9800edb/merged
overlay 148G 73G 69G 52% /var/lib/docker/overlay2/f1100b6702df33a0fa0557b73ed56952cfa0385c182fd271c142b9d6204fdecd/merged
overlay 148G 73G 69G 52% /var/lib/docker/overlay2/44f6aa5c75d6e4f31747398e89bc369b63b9aad27623e8766636bbea58ae32d8/merged
........
|
看输出docker目录占用太多磁盘空间了,那就可以找对应的解决方案了。
docker system 命令
docker system df
命令,类似于 Linux 上的df命令,用于查看 Docker 的磁盘使用情况:
1
2
3
4
5
|
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 56 55 4.011GB 78.94MB (1%)
Containers 60 60 212.3MB 0B (0%)
Local Volumes 5 2 1.378kB 92B (6%)
Build Cache 0 0 0B 0B
|
可以看,Docker 镜像、容器、数据卷占用了多少磁盘空间。
docker system prune
命令可以用于清理磁盘,删除关闭的容器、无用的数据卷和网络,以及 dangling 镜像(即无 tag 的镜像)。
之前已经执行过了,所以看到是0B
1
2
3
4
5
6
7
8
|
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
|
docker system prune -af
命令清理得更加彻底,可以将没有容器使用 Docker 镜像都删掉。
1
|
$ docker system prune -af
|
可以放到释放空间69.58MB
,如果有很空未使用的镜像,容器和数据卷,释放的空间还是很可观的。
1
2
3
4
5
6
7
8
9
|
Deleted Images:
untagged: google/cadvisor:latest
untagged: google/cadvisor@sha256:815386ebbe9a3490f38785ab11bda34ec8dacf4634af77b8912832d4f85dca04
deleted: sha256:eb12107075737019dce2d795dd82f5a72197eb3c64b2140392eaad3ba3b8a34e
deleted: sha256:3385ca422448a4891ab08f24daec3f368197be67f5c786779651f1e85cffa89b
deleted: sha256:f62b8bf389e3af31123f6529d42fb6ef233e0677284af9f4d1db8513d46d6bc8
deleted: sha256:cd7100a72410606589a54b932cabd804a17f9ae5b42a1882bd56d263e02b6215
Total reclaimed space: 69.58MB
|
上边是自动清理,那就可以手动清理,网上一抓一大把,我这里就不做介绍了,我这里介绍一种比较简单的方法。
如 删除所有 tag 的镜像
1
|
$ docker rmi $(docker images | grep "^<none>" | awk "{print $3}")
|
/var/lib/docker/overlay2 磁盘爆满
接下我们继续查看df -hl
磁盘空间
1
2
3
4
5
6
7
8
9
10
|
Filesystem Size Used Avail Use% Mounted on
......
overlay 148G 73G 68G 52% /var/lib/docker/overlay2/cb00c5676cee609000b56c66a73799105a373aad0700c5568f3d361a38089b78/merged
overlay 148G 73G 68G 52% /var/lib/docker/overlay2/64abd807c2a1b351718b5a3ddacd81ff65cb8a93b350a8ca7739a297b9800edb/merged
overlay 148G 73G 68G 52% /var/lib/docker/overlay2/f1100b6702df33a0fa0557b73ed56952cfa0385c182fd271c142b9d6204fdecd/merged
overlay 148G 73G 68G 52% /var/lib/docker/overlay2/44f6aa5c75d6e4f31747398e89bc369b63b9aad27623e8766636bbea58ae32d8/merged
overlay 148G 73G 68G 52% /var/lib/docker/overlay2/2561c9ef9513026d3465f7e07364ce7f34a472f307c097685e28c522c1118b3f/merged
.......
|
依然还是/var/lib/docker/overlay2
容器输出的日志太大,导致目录占用的磁盘空间太大。
关于overlay2
的介绍,可以参考:
官方文档 Use the OverlayFS storage driver
官方文档 Use the OverlayFS storage driver
那就继续找元凶
,进行到/var/lib/docker
目录中,使用du -h --max-depth=1
命令,查看目录占用的磁盘空间
1
2
|
$ cd /var/lib/docker
$ du -h --max-depth=1
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
4.0K ./swarm
4.0K ./tmp
80K ./volumes
4.0K ./runtimes
304K ./network
108K ./buildkit
du: cannot access './overlay2/d41f6fcde566b05684ec84b0db63a2fd415abfe9ef3358a66fc6194eb80bc2ad': No such file or directory
du: cannot access './overlay2/d41f6fcde566b05684ec84b0db63a2fd415abfe9ef3358a66fc6194eb80bc2ad-init': No such file or directory
8.7G ./overlay2
16K ./plugins
35G ./containers
20M ./image
43G .
|
发现containers
目录占用空间最大,继续查看
Containers 包含的我们容器自身的容量、产生的数据容量、产生的日志容量
1
2
|
$ cd containers
$ du -h --max-depth=1
|
1
2
3
4
5
6
|
......
376K ./b84aafb5508aaa1fa5eb94d25997928ded41f6030b8f6785245cfbee40bd1c20
1.6G ./a89cd1bcecbc43be22bdb792f779059f6b03b716a724ac35cc6a80d70b3f83cd
48K ./b12c8ec602a84f8898b6d5b8318ce858788fe46c7040ed449e4a7051144d380b
21G ./807edbf4dbcf6cb4239eead128439c5e5667d56fe951f341fcf0325dab2d6a30
.....
|
看到有一个21G
的目录807edbf4dbcf6cb4239eead128439c5e5667d56fe951f341fcf0325dab2d6a30
,这也是容器的ID。
复制容器ID的前10个字符,查看是哪个容器
1
|
$ docker ps | grep 807edbf4d | awk '{print $1 " " $2}'
|
1
2
|
容器ID 镜像
807edbf4dbcf nginx:alpine
|
我们先使用命令删除日志
1
|
$ truncate -s 0 /var/lib/docker/containers/807edbf4dbcf6cb4239eead128439c5e5667d56fe951f341fcf0325dab2d6a30/807edbf4dbcf6cb4239eead128439c5e5667d56fe951f341fcf0325dab2d6a30-json.log
|
在使用du -h --max-depth=1
命令查看磁盘空间
1
2
3
4
5
6
|
......
376K ./b84aafb5508aaa1fa5eb94d25997928ded41f6030b8f6785245cfbee40bd1c20
1.6G ./a89cd1bcecbc43be22bdb792f779059f6b03b716a724ac35cc6a80d70b3f83cd
48K ./b12c8ec602a84f8898b6d5b8318ce858788fe46c7040ed449e4a7051144d380b
76K ./807edbf4dbcf6cb4239eead128439c5e5667d56fe951f341fcf0325dab2d6a30
......
|
哇哦,看到了吗? 变为了76K
,这就是我们要的效果。
限制日志大小
可以参与官方文档自行尝试 Configure logging drivers
批量清理
程序员都是懒惰的,我们不想一个一个的去清理,那就写个脚本,自动化起来。
准备脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
path=/var/lib/docker/containers/
echo ""
echo "========== Clean Docker Containers Log =========="
echo "Path: "$path
cd $path
for file in $(ls)
do
if [ -d $file ];then
echo $file"-json.log"
cat /dev/null > $file/$file-json.log
else
echo 0
fi
done
echo "========== Clean Docker Containers Log =========="
echo ""
|
把这保存为clean_docker_container_log.sh
,记得设置可执行权限,然后执行
1
2
3
|
$ ./clean_docker_container_log.sh
$ du -h --max-depth=1
|
1
2
3
4
5
6
|
....
32K ./b84aafb5508aaa1fa5eb94d25997928ded41f6030b8f6785245cfbee40bd1c20
1.6M ./a89cd1bcecbc43be22bdb792f779059f6b03b716a724ac35cc6a80d70b3f83cd
32K ./b12c8ec602a84f8898b6d5b8318ce858788fe46c7040ed449e4a7051144d380b
32K ./5107888903e6f03d00ff5ea8454a6710fc07a9143dc42fa9a2996ad1c0d84d51
....
|
还记得之前有个1.6G
的容器吗? 现在变成了1.6M,这就是我们要的效果。
自动化
接下来我们自动化起来,配置自动化执行上边的脚本,在对应的机器上配置crontab
- crontab -e
- 添加如下指令,替换你自己的文件路径
1
2
3
|
# clean docker container log
# 每周一3点执行
0 3 * * 1 sh /root/clean_docker_container_log.sh
|
总结
总之不管是docker原因,还是其它原因,通过正确的方法,找到问题,去解决问题,才是最重要的。
希望以上会对你有所帮助,如果有不对的地方,欢迎指正。
参考资料
Docker Container Log 文件限制
如何清理Docker占用的磁盘空间?
Docker - 清理Docker占用的磁盘空间