UpdateImages.sh - Docker 镜像批量更新脚本

温馨提醒
总结摘要
UpdateImages.sh 是一个用于批量更新 Docker 镜像的 Shell 脚本,支持白名单过滤、自动备份、回滚和详细报告生成,帮助高效管理 Docker 镜像。

UpdateImages.sh - Docker 镜像批量更新脚本

脚本功能

UpdateImages.sh 是一个功能强大的 Docker 镜像批量管理和更新脚本,能够自动拉取所有容器的最新镜像版本,重新创建容器,并提供完整的备份、回滚和报告功能。脚本支持白名单机制保护特定容器不被更新,并生成详细的操作日志和统计报告。

核心特性

  • 批量更新所有 Docker 容器的镜像到最新版本
  • 智能白名单机制,保护关键容器不被更新
  • 自动备份当前镜像和容器配置
  • 生成回滚脚本,支持快速恢复
  • 详细的操作日志和统计报告
  • 镜像拉取超时控制
  • 彩色输出便于识别不同状态
  • 支持 Docker Compose管理的容器

脚本依赖

系统工具依赖

  • docker:Docker 引擎(必需)
  • docker composedocker-compose:Docker Compose 工具(推荐)
  • bash:脚本运行环境(需要 bash shell)
  • jq:JSON 处理工具(用于解析 docker inspect 输出)
  • curl:用于下载镜像信息

权限要求

  • 需要 Docker 守护进程访问权限
  • 建议以 root用户或docker组成员运行

环境变量依赖

内置变量说明(可自定义配置)

脚本开头定义了以下可配置变量(第 6-17 行):

1
2
3
4
5
6
7
8
9
# Pull 超时时间(秒)
PULL_TIMEOUT=300  # 默认 5 分钟超时

# 白名单容器名称(跳过升级),填容器名
# 示例:WHITELIST=("mysql" "postgres-15.2" "php8_4_13")
WHITELIST=()  # 默认为空,不保护任何容器

# 备份根目录
BACKUP_ROOT="/opt/docker-upgrade-backup"  # 备份文件存储路径

配置文件说明

脚本运行时会自动创建以下文件和目录:

1
2
3
4
5
6
7
8
${BACKUP_ROOT}/
├── ${timestamp}/              # 时间戳命名的备份目录
│   ├── upgrade.log           # 详细的操作日志
│   ├── rollback.sh           # 自动生成的回滚脚本
│   ├── image_records.txt     # 镜像记录信息
│   ├── pull_results.txt      # 镜像拉取结果
│   ├── upgrade_results.txt   # 容器更新结果
│   └── report.txt            # 最终统计报告

参数用法

本脚本无命令行参数,通过修改脚本内变量进行定制:

  • 无参数模式:更新所有容器的镜像(除白名单外)
  • 自定义白名单:编辑脚本中的 WHITELIST数组
  • 调整超时时间:修改 PULL_TIMEOUT变量
  • 更改备份路径:修改 BACKUP_ROOT变量

使用方法

快速安装与使用

  1. 下载脚本

    1
    2
    3
    4
    5
    
    # 使用主下载地址
    bash <(curl -sL sc.eli1.top) UpdateImages download
    
    # 或使用备用地址
    bash <(curl -sL download.elisky.cn) UpdateImages download
  2. 赋予执行权限

    1
    
    chmod +x UpdateImages.sh
  3. 配置白名单(可选): 编辑 UpdateImages.sh脚本,修改第 14 行的 WHITELIST数组:

    1
    2
    
    # 保护重要容器不被更新
    WHITELIST=("mysql" "postgres" "redis-cache" "nginx-proxy")
  4. 运行脚本

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    # 直接运行(查看实时输出)
    sudo ./UpdateImages.sh
    
    # 后台运行并记录日志
    nohup sudo ./UpdateImages.sh > /var/log/docker_update.log 2>&1 &
    
    # 或使用 screen/tmux
    screen -S docker-update
    sudo ./UpdateImages.sh
    # 按 Ctrl+A 然后 D 分离会话

