mcpField
D
disaster-recovery-plan

disaster-recovery-plan

github.com/mohitagw15856云与 DevOps1.5k39 次安装5 天前更新
代码仓库

关于 disaster-recovery-plan

这是一个为工程师、SRE 和值班响应人员编写系统灾难恢复计划的 Skill。它根据提供的服务信息,整理恢复目标、故障场景及逐步操作手册。

主要功能

  1. 01收集服务与基础设施信息
  2. 02设定可衡量的 RPO 和 RTO
  3. 03梳理故障场景
  4. 04编写包含命令的恢复手册
  5. 05加入恢复验证步骤

适用场景

  1. 01为生产服务准备恢复流程
  2. 02记录区域故障切换步骤
  3. 03规划数据库损坏后的恢复
  4. 04协助值班团队响应中断

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mohitagw15856/pm-claude-skills --skill disaster-recovery-plan

安装后在 Claude Code 中输入/disaster-recovery-plan确认已加载。

详细介绍

灾难恢复计划技能

为服务或系统制定完整的灾难恢复计划,让工程师、SRE 和值班响应人员能够在灾难场景中以尽可能短的时间完成恢复。一份优秀的 DR 计划会定期测试,包含精确的命令(而非含糊的说明),并将 RTO/RPO 目标设为可衡量的指标,以便团队判断恢复是否成功。

必要输入

如果尚未提供,请询问以下信息:

  • 服务名称及其功能(业务职能和技术角色)
  • 关键性等级——长时间停机的业务影响(例如:Tier 1 = 营收关键,Tier 2 = 影响运营,Tier 3 = 仅限内部使用)
  • 当前基础设施配置——云服务提供商、区域/可用区、部署模型(Kubernetes、ECS、VM、无服务器)
  • RPO/RTO 要求——恢复点目标(可接受的数据丢失量)和恢复时间目标(可停机多长时间)
  • 备份策略——备份内容、备份频率、备份存储位置、保留策略
  • 值班联系人——响应人员链条中的姓名和联系方式

输出格式


灾难恢复计划:[服务名称]

团队:[团队名称] | 技术负责人:[姓名] 关键性等级:[Tier 1 / Tier 2 / Tier 3] | 上次测试:[日期] 下次 DR 测试:[日期] | 文档负责人:[姓名] 上次更新:[日期] | **评审周期:**每季度

**遇到紧急情况?请跳至第 3 节——故障场景操作手册。**找到与当前情况相符的场景,并严格按照步骤操作。


1. 恢复目标

目标值依据
RPO(恢复点目标)[X 分钟/小时][例如:“最后一次已提交的事务——数据库复制为同步模式”]
RTO(恢复时间目标)[Y 分钟/小时][例如:“30 分钟后开始影响营收;目标是在 15 分钟内恢复”]
MTTR 目标(非灾难)[Z 分钟][运营事件,不包括 DR 事件]
数据保留期限(备份)[N 天/周][合规要求或运营策略]
备份频率[每 X 小时][由 RPO 决定——备份间隔必须 ≤ RPO]

实际意义:

  • 如果数据库损坏,事务丢失量最多为 [X 分钟],超过该范围将造成不可接受的业务影响。
  • 宣布发生 DR 事件后,服务必须在 [Y 分钟/小时] 内恢复运行。
  • 如果无法达到任一目标,请立即升级给 [工程经理] 处理。

2. 故障场景清单

场景可能性影响RTO 目标RPO 目标操作手册
单个可用区故障中[部分 / 完全中断][15 分钟][0 — 无数据丢失]第 3.1 节
整个区域故障低完全中断[60 分钟][5 分钟]第 3.2 节
数据库损坏 / 数据丢失低完全中断[90 分钟][RPO 值]第 3.3 节
关键依赖项中断高[部分降级][30 分钟][不适用]第 3.4 节
安全漏洞 / 勒索软件极低完全中断 + 调查[4 小时][最近一次干净备份]第 3.5 节
意外批量删除数据低部分或全部数据丢失[60 分钟][RPO 值]第 3.6 节

3. 故障场景操作手册

3.1 单个可用区故障

**触发条件:**一个 AZ 无法访问——该区域中的 Pod/实例停止响应。 **检测方式:**PagerDuty 告警 [AlertName] 触发,或云服务提供商状态页面显示 AZ 降级。 预期 RTO:[15 分钟] | **预期 RPO:**零(多 AZ 复制正常工作时不会丢失数据)

步骤 1 — 确认故障

# Check pod/instance health across zones
kubectl get pods -o wide -n [namespace] | grep -v Running

# Check which nodes are affected
kubectl get nodes -o wide | grep -v Ready

