发布与回滚

标准化发版步骤、健康检查、监控看板与一键回滚说明,覆盖灰度/全量分支、数据迁移与沟通节奏;适合运维向 Agent 与 on-call 按剧本执行。

SKILL 应列出前置条件(迁移脚本、特性开关、依赖服务版本)、验证步骤(探针、抽样业务请求、对照组指标)与失败时的回滚顺序;不可逆步骤必须标出人工审批点。

与可观测联动:写明核心指标、日志关键字、告警静默策略;发布窗口与代码冻结期写清楚,避免在错误时间由自动化「一步登全量」且无人值守。

发布流水线(门禁 → 部署 → 验证)

  [ 合流 / 打 Tag / 选制品 ]
        │
        ▼
  ┌─────────────┐     门禁:CI 全绿、镜像签名、配置 diff、变更单
  │  前置门禁    │──── 可选:人工审批、维护窗口校验
  └─────────────┘
        │
        ▼
  ┌─────────────┐     部署:蓝绿 / 滚动 / 金丝雀(与策略一致)
  │  渐进发布    │──── 特性开关:默认安全态 → 按百分比或名单放开
  └─────────────┘
        │
        ▼
  ┌─────────────┐     验证:健康探针、SLO、错误率、队列积压、抽样用例
  │  观测与探活  │──── 达标:推进下一阶段;未达标:按剧本回滚或止血
  └─────────────┘

原则:「部署成功」不等于「业务健康」。探活通过后再观察一段稳定窗口(团队约定时长),再扩大流量或宣布完成。

# 发版三阶段清单骨架(可直接粘贴到工单)
# === Pre-Release ===
# [ ] CI 全绿(gh run list --branch main --status success --limit 3)
# [ ] 镜像签名验证通过(cosign verify registry/app:v1.4.2)
# [ ] 配置 diff 已 review(git diff origin/main -- config/ infra/)
# [ ] 变更单已创建(CHANGE-XXXX),维护窗口校验通过
# [ ] 数据库迁移脚本可逆性已确认,执行顺序已写入 Runbook

# === Deploy ===
# [ ] 特性开关默认 off,灰度策略已写入 Runbook
kubectl set image deployment/myapp myapp=registry/app:v1.4.2 -n production
kubectl rollout status deployment/myapp -n production --timeout=5m

# === Post-Release ===
# [ ] 健康探针全绿,业务端点抽样通过
# [ ] SLO 面板与前 7 天基线对比无劣化
# [ ] 告警静默到期后无新告警触发
# [ ] 状态页已更新(若对外)

前置条件与门禁

  • 数据库:迁移顺序、是否可逆、回滚时 schema 与数据是否一致。
  • 配置与密钥:环境变量、KMS/Secret 引用、各环境 diff 已评审。
  • 依赖:下游 API 版本、消息契约、缓存键空间是否兼容。
  • 容量:预估 QPS、连接池、批任务窗口是否覆盖峰值。
#!/bin/bash
# 门禁脚本:验证环境变量与密钥可用性(pre-release gate check)
set -euo pipefail

echo "[PRE-CHECK] 1. 检查必需环境变量"
required_vars=(DB_HOST DB_PORT REDIS_URL API_SECRET_REF)
for var in "${required_vars[@]}"; do
  [[ -z "${!var:-}" ]] && { echo "ERROR: $var 未设置" >&2; exit 1; }
done

echo "[PRE-CHECK] 2. 验证 KMS/Secret 可达"
aws secretsmanager get-secret-value \
  --secret-id prod/myapp/db-password \
  --query SecretString --output text > /dev/null \
  && echo "  OK: DB secret 可读"

echo "[PRE-CHECK] 3. 检查下游依赖版本契约"
curl -sf https://api.payment.internal/health \
  | jq -e '.version | startswith("3.")'

echo "[PRE-CHECK] 所有门禁通过 ✓"

仅应用发布与「含不可逆迁移」的发布应拆成可独立回滚的步骤;技能里写清哪一步失败时停在哪一层。

健康检查与可观测

探活与合成监控

  • HTTP/TCP 就绪与存活探针阈值
  • 关键路径合成事务(登录、下单、支付回调等)
  • 队列/Topic 消费滞后与 DLQ 计数

