自动化脚本如何清理Docker镜像

wen 实用脚本 1

本文目录导读:

自动化脚本如何清理Docker镜像

  1. 基础清理脚本
  2. 更高级的清理脚本
  3. 定时任务配置
  4. 保留特定镜像的脚本
  5. 结合监控的清理脚本
  6. 使用建议

我来介绍几种自动化清理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

使用建议

  1. 先测试再部署

    # 先查看哪些会被删除
    docker system prune -a --volumes --dry-run
  2. 设置执行权限

    chmod +x docker-cleanup.sh
  3. 定期检查日志

    tail -f /var/log/docker-cleanup.log
  4. 注意点

    • 某些镜像可能正在被使用,删除前确保不再需要
    • 建议先在测试环境验证脚本
    • 对于生产环境,使用 smart 模式更安全

这些脚本可以根据你的具体需求进行调整和组合使用。

抱歉,评论功能暂时关闭!