VolumeSnapshot 企业快照与一致性恢复

验证:未记录
适用版本
未记录
验证范围
尚未登记验证记录。
本文缩写(英文全称与中文含义)
缩写 英文全称/名称 中文含义
API Application Programming Interface 应用程序编程接口
CRD Custom Resource Definition Kubernetes 自定义资源定义
CSI Container Storage Interface 容器存储接口
DB Database 数据库
EBS Elastic Block Store AWS 块存储服务
EKS Elastic Kubernetes Service AWS 托管 Kubernetes 服务
GKE Google Kubernetes Engine Google 托管 Kubernetes 服务
IAM Identity and Access Management 身份与访问管理
KMS Key Management Service 密钥管理服务
PITR Point-In-Time Recovery 时间点恢复
PV Persistent Volume 持久卷
PVC Persistent Volume Claim 持久卷申领
RBAC Role-Based Access Control 基于角色的访问控制
RPO Recovery Point Objective 恢复点目标,可接受的数据丢失时间范围
SHA Secure Hash Algorithm 安全散列算法
WAL Write-Ahead Log 预写日志
YAML YAML Ain’t Markup Language 常用于配置文件的数据序列化语言

场景:对 CSI 篇 的真实对账数据卷做可恢复快照。快照不是完整集群备份,也不必然跨账户/跨区域;数据库在线卷快照通常只有 crash consistency,需原生备份/WAL/PITR 或应用 quiesce 配合。

前置能力#

集群必须有 snapshot CRD、snapshot-controller,以及支持快照的 CSI driver/sidecar。GKE/EKS 可能提供托管组件,先检查 ownership,不能再安装第二个 controller:

kubectl get crd volumesnapshots.snapshot.storage.k8s.io
kubectl get volumesnapshotclasses
kubectl get pods -A | rg 'snapshot|csi'

自建环境使用固定版本 external-snapshotter 的 CRD 与 controller manifests,检查兼容表后部署;controller RBAC、leader election、副本分散由平台维护。VolumeSnapshotClass.driver 必须与 PVC 对应 CSI driver 相同。

Hands-on:静止写入→快照→新卷验证#

  1. 暂停预生产对账调度,等在途 Job 完成并关闭文件;记录批次水位、文件清单/校验和。写入者不止一个时全部协调,不能仅 scale 一个 Pod。
  2. 保存 orders-snapshot.yaml(EBS 示例;GKE 改 driver 为 pd.csi.storage.gke.io):
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata: {name: orders-retained}
driver: ebs.csi.aws.com
deletionPolicy: Retain
---
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata: {name: reports-before-change, namespace: orders}
spec:
  volumeSnapshotClassName: orders-retained
  source: {persistentVolumeClaimName: orders-reports}
kubectl apply -f orders-snapshot.yaml
kubectl -n orders wait --for=jsonpath='{.status.readyToUse}'=true volumesnapshot/reports-before-change --timeout=20m
kubectl -n orders get volumesnapshot reports-before-change -o yaml
kubectl get volumesnapshotcontents

快照 ready、云端状态正常且水位已记录后恢复源业务写入。保留 snapshotHandle、大小、区域/账户、KMS key、Class 与 PVC/PV metadata 到受限备份库;不只保存一个 Kubernetes 对象名。

  1. 保存 orders-restore-pvc.yaml;容量至少为快照要求的 restoreSize,示例使用扩容后的 150Gi:
apiVersion: v1
kind: PersistentVolumeClaim
metadata: {name: orders-reports-restore, namespace: orders}
spec:
  storageClassName: orders-gp3
  accessModes: [ReadWriteOnce]
  resources:
    requests: {storage: 150Gi}
  dataSource:
    apiGroup: snapshot.storage.k8s.io
    kind: VolumeSnapshot
    name: reports-before-change
kubectl apply -f orders-restore-pvc.yaml
kubectl -n orders get pvc orders-reports-restore
  1. 用企业批准的对账验证 Job 只读挂载新 PVC,不覆盖源 PVC;对比文件 SHA-256、批次数量、金额与水位。WaitForFirstConsumer 下新卷会等该 Job 调度后才绑定。

  2. 正式业务恢复先隔离写入者,修改引用到新卷并验收;源卷保留,避免二者同时写。快照后的新写入需从业务日志/原生备份重放,不能凭快照宣称 RPO=0。

