本文目录导读:

我来介绍几种自动化清理Docker镜像的方法:
基础清理脚本
#!/bin/bash # docker-cleanup.sh echo "=== Docker 镜像清理开始 ===" # 清理悬空镜像(dangling images) echo "清理悬空镜像..." docker image prune -f # 清理未使用的镜像(未被容器使用的) echo "清理未使用的镜像..." docker image prune -a -f # 清理所有停止的容器 echo "清理停止的容器..." docker container prune -f # 清理未使用的卷 echo "清理未使用的卷..." docker volume prune -f # 清理构建缓存 echo "清理构建缓存..." docker builder prune -f echo "=== 清理完成 ==="
更高级的清理脚本
#!/bin/bash
# docker-cleanup-advanced.sh
# 设置阈值(8GB)
THRESHOLD=8000000000
# 清理函数
cleanup_docker() {
echo "开始清理 Docker 资源..."
# 清理所有未使用的资源
docker system prune -a --volumes -f
# 或者选择性清理
# docker image prune -a -f
# docker container prune -f
# docker volume prune -f
# docker network prune -f
echo "清理完成"
}
# 智能清理(基于磁盘使用率)
cleanup_if_full() {
local usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
if [ $usage -gt 80 ]; then
echo "磁盘使用率 ${usage}%,超过80%,执行清理..."
cleanup_docker
else
echo "磁盘使用率 ${usage}%,无需清理"
fi
}
# 基于时间清理(删除7天前的镜像)
cleanup_by_age() {
echo "清理7天前的镜像..."
docker images --format "{{.Repository}}:{{.Tag}} {{.CreatedAt}}" | \
awk '{if ($2 < "'$(date -d "7 days ago" +%Y-%m-%d)'") print $1}' | \
while read image; do
docker rmi "$image" 2>/dev/null || true
done
}
# 保留特定数量的镜像版本
keep_last_versions() {
local count=3
echo "保留每个镜像的最新 ${count} 个版本..."
for image in $(docker images --format "{{.Repository}}" | sort -u); do
versions=$(docker images "$image" --format "{{.Tag}}" | sort -r)
i=0
for version in $versions; do
i=$((i+1))
if [ $i -gt $count ]; then
echo "删除 ${image}:${version}"
docker rmi "${image}:${version}" 2>/dev/null || true
fi
done
done
}
# 主函数
main() {
case "${1:-full}" in
full)
cleanup_docker
;;
smart)
cleanup_if_full
;;
age)
cleanup_by_age
;;
keep)
keep_last_versions
;;
*)
echo "用法: $0 {full|smart|age|keep}"
exit 1
;;
esac
}
main "$@"
定时任务配置
Linux Crontab
# 编辑 crontab crontab -e # 每天凌晨2点执行清理 0 2 * * * /path/to/docker-cleanup.sh >> /var/log/docker-cleanup.log 2>&1 # 每周日执行一次全面清理 0 3 * * 0 /path/to/docker-cleanup-advanced.sh full >> /var/log/docker-cleanup.log 2>&1
Systemd Timer (更推荐)
# /etc/systemd/system/docker-cleanup.service [Unit] Description=Docker Cleanup Service After=docker.service [Service] Type=oneshot ExecStart=/path/to/docker-cleanup-advanced.sh smart User=root
# /etc/systemd/system/docker-cleanup.timer [Unit] Description=Run Docker cleanup daily [Timer] OnCalendar=daily Persistent=true [Install] WantedBy=timers.target
保留特定镜像的脚本
#!/bin/bash
# docker-cleanup-with-excludes.sh
# 要保留的镜像列表
KEEP_IMAGES=(
"nginx:latest"
"nginx:alpine"
"mysql:8.0"
"redis:alpine"
"ubuntu:20.04"
)
# 获取所有镜像
all_images=$(docker images --format "{{.Repository}}:{{.Tag}}")
for image in $all_images; do
# 检查是否需要保留
keep=false
for keep_image in "${KEEP_IMAGES[@]}"; do
if [ "$image" == "$keep_image" ]; then
keep=true
break
fi
done
# 删除不保留的悬空镜像或特定tag的镜像
if [ "$keep" == false ] && [ "$(echo $image | grep -c '<none>')" -gt 0 ]; then
echo "删除镜像: $image"
docker rmi "$image" 2>/dev/null || true
fi
done
结合监控的清理脚本
#!/bin/bash
# docker-cleanup-monitored.sh
# 日志配置
LOG_FILE="/var/log/docker-cleanup.log"
ALERT_EMAIL="admin@example.com"
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
# 清理前记录空间使用
cleanup_before() {
log_message "清理前磁盘使用:"
df -h / | tail -1 >> "$LOG_FILE"
log_message "清理前Docker占用:"
docker system df >> "$LOG_FILE"
}
# 清理后记录空间使用
cleanup_after() {
log_message "清理后磁盘使用:"
df -h / | tail -1 >> "$LOG_FILE"
log_message "清理后Docker占用:"
docker system df >> "$LOG_FILE"
}
# 清理并发送通知
cleanup_and_notify() {
cleanup_before
# 清理操作
docker system prune -a -f --volumes >> "$LOG_FILE" 2>&1
cleanup_after
# 如果清理超过一定量,发送邮件通知
if [ $? -eq 0 ]; then
mail -s "Docker Cleanup Completed" "$ALERT_EMAIL" < "$LOG_FILE"
fi
}
# 执行清理
cleanup_and_notify
使用建议
-
先测试再部署:
# 先查看哪些会被删除 docker system prune -a --volumes --dry-run
-
设置执行权限:
chmod +x docker-cleanup.sh
-
定期检查日志:
tail -f /var/log/docker-cleanup.log
-
注意点:
- 某些镜像可能正在被使用,删除前确保不再需要
- 建议先在测试环境验证脚本
- 对于生产环境,使用
smart模式更安全
这些脚本可以根据你的具体需求进行调整和组合使用。