指标与日志

  • 错误率、延迟分位、饱和度(CPU/内存/连接)
  • 业务 KPI 对照(转化率、任务成功率)
  • 发布关联的 trace/log 关键字便于快速检索
#!/bin/bash
# 健康检查脚本:验证关键端点(发布后立即运行)
BASE="https://api.example.com"
TIMEOUT=5

check() {
  local name="$1" url="$2" expect="$3"
  code=$(curl -sf -o /dev/null -w "%{http_code}" --max-time $TIMEOUT "$url" || echo "000")
  if [[ "$code" == "$expect" ]]; then
    echo "  OK  [$code] $name"
  else
    echo "FAIL  [$code] $name — expected $expect" >&2; return 1
  fi
}

echo "=== 就绪探针 ==="
check "readiness"   "$BASE/healthz/ready"           "200"
check "liveness"    "$BASE/healthz/live"            "200"

echo "=== 核心业务端点 ==="
check "user-api"    "$BASE/api/v1/users/me"         "401"  # 无 token 应返回 401
check "product-api" "$BASE/api/v1/products?limit=1" "200"
check "checkout"    "$BASE/api/v1/cart"             "401"

echo "=== 队列消费滞后(Kafka)==="
lag=$(kafka-consumer-groups.sh --bootstrap-server kafka:9092 \
  --describe --group myapp-worker 2>/dev/null \
  | awk 'NR>1{sum+=$6} END{print sum+0}')
[[ $lag -lt 1000 ]] && echo "  OK  lag=$lag" || echo "WARN lag=$lag" >&2

灰度、金丝雀与全量

对「灰度 / 金丝雀」与「全量」分别给清单,避免无人值守下一步直接全量。

  • 灰度:实例比例或流量权重、每档停留时间、自动/人工推进条件。
  • 金丝雀:与对照组同一指标面板对比;异常即自动回切或熔断。
  • 全量:明确「宣布完成」的责任人、对外公告时间点(若适用)。
# Nginx upstream 金丝雀权重切换(/etc/nginx/conf.d/upstream.conf)
# 阶段 1:5% 流量到新版本
upstream backend {
    server stable.internal:8080  weight=95;
    server canary.internal:8080  weight=5;
}
# 验证指标稳定后执行:sudo nginx -t && sudo nginx -s reload

# 阶段 2:25%(编辑 weight 后 reload)
# upstream backend { server stable:8080 weight=75; server canary:8080 weight=25; }

# 阶段 3:全量切换(需人工确认)
# upstream backend { server canary:8080 weight=100; }

# Kubernetes Argo Rollouts 等效命令
kubectl argo rollouts set-weight canary-rollout 5    # 阶段 1
kubectl argo rollouts promote canary-rollout          # 推进下一阶段
kubectl argo rollouts abort   canary-rollout          # 回滚权重到 0

回滚顺序与数据影响

  [ 触发:SLO 跌破 / 致命缺陷 / 人工叫停 ]
        │
        ▼
  ┌─────────────┐     先止血:限流、关特性开关、禁用批任务
  │  流量与开关  │
  └─────────────┘
        │
        ▼
  ┌─────────────┐     应用:回滚到上一稳定制品(或蓝绿切回)
  │  制品回滚    │──── 数据:若迁移不可逆 → 走补偿/修复剧本,不单靠「部署旧包」
  └─────────────┘
        │
        ▼
  ┌─────────────┐     验证:探活 + 核心业务抽样 + 告警恢复
  │  回滚后确认  │──── 沟通:内部频道 + 状态页(若对外)
  └─────────────┘
  • 应用回滚是否需同步回滚迁移;若不可逆,标明审批与数据修复路径。
  • 缓存与搜索索引:是否需重建或 TTL 自然过期,避免旧代码读新数据形态。
#!/bin/bash
# 回滚决策树执行脚本
# 触发条件:error_rate > 1% 持续 3 分钟,或 P99 > 2000ms,或人工叫停

echo "=== 步骤 1:止血 — 关闭特性开关 ==="
curl -s -X PATCH https://flags.internal/api/flags/new-checkout \
  -H 'Content-Type: application/json' -d '{"enabled":false}'

