16.5.5 数据备份、恢复与迁移策略
在 Kubernetes 中,持久化数据的可靠性依赖于清晰的备份与恢复策略。本节从备份对象、工具与流程出发,覆盖应用级与存储级方案,结合迁移实践,确保在故障、升级与跨集群迁移场景下的数据可用性与一致性。
备份与恢复对象与边界#
- 数据平面:PVC/PV 持久化数据、数据库/中间件实例数据目录、对象存储中的文件与快照。
- 控制平面:Kubernetes 资源清单(Deployment、StatefulSet、Service、Ingress、ConfigMap、Secret 等)。
- 应用配置:Helm values、应用参数、初始化脚本、访问凭证与密钥。
原理草图(对象与流程边界):
备份策略与频率设计#
- RPO/RTO 定义:根据业务等级设置恢复点目标与恢复时间目标。
- 分层备份:
- 频繁快照(分钟/小时级)用于高频回滚
- 日备份用于稳定恢复
- 周/月归档用于灾备与审计
- 一致性策略:
- 应用一致性:通过 pre-freeze/post-thaw 钩子、应用暂停写入
- 存储一致性:存储快照与底层快照一致
示例:使用 CronJob + restic 进行 PVC 文件级备份
# 1) 创建备份命名空间
kubectl create ns backup
# 2) 创建 restic 仓库密码
kubectl -n backup create secret generic restic-secret \
--from-literal=RESTIC_PASSWORD='StrongPass123'
# 3) 创建对象存储凭证(示例为 S3 兼容)
kubectl -n backup create secret generic s3-cred \
--from-literal=AWS_ACCESS_KEY_ID='minioadmin' \
--from-literal=AWS_SECRET_ACCESS_KEY='minioadmin'
# 4) 查看 PVC 与挂载点(确认备份对象)
kubectl -n app get pvc
# /tmp/cronjob-restic.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: pvc-restic-backup
namespace: backup
spec:
schedule: "0 2 * * *"
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: restic
image: restic/restic:0.15.2
envFrom:
- secretRef:
name: restic-secret
env:
- name: RESTIC_REPOSITORY
value: s3:http://minio.minio.svc:9000/backup
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: s3-cred
key: AWS_ACCESS_KEY_ID
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: s3-cred
key: AWS_SECRET_ACCESS_KEY
command:
- /bin/sh
- -c
- |
restic init || true
restic backup /data
restic snapshots
volumeMounts:
- name: app-data
mountPath: /data
volumes:
- name: app-data
persistentVolumeClaim:
claimName: app-pvc
# 5) 应用 CronJob 并检查结果
kubectl apply -f /tmp/cronjob-restic.yaml
kubectl -n backup get jobs
kubectl -n backup logs job/pvc-restic-backup-<job-suffix>
数据备份方式#
- 文件级备份:适用于通用文件服务与简单应用
- 方案:rsync、restic、tar+对象存储
- 存储级快照:适用于支持 CSI Snapshot 的存储
- 方案:VolumeSnapshot + VolumeSnapshotClass
- 优点:速度快、影响小
- 应用级备份:适用于数据库与中间件
- MySQL:mysqldump、xtrabackup
- Redis:RDB/AOF 文件备份
- Kafka/zk:配置与数据目录归档,重建优先
- 集群资源备份:
- 使用
kubectl get -A -o yaml或 GitOps/Helm 仓库存储
示例:CSI 快照创建与恢复(适用于支持 Snapshot 的存储)
# /tmp/snapshot.yaml
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: app-pvc-snap-20240101
namespace: app
spec:
volumeSnapshotClassName: csi-snapclass
source:
persistentVolumeClaimName: app-pvc
# 创建快照
kubectl apply -f /tmp/snapshot.yaml
kubectl -n app get volumesnapshot
# 通过快照恢复到新 PVC
cat <<'EOF' > /tmp/pvc-restore.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-pvc-restore
namespace: app
spec:
storageClassName: csi-sc
dataSource:
name: app-pvc-snap-20240101
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
EOF
kubectl apply -f /tmp/pvc-restore.yaml
kubectl -n app get pvc
示例:MySQL 应用级备份(容器内执行)
# 进入 MySQL Pod
kubectl -n db exec -it mysql-0 -- /bin/sh
# 执行备份并输出到挂载卷
mysqldump -uroot -p'pass' --single-transaction --databases appdb > /backup/appdb.sql
# 退出后校验
kubectl -n db exec -it mysql-0 -- ls -lh /backup
恢复流程与验证#
- 恢复流程:备份源 → 恢复环境准备 → PV/PVC 恢复 → 应用启动 → 校验
- 关键校验:
- 数据校验:校验和、应用逻辑校验
- 服务校验:接口健康检查、业务读写测试
- 演练要求:定期进行恢复演练并记录耗时与恢复成功率
示例:restic 恢复到新 PVC
# 1) 创建临时 Pod 挂载新 PVC
cat <<'EOF' > /tmp/restore-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: restic-restore
namespace: backup
spec:
restartPolicy: Never
containers:
- name: restic
image: restic/restic:0.15.2
envFrom:
- secretRef:
name: restic-secret
env:
- name: RESTIC_REPOSITORY
value: s3:http://minio.minio.svc:9000/backup
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: s3-cred
key: AWS_ACCESS_KEY_ID
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: s3-cred
key: AWS_SECRET_ACCESS_KEY
command: ["/bin/sh","-c"]
args:
- |
restic snapshots
restic restore latest --target /restore
ls -lh /restore
volumeMounts:
- name: restore-pvc
mountPath: /restore
volumes:
- name: restore-pvc
persistentVolumeClaim:
claimName: app-pvc-restore
EOF
kubectl apply -f /tmp/restore-pod.yaml
kubectl -n backup logs -f pod/restic-restore
校验示例(应用逻辑):
# 假设应用有健康检查接口
kubectl -n app port-forward svc/app 8080:80
curl -s http://127.0.0.1:8080/health
数据迁移策略#
- 同集群迁移:
- PVC 重绑定、PV 重新挂载或数据复制
- 注意 UID/GID/权限一致
- 跨集群迁移:
- 资源清单迁移:通过 GitOps/Helm 统一管理
- 数据迁移:对象存储中转、快照导出/导入
- DNS/入口切换策略:灰度切换与双写同步
- 零停机迁移:
- 双写同步 + 读流量切换
- 数据一致性校验后关闭旧集群
示例:同集群迁移(rsync)
# 源 Pod -> 目标 Pod,要求两端已挂载 PVC
kubectl -n app exec -it src-pod -- /bin/sh -c "tar -C /data -cf - . " \
| kubectl -n app exec -i dst-pod -- /bin/sh -c "tar -C /data -xpf -"
# 校验文件数量一致
kubectl -n app exec -it src-pod -- /bin/sh -c "find /data | wc -l"
kubectl -n app exec -it dst-pod -- /bin/sh -c "find /data | wc -l"
示例:跨集群迁移(对象存储中转)
# 在源集群导出备份并上传
restic -r s3:http://minio.example.com/backup backup /data
restic -r s3:http://minio.example.com/backup snapshots
# 在目标集群恢复
restic -r s3:http://minio.example.com/backup restore latest --target /data
工具与实践建议#
- Velero:备份 Kubernetes 资源与 PVC 数据,支持对象存储
- CSI Snapshot:依赖存储提供商支持,适用于快速恢复
- 自建备份流程:CronJob + restic/rsync + 对象存储
- 统一存储策略:结合 StorageClass 与 SnapshotClass 规范管理
Velero 安装与基本使用示例(MinIO 为对象存储)
# 1) 安装 velero(示例使用 v1.12)
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.8.0 \
--bucket k8s-backup \
--secret-file /tmp/credentials-velero \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://minio.minio.svc:9000
# 2) 创建备份(包含资源和 PVC 快照)
velero backup create app-full \
--include-namespaces app \
--snapshot-volumes
# 3) 查看备份与恢复
velero backup get
velero restore create --from-backup app-full
风险与注意事项#
- 加密与权限:备份数据与对象存储必须加密与权限隔离
- Secret 处理:避免明文泄漏,可采用密钥管理与加密备份
- 版本兼容:恢复时需注意 K8s、存储驱动与应用版本一致性
- 成本评估:快照数量与对象存储成本需纳入规划
常见排错(命令与解释)
# 1) VolumeSnapshot 无法创建:检查 CRD 与 SnapshotClass
kubectl get crd | grep snapshot
kubectl get volumesnapshotclass
# 2) PVC 恢复 Pending:检查存储类与数据源是否匹配
kubectl -n app describe pvc app-pvc-restore
# 3) Velero 备份失败:查看备份详情与日志
velero backup describe app-full --details
kubectl -n velero logs deploy/velero
练习
1. 为 StatefulSet 应用创建一次快照并恢复到新 PVC,验证数据一致性。
2. 编写 CronJob 使用 restic 备份 PVC,并将备份恢复到新环境。
3. 使用 Velero 备份指定命名空间,并进行恢复演练,记录 RTO。
通过建立清晰的备份与恢复策略、标准化的迁移流程与周期性演练,可以显著降低数据丢失风险并提升故障恢复能力,为生产级 Kubernetes 集群提供稳定的数据保障。