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:静止写入→快照→新卷验证#
- 暂停预生产对账调度,等在途 Job 完成并关闭文件;记录批次水位、文件清单/校验和。写入者不止一个时全部协调,不能仅 scale 一个 Pod。
- 保存
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 对象名。
- 保存
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-changekubectl apply -f orders-restore-pvc.yaml
kubectl -n orders get pvc orders-reports-restore-
用企业批准的对账验证 Job 只读挂载新 PVC,不覆盖源 PVC;对比文件 SHA-256、批次数量、金额与水位。WaitForFirstConsumer 下新卷会等该 Job 调度后才绑定。
-
正式业务恢复先隔离写入者,修改引用到新卷并验收;源卷保留,避免二者同时写。快照后的新写入需从业务日志/原生备份重放,不能凭快照宣称 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=truecmp 退出码必须为 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 快照语义