ExitVideo-Bot · On-call 响应手册¶
值班第一响应手册。任何生产事故,第一动作都从这里开始。
🎯 目标¶
- 5 分钟内:收到告警 → 评估严重程度 → 开始处理
- 30 分钟内:完成初步诊断 → 启动缓解措施
- 1 小时内:恢复服务 or 进入 Release Runbook
📞 接收告警¶
PagerDuty¶
PagerDuty App 安装在所有 oncall 工程师手机上。告警触发后:
- 5 秒内:响铃 / 震动 / 推送通知
- 30 秒内:点 "Acknowledge" 确认收到(避免 escalation)
- 2 分钟内:点 "Join Incident" 进入 Slack 频道
#incident-<id> - 5 分钟内:完成首次状态评估
告警等级识别¶
| PagerDuty | 等级 | 处理 |
|---|---|---|
| 🔴 P0 | P0 | 立即上线,30 分钟不能解决 → 升级 TL |
| 🟠 P1 | P1 | 30 分钟响应,4 小时不能解决 → 升级 TL |
| 🟡 P2 | P2 | 4 小时响应 |
| 🟢 P3 | P3 | 24 小时响应 |
Slack 频道¶
#oncall— 日常值班讨论#incident-<id>— 事故专用频道(自动创建)#all-eng— P0 / P1 才会 @
🩺 第一步:3 分钟快速诊断(5 分钟内完成)¶
# 1. ArgoCD 应用状态(30 秒)
kubectl get applications -n argocd
# 期望:所有应用都是 Synced + Healthy
# 异常:找到 Degraded / OutOfSync 的应用名
# 2. Pod 状态(30 秒)
kubectl get pods -n exitvideo-bot
# 期望:所有 Running 且 READY 1/1
# 异常:找 CrashLoopBackOff / ImagePullBackOff / Pending / Error
# 3. 最近事件(30 秒)
kubectl get events -n exitvideo-bot --sort-by=".lastTimestamp" | tail -20
# 4. Grafana 概览(1 分钟)
make grafana-ui
3 分钟内必须能回答:
- [ ] 是 ArgoCD 同步问题吗?
- [ ] 是某个 Pod 挂了?
- [ ] 是某个服务降级了?
- [ ] 是数据库 / Redis 故障?
- [ ] 是上游依赖(如 Stripe / 智谱)挂了?
- [ ] 是 region 级故障?
🛠️ 12 类常见事故详细处理¶
1. ArgoCD Application Degraded¶
症状:kubectl get applications -n argocd 显示 HEALTH=Degraded
诊断:
kubectl describe application exitvideo-bot-api -n argocd
# 查看 Events 部分,找到 Degraded 详细信息
修复:
kubectl get pods -n exitvideo-bot -l app.kubernetes.io/name=exitvideo-bot-api
kubectl logs -n exitvideo-bot -l app.kubernetes.io/name=exitvideo-bot-api --tail=50
argocd app terminate-op exitvideo-bot-api
argocd app sync exitvideo-bot-api --health-check-timeout=60
# 如果还是 Degraded,从上一 Healthy revision rollback
argocd app rollback exitvideo-bot-api
2. ArgoCD Application 长期 OutOfSync¶
症状:应用 Health=Healthy,但 Sync=OutOfSync 超过 15 分钟
修复:
kubectl -n argocd patch application exitvideo-bot-api --type merge \
-p '{"spec":{"syncPolicy":{"automated":{"selfHeal":true}}}}'
argocd app sync exitvideo-bot-api --force
3. Image Updater 未触发更新¶
症状:新 tag 已发布,ArgoCD 应用未更新
诊断:
kubectl logs -n argocd deploy/argocd-image-updater --tail=50
修复:
# 检查 GHCR credentials
kubectl get secret -n argocd argocd-image-updater/ghcr-creds
# 手动触发 webhook
curl -X POST "$IMAGE_UPDATER_WEBHOOK"
4. API 5xx 飙升¶
症状:Grafana 显示 error_rate_5xx > 1%,持续 5 分钟
诊断:
make grafana-ui
# 过滤:status_code=500 OR status_code=502
# 查看是否刚发版
git log --oneline -10
修复:
# 如果刚发版:立刻 rollback
argocd app rollback exitvideo-bot-api
# 如果不是发版:限流
kubectl scale deploy/exitvideo-bot-api -n exitvideo-bot --replicas=20
# 检查数据库连接池
kubectl exec -n database postgres-0 -- pg_stat_activity | wc -l
5. API P99 飙升¶
症状:api_latency_p99 > 500ms,持续 10 分钟
诊断:
# Traces → 按 P99 latency 排序
make grafana-ui
# 看数据库慢查询
kubectl exec -n database postgres-0 -- \
psql -U postgres -c "SELECT * FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 10;"
修复:
# 1. 增加 replica
kubectl scale deploy/exitvideo-bot-api -n exitvideo-bot --replicas=10
# 2. 如果是数据库问题,添加索引
kubectl exec -n database postgres-0 -- \
psql -U postgres -c "CREATE INDEX CONCURRENTLY idx_publish_jobs_tenant_status ON publish_jobs(tenant_id, status);"
# 3. 清理缓存
kubectl exec -n cache redis-master-0 -- redis-cli -a redis FLUSHDB
6. 单个 endpoint 错误率高¶
症状:/v1/webhook/stripe 错误率 50%,其他正常
修复:
# 1. 轮换 webhook secret
argocd app set exitvideo-bot-prod -p webhook.stripeSecret=$NEW_SECRET
argocd app sync exitvideo-bot-prod
# 2. 重放未处理事件
kubectl exec -n database postgres-0 -- \
psql -U postgres -c "SELECT * FROM webhook_events WHERE processed=false ORDER BY created_at LIMIT 100;"
7. Postgres 连接失败¶
症状:connection refused 或 FATAL: too many connections
诊断:
kubectl get pods -n database -l app.kubernetes.io/name=postgresql
kubectl exec -n database postgres-0 -- \
psql -U postgres -c "SELECT count(*) FROM pg_stat_activity;"
修复:
# 1. 临时增加 max_connections
kubectl exec -n database postgres-0 -- \
psql -U postgres -c "ALTER SYSTEM SET max_connections = 500;"
kubectl exec -n database postgres-0 -- pg_ctl reload
# 2. kill 长事务
kubectl exec -n database postgres-0 -- \
psql -U postgres -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state='idle in transaction' AND now() - state_change > interval '5 minutes';"
# 3. 重启应用 Pod 重置连接池
kubectl rollout restart deploy/exitvideo-bot-api -n exitvideo-bot
8. Redis 缓存雪崩¶
症状:Redis hit rate 突然从 95% 跌到 10%
修复:
# 1. 预热缓存
kubectl exec -n app-core -it deploy/exitvideo-bot-api -- \
python -c "from tools.cache import warm_cache; warm_cache()"
# 2. 限流防止雪崩扩散
kubectl apply -f infra/runbooks/../k8s/rate-limit.yaml
9. MinIO 上传失败¶
症状:用户报告视频上传失败 / 500
诊断:
kubectl logs -n storage -l app.kubernetes.io/name=minio --tail=50
kubectl get pvc -n storage
kubectl exec -n storage minio-0 -- df -h
修复:
kubectl rollout restart statefulset/minio -n storage
10. 密钥泄露¶
症状:发现 GitHub commit 含 API key / 发现 Grafana 日志泄露
立即行动(5 分钟内):
# 1. 立刻轮换密钥
vault token revoke -self
# 然后到上游服务(Stripe、智谱、SMS)后台轮换
# 2. 通过 ESO 同步到 K8s
kubectl annotate externalsecret exitvideo-bot-secrets -n exitvideo-bot \
force-sync=$(date +%s) --overwrite
# 3. 重启应用使用新密钥
kubectl rollout restart deploy/exitvideo-bot-api -n exitvideo-bot
kubectl rollout restart deploy/exitvideo-bot-worker -n exitvideo-bot
# 4. 检查 git 历史
git log --all --full-history -- <file>
# 如果 commit 在 main / 历史,git filter-repo 清理
通知:立即 PagerDuty 触发 P1 告警 / 通知 TL + CTO / 24 小时内出具 Postmortem
11. DDoS 攻击¶
症状:NGINX ingress QPS 飙升 / 错误率上升
立即行动:
# 1. CloudFlare 启用 "I'm Under Attack" 模式(Dashboard 操作)
# 2. Argo Rollouts 暂停以阻止流量
kubectl argo rollouts pause exitvideo-bot-api -n exitvideo-bot
# 3. 拉黑攻击 IP(在 CloudFlare WAF 配)
12. mTLS 证书过期¶
症状:Linkerd proxy 启动失败 / 跨 namespace 调用失败
诊断:
kubectl logs -n linkerd deploy/linkerd-proxy-injector --tail=20
linkerd check
修复:
linkerd issuer rotate
kubectl rollout restart deploy -n exitvideo-bot
kubectl rollout restart deploy -n app-core
📋 升级路径(Escalation)¶
oncall (5 分钟响应)
↓ 不能解决 (30 分钟)
TL / 技术负责人
↓ 不能解决 (1 小时)
CTO
↓ 不能解决 / 数据安全
CEO + 法务 + 投资人(仅 P0 / 重大安全事件)
升级命令:
# PagerDuty → "Escalate"
# 或 Slack: @oncall-lead
# 触发 TL 介入
make incident-escalate TL=alice@example.com
📝 事故结束(Postmortem)¶
所有 P1 及以上事故,必须在 48 小时内出具 Postmortem 文档,包含:
- 时间线(UTC)
- 影响范围(用户数 / 错误数 / RTO 实际值)
- Root Cause
- Action Items(每项 owner + deadline)
- 预防措施
模板:infra/ops/postmortem-template.md
🔗 相关资源¶
最后更新:第 13 轮 Runbook 补写 覆盖场景:12 类常见事故 / 5 分钟快速诊断 / 4 级升级路径