# Verify cloud provider AZ status
# AWS: https://health.aws.amazon.com/health/status
# GCP: https://status.cloud.google.com

步骤 2 — 评估是否已自动恢复

# If using auto-scaling, check if replacement instances launched
kubectl get pods -n [namespace] --watch

# Check deployment replica count
kubectl get deployment [service-name] -n [namespace]

# Verify load balancer health checks are passing
[cloud provider CLI command to check target group health]

步骤 3 — 如果自动恢复停滞,则强制重新调度

# Cordon the affected node so no new pods schedule on it
kubectl cordon [node-name]

# Drain the node — moves all pods to healthy nodes
kubectl drain [node-name] --ignore-daemonsets --delete-emptydir-data

# Verify pods have rescheduled successfully
kubectl get pods -o wide -n [namespace]

步骤 4 — 验证服务健康状况

# Smoke test key endpoints
curl -s -o /dev/null -w "%{http_code}" https://[service-url]/health
curl -s -o /dev/null -w "%{http_code}" https://[service-url]/[critical-endpoint]

# Check error rate in monitoring
[dashboard link or query]

**确认恢复的条件:**所有 Pod 均处于 Running 状态,健康检查返回 200,错误率回到基线水平。


3.2 整个区域故障

触发条件: 主区域完全不可用。 检测方式: 所有服务健康检查均失败,云服务提供商状态页面确认发生区域级事件。 预计 RTO: [60 minutes] | 预计 RPO: [5 minutes — 基于跨区域复制延迟]

步骤 1 — 确认区域故障(5 分钟)

# Confirm the primary region is unreachable
ping [primary-region-endpoint] || echo "Primary region unreachable"

# Check replication lag on standby region database
[command to check replica lag — e.g. for RDS: aws rds describe-db-instances --region [dr-region]]

步骤 2 — 宣布 DR 事件并通知相关人员(2 分钟)

在 #incidents 中发布:

🔴 DR EVENT — [Service Name] — Region Failure
Primary region: [region] — UNREACHABLE
Activating failover to: [dr-region]
Incident commander: [Name]
Next update: 15 minutes

通过 PagerDuty 呼叫 [Engineering Manager] 和 [CTO/VP Eng]。

步骤 3 — 提升 DR 数据库(10 分钟)

# AWS RDS — promote read replica to primary
aws rds promote-read-replica \
  --db-instance-identifier [dr-replica-identifier] \
  --region [dr-region]

# Wait for promotion to complete
aws rds wait db-instance-available \
  --db-instance-identifier [dr-replica-identifier] \
  --region [dr-region]

# Record the new database endpoint
aws rds describe-db-instances \
  --db-instance-identifier [dr-replica-identifier] \
  --region [dr-region] \
  --query 'DBInstances[0].Endpoint.Address'

步骤 4 — 在 DR 区域部署服务(20 分钟)

# Update service configuration to point at DR database
kubectl set env deployment/[service-name] \
  DATABASE_URL=[new-dr-database-url] \
  -n [namespace] \
  --context [dr-region-context]

# Scale up the DR deployment
kubectl scale deployment/[service-name] --replicas=[N] \
  -n [namespace] \
  --context [dr-region-context]

# Verify all pods are running
kubectl get pods -n [namespace] --context [dr-region-context]

步骤 5 — 切换 DNS / 负载均衡器(5 分钟)

# Update DNS to point to DR region load balancer
# AWS Route 53:
aws route53 change-resource-record-sets \
  --hosted-zone-id [zone-id] \
  --change-batch file://dr-failover-dns.json

# Verify DNS propagation (may take up to [TTL] seconds)
dig [service-domain] @8.8.8.8

步骤 6 — 端到端验证

# Full smoke test against DR endpoint
curl -s https://[service-url]/health
[run automated smoke test suite if available]

满足以下条件即可确认恢复: DNS 解析到 DR 区域,冒烟测试通过,错误率恢复到基线水平。

故障切换后的操作(非紧急 — 服务稳定后执行):

  • 在确认根本原因已解决之前,不要切回主区域
  • 记录数据丢失时间窗口(检查故障发生时的复制延迟)
  • 开始进行事后复盘 — 参见 [incident-postmortem skill]

3.3 数据库损坏或数据丢失

触发条件: 由于软件 Bug、操作人员错误或硬件故障,数据库中的数据遭到损坏、删除或出现其他错误。 检测方式: 应用程序报错并提示数据缺失或无效、查询错误率监控告警、用户报告。 预计 RTO: [90 minutes] | 预计 RPO: [备份间隔 — 例如 1 小时]

