ExitVideo-Bot · Release 发布手册¶
版本发布全过程的操作手册。涵盖 Semver / 金丝雀发布 / 回滚 / 异常处理。
🎯 发布原则¶
- 可回滚:每次发布必须能在 5 分钟内回滚到上一版本
- 金丝雀:所有生产发布必须经过 5% → 25% → 50% → 100% 灰度
- 不破坏:发布期间 SLO 指标不允许恶化 >10%
- 可追溯:每次发布必须有 GitHub Release 记录 + Slack 通知
📅 发布类型¶
| 类型 | 频率 | 审批 | 是否需 RC | 全自动 |
|---|---|---|---|---|
| Patch (v1.2.3) | 每周 | TL | 否 | 是 |
| Minor (v1.3.0) | 每月 | TL + PM | 是(RC 3 天) | 部分 |
| Major (v2.0.0) | 每季 | TL + CTO + PM | 是(3 个 RC) | 否(手动) |
| Hotfix (v1.2.4) | 紧急 | oncall TL | 否 | 是 |
🚀 流程总览¶
1. PR 合并到 main
↓
2. CI: lint + test + smoke + docker build
↓
3. CI: build-and-push → GHCR (tag=<sha>)
↓
4. Image Updater 改 Helm values(3 分钟内)
↓
5. ArgoCD 同步 + Argo Rollouts 金丝雀
↓
6. Analysis 模板通过 → 自动 promote
↓
7. 监控 30 分钟无降级 → 完成
↓
8. GitHub Release 自动创建 + Slack 通知
🔧 Patch 发布(每周)¶
前置准备¶
# 1. 确认 main 分支 CI 绿色
gh pr checks --watch
# 2. 确认 staging 环境已 soak ≥ 24h
# Grafana → SLO Dashboard → staging
触发发布¶
# 选项 A:推 tag 触发 release.yml workflow
git tag v1.2.3
git push origin v1.2.3
# 选项 B:手动触发 release workflow
gh workflow run release.yml -f version=v1.2.3 -f channel=stable
自动化执行(CI 自动完成)¶
- CI 触发:
release.yml工作流自动启动 - 测试:完整 pytest + smoke
- 构建不可变镜像:
ghcr.io/<owner>/exitvideo-bot:v1.2.3ghcr.io/<owner>/exitvideo-bot:v1.2ghcr.io/<owner>/exitvideo-bot:v1ghcr.io/<owner>/exitvideo-bot:latest- Cosign 签名:SLSA Level 3 keyless
- 触发 Image Updater:Helm values 改 tag
- ArgoCD 同步 + 金丝雀发布:
- 5% → 暂停 5 分钟
- 25% → 暂停 5 分钟
- 50% → 暂停 5 分钟
- 100%
- Analysis 模板(每次 pause 前):
- 成功率 > 99.5%
- P99 < 500ms
- CPU/Memory 不超过 80%
- GitHub Release + Changelog 自动生成
- Slack 通知:#releases 频道
发布完成确认¶
# 1. 检查 Argo Rollouts 状态
kubectl argo rollouts get rollout exitvideo-bot-api -n exitvideo-bot
# 期望:Status: Healthy, Current Step: 100%
# 2. 检查所有 deployment 都升级
kubectl get deploy -n exitvideo-bot -o jsonpath="{.items[*].spec.template.spec.containers[0].image}"
# 期望:所有镜像都是新版本
# 3. Grafana SLO Dashboard 确认
make grafana-ui
# 期望:可用性 / P99 / 错误率 全部正常
🎯 Minor / Major 发布(含 RC)¶
RC 流程(仅 Minor / Major)¶
# 1. 发布 RC.1
git tag v2.0.0-rc1
git push origin v2.0.0-rc1
# → 自动发布到 staging 环境
# 2. soak 3 天
# 3. 修复 bug → RC.2 → soak 3 天
git tag v2.0.0-rc2
git push origin v2.0.0-rc2
# 4. RC 通过后发布正式版
git tag v2.0.0
git push origin v2.0.0
RC vs Stable 区别: - RC 镜像 tag 不覆盖 latest(避免污染) - RC 镜像推送到 staging 集群,不推 prod - RC 默认 24 小时无异常 → 自动 promote 到 stable
⏪ 4. 异常回滚¶
触发条件¶
任一条件满足,立即回滚:
- [ ] API 错误率 > 1%(5 分钟平均)
- [ ] API P99 > 1s(5 分钟平均)
- [ ] Pod CrashLoopBackOff > 10%
- [ ] Database connection error > 5/s
- [ ] 任何 P0/P1 用户感知问题
- [ ] Analysis 模板 fail
自动回滚(Argo Rollouts)¶
Analysis 模板 fail → Argo Rollouts 自动 abort → 流量回退到 stable 版本。
配置(infra/argo-rollouts/analysis-templates.yaml):
- name: success-rate
spec:
metrics:
- name: success-rate
provider: prometheus
inlineResponseTemplate: |
sum(rate(http_requests_total{status!~"5..", rollout="exitvideo-bot-api"}[5m]))
/
sum(rate(http_requests_total{rollout="exitvideo-bot-api"}[5m]))
successCondition: result >= 0.995
failureLimit: 2
手动回滚¶
# 选项 A:ArgoCD rollback(推荐,5 秒回退)
argocd app rollback exitvideo-bot-prod
# 选项 B:手动改 Helm values
argocd app set exitvideo-bot-prod -p image.tag=v1.2.2
argocd app sync exitvideo-bot-prod
# 选项 C:Argo Rollouts 手动 abort
kubectl argo rollouts abort exitvideo-bot-api -n exitvideo-bot
# → 自动回退到上一个 stable revision
回滚后必须做¶
# 1. 立即锁 tag,避免再被同步
kubectl annotate application exitvideo-bot-api -n argocd \
argocd.argoproj.io/paused=true --overwrite
# 2. Slack 通知
make release-rollback-notify VERSION=v1.2.3 STATUS=auto
# 3. 48 小时内出 Postmortem
# 模板:infra/ops/postmortem-template.md
# 4. 修复后发新版本(v1.2.4 或 v2.0.1)
⏸ 5. Argo Rollouts 卡在 Pause¶
症状:kubectl argo rollouts get rollout 显示 Status: Paused
诊断:
kubectl argo rollouts get rollout exitvideo-bot-api -n exitvideo-bot --watch=false
# 输出包含:Current Step / Pause Reason / Age
修复:
# 选项 A:手动 promote
kubectl argo rollouts promote exitvideo-bot-api -n exitvideo-bot
# 选项 B:手动 abort(紧急)
kubectl argo rollouts abort exitvideo-bot-api -n exitvideo-bot
# 选项 C:如果 Analysis 卡太久,skip
# 修改 Analysis 模板的 failureLimit / delay
📦 6. Helm chart 升级失败¶
症状:helm upgrade 报错 / kubectl apply 失败
诊断:
# 1. 看 ArgoCD 同步错误
kubectl describe application exitvideo-bot-api -n argocd | grep -A 10 "Sync Status"
# 2. 看 helm release 历史
helm history exitvideo-bot-api -n exitvideo-bot
# 3. 看具体错误
kubectl get events -n exitvideo-bot --sort-by=".lastTimestamp" | tail -20
修复:
# 选项 A:helm rollback
helm rollback exitvideo-bot-api -n exitvideo-bot 1
# 选项 B:ArgoCD 重试
argocd app sync exitvideo-bot-api --retry-limit=5
# 选项 C:如果 chart 本身 bug,revert chart 修改
git revert <commit>
git push origin main
# → 触发自动 release
🌙 7. 灰度发布到特定租户¶
场景:仅给企业租户发新版本,普通租户保持稳定
# 1. 创建专门的 Application(仅企业租户 namespace)
kubectl apply -f - <<EOF
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: exitvideo-bot-api-enterprise
namespace: argocd
spec:
source:
repoURL: ghcr.io/<owner>/exitvideo-bot
chart: exitvideo-bot
targetRevision: v2.0.0-rc1
destination:
server: https://kubernetes.default.svc
namespace: exitvideo-bot-enterprise
syncPolicy:
automated:
selfHeal: true
EOF
# 2. soak 1 周
# 3. 通过后 promote 到主 Application
kubectl patch application exitvideo-bot-api -n argocd --type merge \
-p '{"spec":{"source":{"targetRevision":"v2.0.0"}}}'
📋 发布前 CheckList¶
- [ ] main 分支 CI 全绿
- [ ] staging 已 soak ≥ 24h(Minor/Major ≥ 3 天)
- [ ] 所有 PR 已合并到 main
- [ ] CHANGELOG.md 已更新
- [ ] 已知 issue 已确认不阻塞发布
- [ ] oncall 工程师已通知(Slack #releases)
- [ ] 监控告警已确认(PagerDuty 测试)
- [ ] 备份已就绪(
make db-backup) - [ ] Vault 密钥无即将过期(>30 天)
📋 发布后 CheckList¶
- [ ] Argo Rollouts 已到 100%
- [ ] 所有 Pod 镜像 tag 正确
- [ ] SLO Dashboard 全部正常
- [ ] Smoke 测试通过(
pytest tests/e2e/) - [ ] Slack #releases 已通知
- [ ] GitHub Release 已创建
- [ ] CHANGELOG.md 已发布
- [ ] 后 24h 监控指标无异常
🔗 相关资源¶
最后更新:第 13 轮 Runbook 补写 覆盖场景:4 类发布 / 自动 + 手动回滚 / 灰度策略 / Pre + Post CheckList