清理Docker占用的磁盘空间
当你使用 docker,并且容器运行比较久,程序又疯狂的输入后,就会导致 docker的日志占用磁盘空间太大,这时候就需要清理一下了。
根据以住的解决问题的思路,这次记录下来,方便以后查阅,也给其遇到此问题的小伙伴一个参考。
查看磁盘空间
$ df -hl输出
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 的磁盘使用情况:
docker system dfTYPE 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 的镜像)。
docker system prune之前已经执行过了,所以看到是 0B
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: 0Bdocker system prune -af命令清理得更加彻底,可以将没有容器使用 Docker 镜像都删掉。
docker system prune -af可以放到释放空间 69.58MB,如果有很空未使用的镜像,容器和数据卷,释放的空间还是很可观的。
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 的镜像
docker rmi $(docker images | grep "^<none>" | awk "{print $3}")/var/lib/docker/overlay2 磁盘爆满
接下我们继续查看 df -hl磁盘空间
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命令,查看目录占用的磁盘空间
$ cd /var/lib/docker
$ du -h --max-depth=14.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 包含的我们容器自身的容量、产生的数据容量、产生的日志容量
$ cd containers
$ du -h --max-depth=1......
376K ./b84aafb5508aaa1fa5eb94d25997928ded41f6030b8f6785245cfbee40bd1c20
1.6G ./a89cd1bcecbc43be22bdb792f779059f6b03b716a724ac35cc6a80d70b3f83cd
48K ./b12c8ec602a84f8898b6d5b8318ce858788fe46c7040ed449e4a7051144d380b
21G ./807edbf4dbcf6cb4239eead128439c5e5667d56fe951f341fcf0325dab2d6a30
.....看到有一个 21G的目录 807edbf4dbcf6cb4239eead128439c5e5667d56fe951f341fcf0325dab2d6a30,这也是容器的ID。
复制容器ID的前10个字符,查看是哪个容器
docker ps | grep 807edbf4d | awk '{print $1 " " $2}'容器ID 镜像
807edbf4dbcf nginx:alpine我们先使用命令删除日志
$ truncate -s 0 /var/lib/docker/containers/807edbf4dbcf6cb4239eead128439c5e5667d56fe951f341fcf0325dab2d6a30/807edbf4dbcf6cb4239eead128439c5e5667d56fe951f341fcf0325dab2d6a30-json.log在使用 du -h --max-depth=1命令查看磁盘空间
$ du -h --max-depth=1......
376K ./b84aafb5508aaa1fa5eb94d25997928ded41f6030b8f6785245cfbee40bd1c20
1.6G ./a89cd1bcecbc43be22bdb792f779059f6b03b716a724ac35cc6a80d70b3f83cd
48K ./b12c8ec602a84f8898b6d5b8318ce858788fe46c7040ed449e4a7051144d380b
76K ./807edbf4dbcf6cb4239eead128439c5e5667d56fe951f341fcf0325dab2d6a30
......哇哦,看到了吗? 变为了 76K,这就是我们要的效果。
限制日志大小
可以参与官方文档自行尝试 Configure logging drivers
批量清理
程序员都是懒惰的,我们不想一个一个的去清理,那就写个脚本,自动化起来。
准备脚本
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,记得设置可执行权限,然后执行
$ ./clean_docker_container_log.sh
$ du -h --max-depth=1....
32K ./b84aafb5508aaa1fa5eb94d25997928ded41f6030b8f6785245cfbee40bd1c20
1.6M ./a89cd1bcecbc43be22bdb792f779059f6b03b716a724ac35cc6a80d70b3f83cd
32K ./b12c8ec602a84f8898b6d5b8318ce858788fe46c7040ed449e4a7051144d380b
32K ./5107888903e6f03d00ff5ea8454a6710fc07a9143dc42fa9a2996ad1c0d84d51
....还记得之前有个 1.6G的容器吗? 现在变成了1.6M,这就是我们要的效果。
自动化
接下来我们自动化起来,配置自动化执行上边的脚本,在对应的机器上配置crontab
- crontab -e
- 添加如下指令,替换你自己的文件路径
# clean docker container log
# 每周一3点执行
0 3 * * 1 sh /root/clean_docker_container_log.sh总结
总之不管是docker原因,还是其它原因,通过正确的方法,找到问题,去解决问题,才是最重要的。
希望以上会对你有所帮助,如果有不对的地方,欢迎指正。