步骤 1 — 立即止损

# Put the service into maintenance mode to prevent further writes to corrupted data
[command to enable maintenance mode — e.g. kubectl set env deployment/[name] MAINTENANCE_MODE=true]

# Or: scale down the service to zero to prevent writes
kubectl scale deployment/[service-name] --replicas=0 -n [namespace]

步骤 2 — 评估数据损坏范围

# Identify which tables/records are affected
[SQL query to check data integrity — e.g.]
# psql $DATABASE_URL -c "SELECT COUNT(*) FROM [table] WHERE [integrity check condition]"

# Determine when corruption started (cross-reference with deploy times and error logs)
[log query to find earliest error — e.g. in Datadog:]
# service:[service-name] status:error "[corruption error message]" | sort by timestamp asc

步骤 3 — 确定正确的恢复点

# List available backups
[command to list backups — e.g. for RDS:]
aws rds describe-db-snapshots \
  --db-instance-identifier [db-identifier] \
  --query 'DBSnapshots[*].[SnapshotCreateTime,DBSnapshotIdentifier]' \
  --output table

# Choose the most recent backup BEFORE corruption started
# Record the chosen snapshot ID: [snapshot-id]

步骤 4 — 从备份恢复

# Restore to a NEW database instance (never overwrite production directly)
aws rds restore-db-instance-from-db-snapshot \
  --db-instance-identifier [service-name]-restored-[date] \
  --db-snapshot-identifier [snapshot-id] \
  --region [region]

# Wait for restore to complete
aws rds wait db-instance-available \
  --db-instance-identifier [service-name]-restored-[date]

# Get the restored instance endpoint
aws rds describe-db-instances \
  --db-instance-identifier [service-name]-restored-[date] \
  --query 'DBInstances[0].Endpoint.Address'

步骤 5 — 验证恢复的数据

# Connect to restored database and verify integrity
psql [restored-db-endpoint] -U [user] -d [database] -c "[data integrity query]"

# Confirm record counts match expectations
psql [restored-db-endpoint] -U [user] -d [database] -c "SELECT COUNT(*) FROM [critical-table]"

步骤 6 — 将服务指向恢复后的数据库

kubectl set env deployment/[service-name] \
  DATABASE_URL=postgres://[user]:[pass]@[restored-endpoint]/[db] \
  -n [namespace]

kubectl scale deployment/[service-name] --replicas=[N] -n [namespace]

满足以下条件即可确认恢复: 服务已使用恢复后的数据库运行,数据完整性检查通过,错误率恢复到基线水平。


3.4 关键依赖项中断

触发条件: [service name] 所依赖的服务不可用或性能下降。 检测方式: 调用 [dependency] 的端点错误率或延迟上升、依赖项所有者发出告警。 预计 RTO: 取决于依赖项 — [30 minutes for mitigation, resolution depends on dependency owner]

依赖关系图:

依赖项关键程度降级行为缓解措施
[Database]关键 — 所有写入均失败完全中断启用 DR 数据库(第 3.3 节)
[Cache — Redis]高 — 延迟上升性能下降绕过缓存,直接从 DB 提供数据
[Auth service]关键 — 身份验证失败所有需要身份验证的端点均失败返回缓存的令牌(如果已实现)
[Message queue]中 — 异步处理延迟写入成功,异步任务排队队列积压 — 参见值班手册
[External API — name]低 — 功能 X 不可用平稳降级使用功能标志禁用功能 X

缓解步骤:

# Enable circuit breaker / fallback for [dependency] if implemented
kubectl set env deployment/[service-name] [DEPENDENCY]_CIRCUIT_BREAKER=open -n [namespace]

# Enable feature flag to disable [dependency-backed feature]
[feature flag CLI command or dashboard link]

# Check if dependency has a status page
# [Dependency status URL]

