背景
服务器上运行Docker后,会定期产生一些遗留文件,若不定期清理,则磁盘空间会被打满。
主要有如下遗留存储需要清理
- 停止的Docker
- 未被使用的Network
- 未被使用的Volume
- 未被使用的Image
- Docker build Cache(特别是用来当作制作Docker镜像的机器,比如Jenkins Agent,会遗留大量的build Cache)
可以使用如下命令查看docker当前占用的资源情况
docker system df
程序
Feature
功能 | 说明 |
---|---|
设置Docker磁盘清理程序(清理24小时前的未被使用的数据,可以自定义延长此时间) | 使用docker自带prune 比如 docker image prune |
设置定时任务,定期执行清理程序 并记录清理日志 | 使用Crontab |
脚本
#!/bin/sh
# onekey_reclaim_docker_disk_space.sh
## if input param is now,execute the reclaim script right now
help() {
echo "Usage:"
echo "reclaim_docker_disk_space.sh [-r|-h] "
echo "Description:"
echo "-r, reclaim the disk space right now"
echo "-h, show script usage"
exit 1
}
run_now=false
while getopts 'h:r' OPT; do
case $OPT in
r) run_now=true ;;
h) help ;;
?) help ;;
esac
done
clear_docker_script="/devops/reclaim_docker_disk_space.sh"
generate_clear_script() {
mkdir -p /devops
if [ ! -f $clear_docker_script ]; then
touch ${clear_docker_script}
chown root:root ${clear_docker_script}
chmod +x ${clear_docker_script}
fi
cat >${clear_docker_script} <<"EOF"
#!/bin/sh
#
# Clear Docker Disk Space
# before the until_time
# the unused docker image,container,namespace,docker build cache will be reclaimed
#
until_time="24h"
reclaim_docker_disk_space() {
docker volume prune -f
expect_major_no=17
expect_minor_no=6
docker_version=$(docker version --format '{{.Server.Version}}')
major_no=$(echo "$docker_version" | awk '{print int($0)}')
minor_no=$(echo "$docker_version" | awk '{print int($1)}')
if [ "${major_no}" -ge $expect_major_no ]; then
if [ "${minor_no}" -ge $expect_minor_no ]; then
echo "current docker version: $docker_version "
docker system prune --filter "until=${until_time}" -f
# After 17.06.1,the volumes will be reclaimed individual
docker volume prune -f
fi
else
docker system prune --filter "until=${until_time}" -f
fi
}
main() {
echo "=== start to reclaim docker disk space,until ${until_time} ==="
reclaim_docker_disk_space
echo "=== reclaim docker disk space success ==="
}
main
EOF
}
create_cron_task() {
# execute the shell at 5 am
crond_log_file="/var/log/crond.log"
if [ ! -f $crond_log_file ]; then
mkdir -p /var/log
touch $crond_log_file
fi
clear_docker_cron_express="0 5 * * * /bin/sh ${clear_docker_script} >>${crond_log_file} 2>&1"
user_root_cron_file="/var/spool/cron/root"
if [ ! -f $user_root_cron_file ]; then
mkdir -p /var/spool/cron
touch $user_root_cron_file
fi
# todo update the crontab expression
result=$(cat <$user_root_cron_file | grep -c "${clear_docker_script}")
if [ "$result" -eq 0 ]; then
echo "$clear_docker_cron_express" >>$user_root_cron_file
echo "Successfully append the clear_docker_script to the /var/spool/cron/root "
fi
systemctl reload crond
echo "Successfully Create the Clear_Docker_Disk_Space Cron Job."
echo "=== Now Showing the Cron Table ==="
crontab -l
}
run_now() {
/bin/sh ${clear_docker_script}
}
main() {
generate_clear_script
create_cron_task
if [ $run_now == true ]; then
run_now
fi
}
main
效果
会在Crontab中添加一个定时任务,每天凌晨5点清理前24小时的docker无用数据。
并且可以在 /var/log/crond.log中查看清理信息。
查看清理消息