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 集群提供稳定的数据保障。