典型使用场景示例

场景 1:首次使用(测试环境)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 在生产环境使用前,建议在测试环境验证
# 编辑脚本,设置白名单保护关键服务
WHITELIST=("database" "cache")

# 运行脚本观察输出
sudo ./UpdateImages.sh

# 检查备份目录和日志
ls -la /opt/docker-upgrade-backup/
cat /opt/docker-upgrade-backup/*/upgrade.log

场景 2:生产环境定期更新

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 配置白名单保护关键业务容器
WHITELIST=("mysql-prod" "redis-sentinel" "monitoring-agent")

# 设置较长的超时时间(应对网络波动)
PULL_TIMEOUT=600  # 10 分钟

# 创建定时任务(每周日凌晨 2 点执行)
crontab -e
# 添加:
0 2 * * 0 /path/to/UpdateImages.sh >> /var/log/docker_weekly_update.log 2>&1

场景 3:回滚到更新前的版本

如果更新后出现问题,使用自动生成的回滚脚本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 查看备份目录
ls -la /opt/docker-upgrade-backup/

# 找到最近一次的备份
latest_backup=$(ls -t /opt/docker-upgrade-backup/ | head -1)

# 执行回滚脚本
sudo /opt/docker-upgrade-backup/${latest_backup}/rollback.sh

# 或者手动回滚特定容器
docker stop new_container_name
docker rm new_container_name
docker run [原容器参数...] old_image:tag

场景 4:查看详细报告

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 运行脚本后查看生成的报告
latest_report=$(ls -t /opt/docker-upgrade-backup/*/report.txt | head -1)
cat "$latest_report"

# 报告内容包括:
# - 成功更新的容器列表
# - 跳过更新的容器(白名单)
# - 失败的更新操作
# - 新旧镜像版本对比
# - 操作统计信息

场景 5:仅查看不更新(干运行模式)

临时修改脚本,只查看哪些容器会被更新但不实际执行:

1
2
3
4
5
6
7
8
# 在脚本的更新逻辑前添加 exit 0
# 找到 main 函数或更新循环部分,在第一行添加:
echo "=== DRY RUN MODE - No actual updates will be performed ==="
# ... 原有的检查逻辑 ...
exit 0  # 添加此行阻止实际更新

# 运行脚本查看将被更新的容器
sudo ./UpdateImages.sh

场景 6:集成到 CI/CD流程

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/bin/bash
# deploy.sh - 部署脚本中调用更新脚本

# 停止应用容器
docker-compose down

# 更新镜像
/path/to/UpdateImages.sh

# 重新启动应用
docker-compose up -d

# 检查健康状态
docker-compose ps

脚本执行流程详解

  1. 信息收集阶段

    • 扫描所有运行中的容器
    • 记录容器名称、镜像、镜像 ID等信息
    • 生成 image_records.txt文件
  2. 白名单过滤

    • 检查容器是否在 WHITELIST 中
    • 跳过受保护的容器
  3. 镜像拉取阶段

    • 对每个容器检查是否有新镜像
    • 并行拉取最新镜像(带超时控制)
    • 记录拉取结果到 pull_results.txt
  4. 容器更新阶段

    • 停止旧容器
    • 备份容器配置
    • 使用新镜像重新创建容器
    • 启动新容器
    • 记录更新结果到 upgrade_results.txt
  5. 清理和报告

    • 清理悬空镜像(dangling images)
    • 生成统计报告 report.txt
    • 创建回滚脚本 rollback.sh

实际应用场景

  • 定期维护更新:每周或每月定期更新所有容器镜像,获取安全补丁和功能改进
  • 安全应急响应:当发现重大安全漏洞时,快速更新相关容器镜像
  • 批量部署环境:在新环境中快速更新所有镜像到最新版本
  • DevOps自动化:集成到 CI/CD流水线,实现自动化的镜像更新和部署
  • 多环境管理:统一管理开发、测试、生产环境的容器镜像版本
  • 容器迁移:在服务器迁移时,先更新所有镜像再导出配置
  • 版本升级:配合应用升级,批量更新相关容器镜像