可执行的只读文件验收#

以下覆盖整棵业务文件目录,比较文件集合、大小和 SHA-256;业务金额/批次仍需应用对账。先下载 volume-manifest.py,再保存以下 verify-pod.yaml。镜像需包含 Python 3,并替换成企业批准的 digest;UID/GID 必须有源文件读取权限,不为演练修改卷权限。

apiVersion: v1
kind: Pod
metadata:
  name: reports-verify
  namespace: orders
  labels: {purpose: restore-verification}
spec:
  automountServiceAccountToken: false
  restartPolicy: Never
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    runAsGroup: 1000
    seccompProfile: {type: RuntimeDefault}
  containers:
    - name: verify
      image: REPLACE_APPROVED_PYTHON_IMAGE_AT_DIGEST
      command: [python3, -c, 'import time; time.sleep(7200)']
      resources:
        requests: {cpu: 100m, memory: 128Mi}
        limits: {cpu: '1', memory: 512Mi}
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities: {drop: [ALL]}
      volumeMounts:
        - {name: reports, mountPath: /reports, readOnly: true}
  volumes:
    - name: reports
      persistentVolumeClaim: {claimName: orders-reports, readOnly: true}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: {name: reports-verify, namespace: orders}
spec:
  podSelector: {matchLabels: {purpose: restore-verification}}
  policyTypes: [Ingress, Egress]
  ingress: []
  egress: []

在步骤 1 静止写入后、步骤 2 快照前执行。确保原写入 Pod 已退出并释放挂载,避免 ReadWriteOnce 跨节点挂载冲突;只终止已完成的任务,不强删仍在写入的 Pod。/reports/batches 换成真实对账目录,必须覆盖此次恢复范围:

set -euo pipefail
umask 077
kubectl apply -f verify-pod.yaml
kubectl -n orders wait --for=condition=Ready pod/reports-verify --timeout=10m
kubectl -n orders exec -i reports-verify -- python3 - /reports/batches < volume-manifest.py > source-manifest.json
kubectl -n orders delete pod reports-verify --wait=true

将源清单与批次水位、快照 ID 一起存入受限证据库;清单在卷外保存。成功生成清单后才做快照,期间仍禁止源写入。清单可能含敏感文件名,不提交 Git。

步骤 4 时,将 YAML 的 claimName 改为 orders-reports-restore,再次运行:

set -euo pipefail
kubectl apply -f verify-pod.yaml
kubectl -n orders wait --for=condition=Ready pod/reports-verify --timeout=10m
kubectl -n orders exec -i reports-verify -- python3 - /reports/batches < volume-manifest.py > restored-manifest.json
cmp source-manifest.json restored-manifest.json
kubectl -n orders delete pod reports-verify --wait=true

cmp 退出码必须为 0;缺文件、多文件、大小/内容变化均失败。校验失败保留新卷排查,不切流;脚本拒绝符号链接和特殊文件,不比较所有权、ACL 或扩展属性。海量文件需规划清单内存和哈希 I/O 窗口。完成后删除本次 NetworkPolicy,源/恢复 PVC 和快照按保留策略单独处理。

企业故障与回收#

问题 检查
Snapshot 一直不 ready Class driver、snapshot-controller/CSI 日志、源 PVC、IAM/KMS、云 API 限额
恢复卷 Pending 消费者是否存在、StorageClass 拓扑/容量、区域及 KMS 权限
文件可读但业务不一致 快照时写入未静止、外部 DB/队列水位不一致,需要应用级恢复

演练恢复到另一个已授权集群/账户时,额外验证快照共享/复制、KMS 授权、预置 VolumeSnapshotContent 与 API 版本,不能复制 YAML 就认为数据已迁移。Retain 下删除 Snapshot 不会替你清除所有云快照,设保留期/资产清单防泄漏费用。Kubernetes 快照语义

搜索文档

输入关键词,搜索所有文档。

↑ ↓ 选择 · Enter 打开 · Esc 关闭