升级处理: 通过 [PagerDuty / Slack #[channel]] 联系 [dependency] 的值班人员。告知对方你们服务的错误率以及依赖项错误开始出现的时间。


3.5 安全漏洞或勒索软件攻击

触发条件: 有证据表明存在未经授权的访问、数据外泄或服务数据被加密。 检测方式: 安全工具告警、异常访问模式、用户报告数据泄露。 预计 RTO: [4+ hours — prioritise containment over speed] | 预计 RPO: [最后一次验证无问题的备份]

步骤 1 — 立即隔离

# Take the service offline — do not attempt to recover while breach is active
kubectl scale deployment/[service-name] --replicas=0 -n [namespace]

# Revoke all API keys and service account credentials immediately
[command to rotate secrets — e.g. via Vault or cloud provider]

# Block all external access at network level
[firewall/security group command to deny all inbound traffic]

步骤 2 — 立即通知安全团队 通过 PagerDuty 呼叫 [Security lead]。在安全团队参与前,切勿尝试修复问题。

在 #security-incidents 中发布(私有频道,不是 #incidents):

🔴 SECURITY INCIDENT — [Service Name]
Time detected: [Time]
Evidence: [One sentence — what was observed]
Actions taken: Service isolated, credentials revoked
Awaiting: Security team guidance

步骤 3 — 保留证据

# Export current logs before any remediation
[log export command — preserve evidence for forensics]

# Snapshot the current state of all infrastructure
[snapshot/image command]

步骤 4 及后续步骤 — 遵循安全团队的指导。 在安全团队确认攻击途径已关闭之前,不要从备份恢复。


3.6 意外的大规模数据删除

触发条件: 操作人员、脚本或应用程序错误导致记录被大规模删除。 检测方式: 记录数量骤降、用户报告数据丢失、应用程序报错。 预期 RTO: [60 minutes] | 预期 RPO: [Backup interval]

# Step 1 — Stop further writes immediately
kubectl scale deployment/[service-name] --replicas=0 -n [namespace]

# Step 2 — Determine what was deleted and when
psql $DATABASE_URL -c "
  SELECT schemaname, tablename,
         n_dead_tup, last_autovacuum
  FROM pg_stat_user_tables
  ORDER BY n_dead_tup DESC LIMIT 10;
"

# Step 3 — Check if deletion is recoverable via MVCC (PostgreSQL)
# Records may still be recoverable if VACUUM has not run
psql $DATABASE_URL -c "
  SELECT * FROM [table]
  WHERE xmax != 0  -- recently deleted rows
  LIMIT 100;
"

# Step 4 — If not recoverable via MVCC, restore from backup
# Follow Section 3.3 (Database Corruption runbook) from Step 3 onward

4. 备份和恢复流程

备份配置
数据存储备份类型频率保留期限位置
[Primary database]自动快照每 [N] 小时[N] 天[S3 bucket / cloud storage path]
[Primary database]事务日志备份持续进行[N] 天[Location]
[Secondary store — e.g. Redis]RDB 转储每日[N] 天[Location]
[Blob/object storage]跨区域复制持续进行[N] 天[DR region bucket]
[Config / secrets]Terraform 状态 + Vault 备份变更时永久[Location]
备份验证(每周执行)
# Test restore of latest database backup to a throwaway instance
aws rds restore-db-instance-from-db-snapshot \
  --db-instance-identifier [service-name]-backup-test-$(date +%Y%m%d) \
  --db-snapshot-identifier $(aws rds describe-db-snapshots \
    --db-instance-identifier [db-id] \
    --query 'sort_by(DBSnapshots, &SnapshotCreateTime)[-1].DBSnapshotIdentifier' \
    --output text)

# Wait for restore, then run integrity checks
psql [test-instance-endpoint] -c "[integrity check query]"

# Confirm row counts match recent production values (allow ≤ RPO difference)
psql [test-instance-endpoint] -c "SELECT COUNT(*) FROM [critical-table]"

# Destroy the test instance
aws rds delete-db-instance \
  --db-instance-identifier [service-name]-backup-test-$(date +%Y%m%d) \
  --skip-final-snapshot

5. DR 测试频率

必须定期测试。未经测试的 DR 计划不算 DR 计划。

测试类型频率执行人员通过标准
备份恢复验证每周(自动)值班轮班人员恢复完成,完整性检查通过
可用区故障切换演练每月工程团队达到 RTO 目标,零数据丢失
区域故障切换演练每季度工程团队 + SRE达到 RTO/RPO 目标
完整 DR 演练日每年工程团队 + 相关方演练所有场景,记录差距
混沌工程(基础设施故障)每周(自动)混沌工程工具服务平稳降级并自动恢复
演练日流程
  1. 演练日前(提前 1 周): 通知所有相关方,当天冻结生产环境变更,准备 DR 环境。
  2. 确定范围: 从第 2 节选择 2–3 个场景。测试前记录预期结果。
  3. 执行: 一人担任事件指挥官,其他人执行运行手册步骤,另安排一人观察并计时。
  4. 测量: 针对每个场景,记录实际 RTO 和 RPO,并与目标对比。
  5. 复盘(当天): 记录差距、运行手册中的错误以及自动化机会。
  6. 后续事项: 为发现的每项差距创建工单。优先级:P1 项必须在下次演练日前修复。

6. 沟通计划

DR 事件期间的内部沟通

事件指挥官职责:

  • 宣布 DR 事件并建立事件频道
  • 至少每 15 分钟发布一次更新
  • 决定是否进行故障切换(不要让团队通过委员会投票决定)
  • 告知业务相关方预计恢复时间

DR 事件开始时通知以下人员:

角色姓名联系方式通知时间
工程经理[Name][Slack / Phone]立即
CTO / VP Engineering[Name][Phone]Tier 1 服务:立即
客户成功负责人[Name][Slack]对客户造成影响时
安全负责人[Name][Slack / PagerDuty]怀疑发生安全漏洞时
法务 / 合规[Name][Email / Phone]数据丢失涉及 PII 时
沟通模板

宣布 DR 事件:

🔴 DR EVENT — [Service Name]
Time: [HH:MM UTC]
Scenario: [Zone failure / Region failure / Data loss / etc.]
Impact: [Who is affected and how]
RTO target: [X minutes]
Incident commander: [Name]
War room: [Slack channel / call link]
Next update: [Time + 15 min]

状态更新(每 15 分钟):

🔴 DR UPDATE — [Service Name] — [HH:MM UTC]
Status: [Investigating / Executing recovery / Verifying]
Progress: [One sentence on current step]
Blockers: [Any — or "None"]
Updated RTO estimate: [Time]
Next update: [Time + 15 min]

确认恢复:

✅ DR RESOLVED — [Service Name] — [HH:MM UTC]
Total downtime: [X minutes]
Data loss: [None / X minutes of transactions]
RTO target: [X min] — Actual: [Y min] — [MET / MISSED]
RPO target: [X min] — Actual: [Y min] — [MET / MISSED]
Root cause: [One sentence]
Post-incident review: [Scheduled for / Link when created]

7. DR 准备情况检查清单

每季度以及每次重大基础设施变更前运行此检查清单:

备份:

  • 自动备份正在运行,且失败时会触发警报
  • 最近一次备份恢复已在过去 7 天内完成测试
  • 备份保留策略符合 RPO 和合规要求
  • 备份存储在与主环境不同的区域/账户中

故障转移基础设施:

  • DR 区域/环境已存在并完成配置(而不只是有文档记录)
  • DNS 故障转移流程已记录,并包含准确的命令
  • DR 数据库副本保持最新(复制延迟在 RPO 范围内)
  • 服务可通过单条命令或自动化流水线部署到 DR 区域

运行手册:

  • 第 3 节中的所有运行手册都已在上一季度内完成测试
  • 已根据当前基础设施验证运行手册中的命令(没有过时的引用)
  • 联系人名单是最新的(不包含已离职员工)

访问权限:

  • 值班工程师可以访问 DR 区域控制台/CLI
  • 已配置并测试 DR 区域的服务账户凭据
  • 已设置紧急访问的应急账户,以便 SSO 不可用时使用

监控:

  • DR 区域中也配置了监控(而不只是主区域)
  • DR 环境出现问题时,警报会正确触发

质量检查

  • RPO 和 RTO 目标是具体数值,而非范围,并已与业务部门达成一致
  • 每份运行手册中的每条命令都由人工在上一季度内实际运行过,而非未经测试便从文档中复制
  • DR 数据库已部署在 DR 区域,并且监控复制延迟
  • 已在过去 7 天内完成端到端备份恢复测试
  • 游戏日安排已列入团队日历,而不只是记录在此处
  • 联系人名单包含当前电话号码,而不只是 Slack 用户名(DR 事件期间 Slack 可能不可用)
  • 安全漏洞运行手册(3.5)明确列出安全团队联系人,且不会尝试自行修复
  • 监控仪表板中清晰显示所有阈值(RTO/RPO),以便实时衡量实际值与目标值

反模式

  • 不要编写未经测试的运行手册命令——在真实灾难期间,认知负荷最高时,运行手册中未经测试的命令会带来直接危险
  • 未经业务部门批准,不要设定 RTO/RPO 目标——技术团队经常设定理想化目标,而这些目标并未反映业务对停机成本的实际承受能力
  • 不要只写每种故障转移场景的“顺利流程”——运行手册必须明确说明恢复步骤本身失败时该怎么办
  • 不要只将 Slack 用户名列为升级联系人的联系方式——区域范围故障期间 Slack 可能不可用;电话号码是必需的
  • 不要在未预先承诺修复所发现问题的情况下安排 DR 游戏日——无人负责后续行动项的游戏日只是作秀,并不能提升应急准备程度

示例触发语句

  • “编写 DR 计划。”
  • “记录故障转移流程。”
  • “创建恢复运行手册。”
  • “定义 RTO/RPO 目标。”
  • “为灾难恢复游戏日做准备。”

评论

支持 Markdown