注意事项

白名单策略

  • 必须保护的容器类型

    • 数据库容器(MySQL、PostgreSQL、MongoDB等)
    • 缓存容器(Redis、Memcached)
    • 消息队列(RabbitMQ、Kafka)
    • 监控代理(Prometheus、Grafana Agent)
    • 反向代理(Nginx、Traefik)- 如果在用其管理其他容器
  • 谨慎更新的容器

    • 有持久化数据卷的容器
    • 配置复杂的容器
    • 依赖特定版本的容器

备份策略

  • 自动备份位置

    1
    2
    
    BACKUP_ROOT="/opt/docker-upgrade-backup"
    # 每次运行都会创建新的时间戳目录
  • 手动备份建议

    1
    2
    3
    
    # 运行脚本前手动备份重要数据
    docker export $(docker ps -q) > backup.tar
    docker volume ls > volumes_backup.txt
  • 备份保留策略

    1
    2
    
    # 配置 logrotate 或 cron 清理旧备份
    find /opt/docker-upgrade-backup -type d -mtime +30 -exec rm -rf {} \;

回滚准备

  • 回滚脚本验证

    1
    2
    3
    4
    5
    
    # 更新后立即检查回滚脚本
    cat /opt/docker-upgrade-backup/*/rollback.sh
    
    # 测试回滚(在测试环境)
    sudo bash /opt/docker-upgrade-backup/*/rollback.sh --dry-run
  • 手动回滚步骤

    1
    2
    3
    4
    5
    6
    7
    8
    
    # 1. 停止新容器
    docker stop container_name
    
    # 2. 删除新容器
    docker rm container_name
    
    # 3. 使用旧镜像重新启动
    docker run -d --name container_name old_image:tag

网络和性能考虑

  • 镜像拉取超时

    • 默认 300 秒(5 分钟)
    • 大镜像(如 Windows基础镜像)可能需要更长时间
    • 网络不稳定环境建议设置为 600-900 秒
  • 并发控制

    • 脚本默认串行拉取镜像,避免占用过多带宽
    • 如需并行拉取,需修改脚本逻辑

兼容性说明

  • Docker 版本:支持 Docker 18.09及以上版本
  • Docker Compose:支持 v1和v2版本
  • 容器存储驱动:兼容 overlay2、aufs、devicemapper等

错误处理

  • 常见失败原因

    • 网络连接问题导致镜像拉取失败
    • 磁盘空间不足
    • 端口冲突
    • 卷挂载路径不存在
    • 环境变量缺失
  • 调试方法

    1
    2
    3
    4
    5
    6
    7
    8
    
    # 查看详细日志
    tail -f /opt/docker-upgrade-backup/*/upgrade.log
    
    # 检查 Docker 守护进程状态
    systemctl status docker
    
    # 验证镜像是否存在
    docker images | grep image_name

最佳实践

  1. 先在测试环境验证:确保脚本与您的环境兼容
  2. 建立变更窗口:选择业务低峰期执行更新
  3. 通知相关人员:更新前通知团队可能出现的短暂中断
  4. 健康检查:更新后验证所有容器的健康状态
  5. 版本记录:记录每次更新的镜像版本和时间
  6. 监控告警:更新后加强监控,及时发现异常
  7. 逐步推广:从非关键业务开始,逐步扩展到核心业务

限制和约束

  • 不支持的操作

    • 不会更新 Docker Swarm 服务的镜像
    • 不会处理 Kubernetes Pod
    • 不会更新通过 systemd管理的容器
  • 特殊情况

    • 使用 latest 标签的镜像可能不会触发更新检测
    • 本地构建的镜像(无远程仓库)不会被更新
    • 已停止的容器不会被包含在更新范围内