Appearance
CI/CD 发布复盘
这篇记录不是单纯讲“怎么发布”,而是讲发布为什么会在某一步卡住,以及怎样把这条链路变得更可靠。CI/CD 最怕的不是慢,而是链路里某一段变成了黑盒:看不到、说不清、也回不去。
事故背景
某次发布过程中,构建、推送镜像和部署动作看起来都执行成功了,但服务就是没有按预期更新。最开始容易怀疑的是应用本身,但往往真正的问题在流程中间层:
- 镜像 tag 没有更新
- 拉取到了旧镜像
- 部署脚本没有等待 rollout 完成
- 环境变量被错误覆盖
- 健康检查没有正确反映新版本状态
这类问题最麻烦的地方在于,流水线“绿了”,但用户看到的还是旧状态。
流水线结构
一个比较清楚的发布链路通常会拆成几段:
- 代码检查
- 构建测试
- 镜像打包
- 推送制品
- 部署到目标环境
- 验证新版本
如果每一步都只是执行命令,而没有明确产物和状态,后面排障时会非常难回看。
这次的问题
排查时先看的是最末端症状:
- 发布成功但页面没有变化
- 容器没有重建
- 新镜像没有被拉取
- 回滚逻辑也没有触发
这个时候最重要的是不要急着重跑流水线,而是先确认发布对象到底有没有被更新。很多时候问题不是“部署没执行”,而是“执行了但没换到新版本”。
镜像和标签
最常见的坑就是镜像标签策略太宽松。比如固定使用 latest,或者 tag 复用太频繁,就很难判断当前线上到底跑的是哪个版本。
更稳妥的方式是:
- 每次构建生成唯一 tag
- tag 里带上 commit 或构建号
- 部署时明确指定版本
- 发布后记录实际运行中的镜像 ID
bash
docker images | head
kubectl get deploy -o wide
kubectl describe pod <pod-name>部署同步问题
如果流水线没有等待部署完成,就会出现“脚本成功,但服务还没切换完”的错觉。这个问题在 Kubernetes 和 Docker Compose 里都会出现,只是表现不同。
在 Kubernetes 中,建议至少等待:
bash
kubectl rollout status deploy/app -n app在 Docker Compose 场景中,则至少要确认:
bash
docker compose ps
docker compose logs -f app如果不看状态就直接认为发布成功,后面一旦出现短暂失败,排查会非常困难。
验证策略
发布后的验证最好分成两层:
技术验证
- 容器或 Pod 是否起来
- 健康检查是否通过
- 日志是否有异常
- 新版本镜像是否已生效
业务验证
- 首页是否正常打开
- 核心 API 是否可用
- 页面资源是否完整
- 延迟和错误率是否正常
技术验证只能说明“系统启动了”,业务验证才能说明“真的对外可用了”。
复盘后修正
这次复盘后,最值得改的不是单点命令,而是整个发布链路的可观察性:
- 每次发布记录版本号
- 部署后强制做一次健康检查
- 出问题时自动保留最近日志
- 回滚命令写入固定脚本
- 发布完成后输出明确结果
如果流程足够清晰,后面就算是临时值班的人接手,也不会因为找不到上下文而手忙脚乱。
结论
CI/CD 的成熟程度,往往不是看它自动化了多少步骤,而是看每一步失败时能不能快速定位。真正好用的流水线,应该让发布变成一件可观察、可解释、可回退的事情。