当补丁导致容器启动失败时的回滚策略
解读
国内互联网节奏快、灰度窗口短,补丁一旦引入启动失败,必须在分钟级完成回滚,否则直接影响 SLA 与资损。面试官想确认:
- 你是否具备**“可回滚”设计前置意识**(镜像版本化、不可变基础设施);
- 能否在Swarm/K8s 双栈环境下,用 Docker 原生能力快速止血;
- 是否熟悉国内云厂商镜像仓库的限速与配额,保证回滚镜像秒级拉取;
- 能否把回滚动作沉淀为CI/CD 模板,下次无人值守。
知识点
- 镜像不可变原则:tag 永不复用,生产只用 digest 或
v1.2.3-<git-sha>级 tag。 - Docker Compose v3.7+ rollback:
docker stack deploy --rollback-order stop-first --rollback-parallelism 1可单批串行回滚,避免雪崩。 - Swarm 任务历史:
docker service ps --no-trunc查看失败原因,docker service rollback一键回到上一版本,默认 5 分钟内完成。 - 健康检查与重启策略:
HEALTHCHECK --interval=5s --retries=3配合restart-policy: on-failure:3,连续失败即触发回滚。 - 镜像预热:在阿里云 ACR 个人版限速 1 MB/s 场景下,提前
docker pull <旧镜像>到所有节点,回滚时直接本地起容器,零网络等待。 - Secrets 版本对齐:回滚时若旧镜像依赖旧版证书,需同时回滚 Docker Secrets,避免“镜像旧、配置新”导致二次失败。
- CI/CD 卡点:GitLab CI 在
.gitlab-ci.yml中设置only: variables: $ROLLBACK == "true",一键创建回滚流水线,人工只需点“retry”。 - 审计与告警:在钉钉群机器人接入
docker events --filter event=service_rollback,回滚动作 10 秒内推送,方便运营复盘。
答案
线上出现补丁镜像 app:v1.2.4 启动失败,按以下 6 步回滚:
- 立即止血:
docker service update --rollback --detach=false myapp
Swarm 自动回到上一稳定版本app:v1.2.3,串行替换,确保数据库连接池不瞬间打满。 - 定位根因:
docker service ps myapp --no-trunc | grep Failed拿到容器 ID,
docker logs --tail 200 <ID>结合dmesg | grep OOM判断是补丁引入的新依赖缺库还是内存泄漏。 - 镜像预热:
若集群跨可用区,提前在各节点执行
docker pull registry.cn-hangzhou.aliyuncs.com/xxx/app:v1.2.3
利用阿里云 ACR 预热 API,回滚时无需等待限速。 - 配置同步:
若v1.2.4改动了/run/secrets/api-key,回滚前执行
echo "old-key" | docker secret create api-key-v1.2.3 -
并在 Compose 文件里指定secret: api-key-v1.2.3,保证密钥版本与镜像一致。 - CI/CD 模板固化:
在 GitLab CI 新增rollback-job:
下次回滚只需在 Web 端点击“retry”,无需运维半夜登录堡垒机。rollback: stage: deploy script: - docker stack deploy -c docker-compose.yml myapp only: variables: - $ROLLBACK == "true" - 复盘与防重:
将失败镜像v1.2.4打blocklist标签,禁止 CI 再次推送同名 tag;
在云效流水线增加“启动探测”阶段,健康检查失败即自动回滚并阻塞后续阶段,把故障消灭在灰度 10% 阶段。
拓展思考
- 双镜像仓库策略:核心支付服务同步到金融云 ACR 与自建 Harbor,当公网 ACR 被运营商 QoS 限速时,秒级切换内网 Harbor 完成回滚。
- 蓝绿回滚与数据库兼容:若补丁包含不可逆 SQL,需先在 CI 中跑
flyway migrate -target=1.2.3做向下迁移脚本,否则回滚后容器启动成功但业务逻辑报错。 - Serverless 场景:在阿里云 ECI 弹性容器实例中,没有 Swarm,需提前用虚拟节点 + Deployment 的
revisionHistoryLimit=10,通过kubectl rollout undo回滚,Docker 选手也要懂 K8s 逃生通道。