总结摘要
UpdateImages.sh 是一个用于批量更新 Docker 镜像的 Shell 脚本,支持白名单过滤、自动备份、回滚和详细报告生成,帮助高效管理 Docker 镜像。
UpdateImages.sh - Docker 镜像批量更新脚本
脚本功能
UpdateImages.sh 是一个功能强大的 Docker 镜像批量管理和更新脚本,能够自动拉取所有容器的最新镜像版本,重新创建容器,并提供完整的备份、回滚和报告功能。脚本支持白名单机制保护特定容器不被更新,并生成详细的操作日志和统计报告。
核心特性:
- 批量更新所有 Docker 容器的镜像到最新版本
- 智能白名单机制,保护关键容器不被更新
- 自动备份当前镜像和容器配置
- 生成回滚脚本,支持快速恢复
- 详细的操作日志和统计报告
- 镜像拉取超时控制
- 彩色输出便于识别不同状态
- 支持 Docker Compose管理的容器
脚本依赖
系统工具依赖
docker:Docker 引擎(必需)docker compose或docker-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
2
3
4
5
| # 使用主下载地址
bash <(curl -sL sc.eli1.top) UpdateImages download
# 或使用备用地址
bash <(curl -sL download.elisky.cn) UpdateImages download
|
赋予执行权限:
1
| chmod +x UpdateImages.sh
|
配置白名单(可选):
编辑 UpdateImages.sh脚本,修改第 14 行的 WHITELIST数组:
1
2
| # 保护重要容器不被更新
WHITELIST=("mysql" "postgres" "redis-cache" "nginx-proxy")
|
运行脚本:
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
|
脚本执行流程详解
信息收集阶段:
- 扫描所有运行中的容器
- 记录容器名称、镜像、镜像 ID等信息
- 生成
image_records.txt文件
白名单过滤:
- 检查容器是否在 WHITELIST 中
- 跳过受保护的容器
镜像拉取阶段:
- 对每个容器检查是否有新镜像
- 并行拉取最新镜像(带超时控制)
- 记录拉取结果到
pull_results.txt
容器更新阶段:
- 停止旧容器
- 备份容器配置
- 使用新镜像重新创建容器
- 启动新容器
- 记录更新结果到
upgrade_results.txt
清理和报告:
- 清理悬空镜像(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
|
最佳实践
- 先在测试环境验证:确保脚本与您的环境兼容
- 建立变更窗口:选择业务低峰期执行更新
- 通知相关人员:更新前通知团队可能出现的短暂中断
- 健康检查:更新后验证所有容器的健康状态
- 版本记录:记录每次更新的镜像版本和时间
- 监控告警:更新后加强监控,及时发现异常
- 逐步推广:从非关键业务开始,逐步扩展到核心业务
限制和约束
不支持的操作:
- 不会更新 Docker Swarm 服务的镜像
- 不会处理 Kubernetes Pod
- 不会更新通过 systemd管理的容器
特殊情况:
- 使用 latest 标签的镜像可能不会触发更新检测
- 本地构建的镜像(无远程仓库)不会被更新
- 已停止的容器不会被包含在更新范围内