echo "=== 步骤 2:限流(可选,待确认业务影响)==="
kubectl annotate ingress myapp-ingress nginx.ingress.kubernetes.io/limit-rps="50" -n production

echo "=== 步骤 3:制品回滚 ==="
kubectl rollout undo deployment/myapp -n production
kubectl rollout status deployment/myapp -n production --timeout=5m

echo "=== 步骤 4:验证回滚后健康状态 ==="
curl -sf https://api.example.com/healthz/ready | jq .

echo "=== 步骤 5:若有不可逆迁移,执行数据补偿脚本(人工确认后执行)==="
# psql $DB_URL -f migrations/rollback/V20240410_compensate.sql

echo "=== 回滚完成,通知 Slack #incidents ==="

沟通、窗口与冻结期

  • 对内:变更摘要、影响面、值班与升级路径、预计回滚时间。
  • 对外:状态页更新时机、维护公告模板(若适用)。
  • 冻结期:禁止自动合并/自动发布的时段与例外流程(紧急补丁)。
# Slack 发布通知模板(Incoming Webhook 格式)
curl -s -X POST "$SLACK_WEBHOOK_URL" \
  -H 'Content-Type: application/json' \
  -d '{
  "text": "🚀 *发布通知* — myapp v1.4.2 已上线",
  "blocks": [
    {
      "type": "section",
      "fields": [
        {"type": "mrkdwn", "text": "*版本*\nv1.4.2"},
        {"type": "mrkdwn", "text": "*策略*\n金丝雀 5%→25%→100%"},
        {"type": "mrkdwn", "text": "*变更摘要*\n修复支付竞态 (#4321)"},
        {"type": "mrkdwn", "text": "*值班*\n@oncall | CHANGE-9876"}
      ]
    },
    {
      "type": "actions",
      "elements": [
        {"type":"button","text":{"type":"plain_text","text":"监控面板"},
         "url":"https://grafana.example.com/d/release"},
        {"type":"button","text":{"type":"plain_text","text":"一键回滚"},
         "url":"https://wiki.example.com/runbook/rollback","style":"danger"}
      ]
    }
  ]
}'

# 发布后监控时间窗(至少观察以下指标 30 分钟):
# - HTTP 5xx 错误率 < 0.5%(Grafana: rate(http_requests_total{status=~"5.."}[5m]))
# - P99 响应时间 < 800ms
# - 消息队列积压 < 1000 条
# - CPU / 内存饱和度 < 80%

Runbook 片段实验室

选择发布策略并勾选本次变更涉及项,生成可粘贴到工单或 Agent 上下文的 Markdown 清单;发布名称用于标题,可按仓库惯例修改。

本次变更涉及(勾选生成对应检查项)

生成内容仅为骨架;请补全具体指标阈值、负责人、工单链接与回滚命令。全量策略务必在技能中写明「人工确认」步骤。

---
name: release-and-rollback
description: 标准化发版三阶段、健康检查、灰度策略与一键回滚
version: 2.0
---
# 前置条件(pre-release)
- CI 全绿 & 镜像签名验证通过
- 数据库迁移脚本 review(是否可逆?回滚 schema 是否兼容?)
- 配置与 Secret diff 各环境已评审
- 变更单已创建,维护窗口已确认

# 部署(deploy)
- 特性开关:默认安全态(off)
- 策略:金丝雀 5%→25%→100%,每阶观测 ≥15 min
- kubectl rollout status 验证滚动完成
- Runbook 命令:kubectl argo rollouts promote myapp-rollout

# 发布后验证(post-release)
- 健康探针:/healthz/ready + 业务端点抽样
- 指标门禁:error_rate < 0.5%,P99 < 800ms,lag < 1000
- 稳定窗口 30 min 无告警 → 宣布完成 → 更新状态页

# 回滚触发与顺序
- 触发:SLO 跌破 / P99 > 2s 持续 3 min / 致命缺陷 / 人工叫停
- 顺序:kill switch → kubectl rollout undo → 数据补偿(若需)
- 沟通:Slack #incidents + 状态页 + 升级路径

返回技能库 更多技能入口