15.11.10 生产变更与回滚策略
生产变更必须遵循“可预期、可回退、可验证”的原则。在容器化场景中,变更对象包括镜像版本、配置文件、运行参数、编排文件与运行时资源策略。变更前需明确影响范围与依赖关系,梳理服务拓扑、流量入口、配置中心与外部依赖,形成变更清单与风险评估,并确保镜像、配置、数据与编排文件具备可追溯版本。
变更准备与基线冻结(示例)#
目标:在变更前冻结基线,确保镜像与编排文件可回溯。
# 1) 记录当前运行镜像与容器信息
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
# 2) 导出当前运行容器的完整配置(作为回退参考)
docker inspect webapp > /var/backups/docker/webapp.inspect.json
# 3) 拉取新版本镜像并打上稳定标签
docker pull registry.example.com/app/webapp:1.2.3
docker tag registry.example.com/app/webapp:1.2.3 registry.example.com/app/webapp:stable-1.2.3
# 4) 备份当前 compose 文件
cp /opt/app/docker-compose.yml /var/backups/docker/docker-compose.yml.$(date +%F)
命令解释
- docker ps --format:以表格列出容器与镜像版本,便于差异比对。
- docker inspect:导出容器配置,回滚时可复原环境变量、端口、挂载等。
- docker tag:为镜像打稳定标签,保证回滚可快速拉取。
发布策略与执行示例(滚动+灰度)#
目标:分批、小步、可观测,降低变更风险。
Compose 示例:设置健康检查、资源限制、版本标签
# /opt/app/docker-compose.yml
version: "3.8"
services:
webapp:
image: registry.example.com/app/webapp:1.2.3
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
deploy:
replicas: 2
healthcheck:
test: ["CMD", "curl", "-f", "http://127.0.0.1:8080/health"]
interval: 10s
timeout: 3s
retries: 3
执行步骤
# 1) 仅替换一个实例进行灰度验证(示例为手动滚动)
docker-compose up -d --scale webapp=1
# 2) 观察健康检查与日志
docker ps --filter name=webapp
docker logs --tail 200 -f webapp
# 3) 通过外部探测验证业务功能
curl -i http://127.0.0.1:8080/health
预期效果
- 健康检查返回 200,日志无报错,实例稳定运行。
- 验证通过后再逐步扩容到全量副本。
回滚策略与命令示例#
回滚策略应覆盖镜像回退、配置回退、数据回退与流量回退四类。
1) 镜像回退#
# 回退到上一个稳定版本
docker stop webapp
docker rm webapp
docker run -d --name webapp -p 8080:8080 \
registry.example.com/app/webapp:stable-1.2.2
2) 配置回退#
# 使用备份的 compose 文件回退配置
cp /var/backups/docker/docker-compose.yml.2024-01-20 /opt/app/docker-compose.yml
docker-compose up -d
3) 数据回退(示例:只读保护 + 备份恢复)#
# 变更前设置数据库为只读(示例)
mysql -h db -u root -p -e "SET GLOBAL read_only=ON;"
# 恢复备份(示例)
mysql -h db -u root -p appdb < /var/backups/db/appdb_2024-01-20.sql
# 恢复写入
mysql -h db -u root -p -e "SET GLOBAL read_only=OFF;"
4) 流量回退(示例:Nginx upstream 切换)#
# /etc/nginx/conf.d/upstream.conf
upstream webapp {
server 10.0.0.10:8080; # old
# server 10.0.0.20:8080; # new (回滚时注释)
}
nginx -s reload
变更验收与监控检查(示例)#
# 资源与运行态检查
docker stats --no-stream
docker events --since 10m
# 关键指标:错误率/延迟/重启次数(示例)
docker inspect --format='{{.RestartCount}}' webapp
验收清单
- 核心路径功能通过
- 资源占用稳定、无异常重启
- 日志无新出现的 ERROR/EXCEPTION
常见故障与排错#
场景:新版本容器不断重启
排查步骤:
# 1) 查看容器退出原因
docker logs --tail 200 webapp
# 2) 查看健康检查失败情况
docker inspect --format='{{json .State.Health}}' webapp | jq
# 3) 回滚
docker run -d --name webapp -p 8080:8080 \
registry.example.com/app/webapp:stable-1.2.2
场景:变更后请求延迟升高
排查建议:
- 对比新旧镜像 CPU/内存占用(docker stats)。
- 检查依赖服务连接数与超时配置(如 DB、Redis)。
练习#
- 使用
docker inspect导出容器配置并恢复一个相同的容器。 - 模拟发布新镜像,将
healthcheck设为失败,观察容器重启与回滚流程。 - 设计一个灰度发布方案:先发布 10% 流量并验证后全量发布。