在 K8s 里,“备份"不等于"把 Pod 存下来”——Pod 是声明式的是可以重建的,真正需要备份的是两类东西:元数据(namespace/deployment/CM/secret/service…)和持久化数据(PVC 里的数据)。etcd 保存了集群的"真相",PVC 保存了业务的"价值"。本指南围绕 Velero(元数据+卷)、etcd 快照(集群真相)、CSI 快照(数据)三件套,讲清楚怎么备、怎么存、怎么高效地恢复,以及为什么"没演练过的备份等于没有备份"。
目录
- 1. 备份的边界:哪些该备、哪些重建
- 2. 备份对象分层:etcd / 元数据 / 数据卷
- 3. Velero:元数据与工作负载的备份恢复
- 4. etcd 快照:控制面真相的守护
- 5. CSI 快照与持久化数据备份
- 6. Restore:恢复流程与粒度
- 7. 跨集群/跨区域容灾与 RTO/RPO
- 8. 恢复演练:让备份真正可用
- 9. 生产最佳实践与避坑
1. 备份的边界:哪些该备份、哪些可重建
1.1 声明式资源值得备吗?
K8s 的配置(Deployment/ConfigMap/Secret/Service...)通常已在 Git 中
→ GitOps 本身就是"配置备份"
那还需要备份集群对象吗?——是的,场景:
- 部分资源没进 Git(临时创建、PVC/Service 运行时态、Ingress 手动改)
- 命名空间、RBAC、resourcequota 等"平台态"对象
- 恢复"整集群到某时间点"比重新 apply 一堆 manifest 更快
所以备份的对象 = "平台 + 应用定义"的完整快照,
而不仅是 Git 里的 manifest。
1.2 什么是确定要备份的
三类核心资产:
1. 集群状态:etcd(Pod/Deployment/所有对象 + Node 状态)
2. 持久化数据:PVC 里的数据(数据库、消息、文件、状态)
3. 平台配置:RBAC、quota、storageclass、网络策略
不需备份(可按需重建):
- Pod/Service 等"可再创建"对象(若有 GitOps,可重放)
注意:不要把"备份"做成"浪费时间抄录全部"——聚焦真正有恢复价值的数据
ℹ️ 核心认知:备份的定义 = 你能恢复什么。如果备份了但恢复不出来/太慢,它就没有价值。
2. 备份对象分层:etcd / 数据 / 数据卷
分层恢复心智:
控制面恢复(etcd):
救"集群本身"—— 一个节点或整个 etcd 状态坏了
元数据恢复(Velero):
救"应用定义"—— 误删 namespace / 配置漂移
数据恢复(Velero + CSI/存储快照):
救"业务数据"—— 数据库/文件/状态机
三种恢复要联动:
先恢复集群(etcd)→ 再恢复应用(Velero 元数据)→ 再恢复数据(卷)
通常"全恢复"顺序很重要,否则孤立恢复会产生不一致。
3. Velero:元数据与工作负载的备份恢复
3.1 Velero 架构
Velero 在集群里跑一个 server(备份控制器):
- Backup:把"集群资源 + 持久化数据"打包到对象存储
- Restore:从对象存储还原资源与数据
- Schedule:cron 定时备份
- 对象存储:S3/GCS/MinIO/OSS 等
- 卷备份:通过 storage 插件(VolumeSnapshot / FileSystem Backup)
组件:
- velero CLI(本地管理)
- velero server + node-agent(数据卷备份)
- 云插件(AWS/GCP/Azure/通用 S3)
3.2 安装与首个备份
# 安装(AWS S3 示例)
velero install \
--provider aws --bucket my-cluster-backups \
--secret-file ./cloud-credentials \
--backup-location-config region=us-east-1,bucket=my-cluster-backups \
--snapshot-location-config region=us-east-1
# 创建一次备份
velero backup create myapp-$(date +%F) \
--include-namespaces shop # 备份 shop 命名空间
# 查看备份进度
velero backup describe myapp-XXXX
velero backup get
3.3 常用备份子集
# 按标签 / 类型 / 命名空间精确选择
velero backup create app-backup \
--selector app=api,env=prod # 标签
--include-namespaces shop,payment # 命名空间
--exclude-resources=events # 排除(大而无用)
--include-cluster-resources=true # 是否包含集群级资源
提示:
- 用 Schedule 做定时备份(见第 4 节–其实是等值)
- 关注备份体积与耗时(首备常大,日常增量),监控失败
4. etcd 快照:控制面真相源
4.1 为什么备份 etcd
etcd 保存集群的"全部声明式对象",是控制面的真相源:
- 误删 namespace / 误改 Deployment 反了 → 能从快照找回来
- 控制面节点彻底损坏 → 从 etcd 快照恢复整个集群定义
备份方式:etcdctl snapshot save
注意:etcd 备份只救"控制面状态",
不救"PersistentVolume 数据"(那要卷备份)——两者要分开。
4.2 etcd 快照示例
# 在 etcd 节点(或管理 cert)上执行
ETCDCTL_ENDPOINTS=https://10.0.0.5:2379 \
ETCDCTL_CACERT=/etc/etcd/ca.pem \
ETCDCTL_CERT=/etc/etcd/server.crt \
ETCDCTL_KEY=/etc/etcd/server-key.pem \
etcdctl snapshot save etcd-snapshot-$(date +%F).db
# 校验快照可用
etcdctl snapshot status etcd-snapshot-XXXX.db
# 恢复到临时目录验证(见演练)
etcdctl snapshot restore etcd-snapshot-XXXX.db \
--name master-1 --data-dir /new/etcd ...
定时与保留:
- cron 每天 + 保留 N 份
- 或 Velero 的 "etcd" 插件(如 open-cluster 的备份插件)自动化
记录:恢复 etcd 要"整机整集群"配合(member 恢复、节点拓扑重建)
5. CSI 快照与持久化数据备份
5.1 卷备份的两条路
方式一:CSI VolumeSnapshot(快照)
云存储的原生快照,秒级、增量、低成本
前提:StorageClass 支持 CSI(csi-informer/快照 CRD)
方式二:文件级备份(Velero fileSystemBackup)
把 PV 里文件打包上传(对不支持快照的存储/数据库文件也适用)
数据拷全、可做时间点,但占用存储、耗时
依据:哪种都有 Cost;数据库常需要"应用层一致"(先 flush)
5.2 CSI 快照
# 创建 VolumeSnapshot(针对某个 PVC)
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: order-data-snap-001
namespace: shop
spec:
volumeSnapshotClassName: csi-snap
source:
persistentVolumeClaimName: order-data-0
# 从快照恢复 → 创建一个可从快照克隆的 PVC
kubectl get volumesnapshot order-data-snap-001
velero backup create order-data-snap \
--snapshot-volumes --include-volumes order-data-0
ℹ️ 数据一致性:数据库/消息在快照前应"逻辑一致"——先用配套机制(应用层 flush/停写/停服务)进入一致状态,再快照,否则得到的可能是"崩溃一致"(不可靠)的备份。
6. Restore:恢复 vs 策略
6.1 完整恢复流程
# 恢复到另一个(同名或新)命名空间
velero restore create --from-backup my-backup \
--include-namespaces shop --namespace-mappings shop:shop-restored
# 查看与校验
velero restore describe restored-XXXX
velero restore get
Restore 策略:
- 同命名空间恢复(覆盖/新建)
- 新命名空间恢复(maps)
- 排除/包含 PV 的数据
恢复注意:
- 恢复前确认目标集群有对应 storageclass / StorageProvider
- 恢复 out,时间尽量等数据完整,勿操之过急
7. 跨集群/跨区域容灾与 RPO
7.1 RTO / RPO
两个关键指标:
RPO(Recovery Point Objective):可接受丢失多长时间的数据
例 RPO=1h → 备份频率至少要每小时一次
RTO(Recovery Time Objective):可接受多快恢复服务
例 RTO=2h → 只要 2 小时内能跑起来
设计:
RPO 决定"备份频率"(快照/日志/CDC)
RTO 决定"网络+存储恢复速度"
一般来说 RPO 小时级 → 备份+快照;RPO 分钟级 → 加日志/WAL
7.2 跨集群/跨区域容灾
模式一:主备活动区
备份到对区对象存储,灾后在对区新集群恢复(RTO=分钟~小时)
模式二:双集群/双活
数据按区复制 + 双写/多活(RTO 更小,但复杂)
怎么选:
- 首推:从"可恢复的有效备份"开始(先把 RPO/RTO 做到 可信)
- 加容量:先做"备份 + 演练",再做"热备同步"
跨区时,Velero 支持跨 region 的对象存储 + 双区复制,让备份与恢复都不依赖单一区域。
8. 恢复演练:让备份真的能救
8.1 为什么必须演练
"备份没演练 = 备份不存在"
真实故障时没有时间去学 Velelo API、去找恢复流程。
演练 = 把"灾后 恢复" 练成"脚本化、可一键执行、有 SOP"
- 每季度/每发布前做一次"全量恢复演练"
- 恢复到一个干净的沙箱集群
- 验证:集群对象恢复、数据 volume 恢复、应用能启动、
数据不丢、业务 SLO 恢复
- 记录演练时长 → 体检我们的 RTO 是否达标
8.2 演练流程示例
目标:恢复整个 shop 集群到新集群,2 小时内可服务
步骤:
1. 建一个干净的新集群(不同的集群)
2. velero install(连同一对象存储的备份)
3. 列出可用 backup → 选最新
4. 执行恢复(元数据 + 卷)
5. 检查:Deployment Running / Service 可达 / 数据一致
6. 计时 → 是否 < RTO → 修正超出项
7. 记录:恢复顺序、瓶颈点、下次优化项
产出:SOP 文档 + 自动化脚本(可用定时任务自动定期跑)
9. 生产最佳实践与避坑
9.1 Checklist
□ 明确备份范围(etcd:元数据+数据,Volume:业务数据)
□ 定义 RPO / RTO:根据业务损失与恢复要求
□ 备份频率 >= 1/RPO(cron 定时)
□ 备份留存:多版本、保留窗口(如 14 天 / N 份)
□ 数据一致性:数据库备份前搞 flush/得一致点
□ 用 Velero Schedule + CSI 快照自动化
□ 备份存储异地(跨区对象存储)
□ 每季度一次全量恢复演练 + RTO 验证
□ 恢复 SOP 文档化、可执行
□ 监控备份成功率/失败告警(防止悄悄失败)
9.2 常见坑
| 坑 | 现象 | 对策 |
|---|---|---|
| 只备 etcd | 数据盘丢了 | 加上数据卷备份 |
| 没演练 | 灾时才学 | 季度演练 + SOP |
| 备份静默失败 | 以为有其实没有 | 监控 backup 成功/告警 |
| 恢复不了 | 依赖存储缺失 | 演练发现补齐 |
| RPO 不对齐 | 丢数据超预期 | 按 RPO 定备份频率 |
| 一致性问题 | 数据损坏 | 备份前 flush / 用 WAL |
9.3 一句话原则
备份的本义不是"存了快照",而是"到灾难时你能用几分钟把它变成可用的服务"。
小结
K8s 容灾 = etcd(控制面真相)+ Velero/CSI(元数据与数据)+ 定期演练(让 RPO/RTO 真实) 的组合。别只盯"有没有备",要盯"能不能恢复、何时能恢复"。落地记住五件事:etcd 备集群真相、Velero/CSI 备业务数据、按 RPO 定频率、每季度全量恢复演练、监控备份失败。当灾难真的从天而降时,一张"演练过、秒级可执行、数据完整"的恢复 SOP,就是团队和业务之间最后一道、也是最值钱的一道防线。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。