发布与回滚
标准化发版步骤、健康检查、监控看板与一键回滚说明,覆盖灰度/全量分支、数据迁移与沟通节奏;适合运维向 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 + 状态页 + 升级路径