本页面介绍如何使用卷快照备份和恢复永久性磁盘存储空间。
如需了解说明,请参阅 Kubernetes 卷快照简介。
使用要求
如需在 GKE 上使用卷快照,必须满足以下要求:
使用支持快照的 CSI 驱动程序。树内永久性磁盘驱动程序不支持快照。如需创建和管理快照,您必须使用与底层
PersistentVolumeClaim
(PVC) 相同的 CSI 驱动程序。对于永久性磁盘 (PD) 卷快照,请使用 Compute Engine 永久性磁盘 CSI 驱动程序。Compute Engine 永久性磁盘 CSI 驱动程序默认安装在运行 GKE 1.18.10-gke.2100 版或更高版本或者 1.19.3-gke.2100 版或更高版本的新 Linux 集群上。您还可以在现有集群上启用 Compute Engine 永久性磁盘 CSI 驱动程序。
如需查看支持快照的所有 CSI 驱动程序列表,请参阅 Kubernetes 文档的驱动程序中的其他功能列。
使用控制层面版本 1.17 或更高版本。如需使用 Compute Engine 永久性磁盘 CSI 驱动程序,请在
VolumeSnapshot
中使用 GKE 1.17.6-gke.4 版或更高版本。
- 已有要用于快照的
PersistentVolumeClaim
。用于快照来源的PersistentVolume
必须由 CSI 驱动程序管理。您可以通过检查PersistentVolume
规范的csi
部分是否包含driver: pd.csi.storage.gke.io
或filestore.csi.storage.gke.io
来验证是否使用了 CSI 驱动程序。如果PersistentVolume
由 CSI 驱动程序动态预配(如以下部分所述),则它由 CSI 驱动程序管理。
限制
Compute Engine 上创建磁盘快照的所有限制也适用于 GKE。
最佳实践
在 GKE 上使用永久性磁盘 Volume
快照时,请务必遵循 Compute Engine 磁盘快照的最佳做法。
须知事项
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行
gcloud components update
以获取最新版本。
创建和使用卷快照
本文档中的示例展示了如何执行以下操作:
- 创建
PersistentVolumeClaim
和Deployment
。 - 将文件添加到
Deployment
使用的PersistentVolume
。 - 创建
VolumeSnapshotClass
以配置快照。 - 创建
PersistentVolume
的卷快照。 - 删除测试文件。
- 将
PersistentVolume
恢复到您创建的快照。 - 验证恢复是否有效。
如需使用卷快照,您必须完成以下步骤:
- 创建
VolumeSnapshotClass
对象以指定快照的 CSI 驱动程序和删除政策。 - 创建
VolumeSnapshot
对象以请求现有PersistentVolumeClaim
的快照。 - 在
PersistentVolumeClaim
中引用VolumeSnapshot
以将卷恢复到该快照,或者使用该快照创建新卷。
创建 PersistentVolumeClaim
和 Deployment
如需创建
PersistentVolumeClaim
对象,请将以下清单保存为my-pvc.yaml
:Persistent Disk
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pvc spec: storageClassName: standard-rwo accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
此示例使用默认随 Compute Engine 永久性磁盘 CSI 驱动程序安装的
standard-rwo
存储类别。如需了解详情,请参阅使用 Compute Engine 永久性磁盘 CSI 驱动程序。对于
spec.storageClassName
,您可以指定使用受支持的 CSI 驱动程序的任何存储类别。应用清单:
kubectl apply -f my-pvc.yaml
如需创建
Deployment
,请将以下清单保存为my-deployment.yaml
:apiVersion: apps/v1 kind: Deployment metadata: name: hello-app spec: selector: matchLabels: app: hello-app template: metadata: labels: app: hello-app spec: containers: - name: hello-app image: google/cloud-sdk:slim args: [ "sleep", "3600" ] volumeMounts: - name: sdk-volume mountPath: /usr/share/hello/ volumes: - name: sdk-volume persistentVolumeClaim: claimName: my-pvc
应用清单:
kubectl apply -f my-deployment.yaml
检查
Deployment
的状态:kubectl get deployment hello-app
Deployment
可能需要一段时间才能准备就绪。您可以运行上述命令,直到看到类似如下所示的输出:NAME READY UP-TO-DATE AVAILABLE AGE hello-app 1/1 1 1 2m55s
将测试文件添加到卷
列出
Deployment
中的Pods
:kubectl get pods -l app=hello-app
输出类似于以下内容:
NAME READY STATUS RESTARTS AGE hello-app-6d7b457c7d-vl4jr 1/1 Running 0 2m56s
在
Pod
中创建测试文件:kubectl exec POD_NAME \ -- sh -c 'echo "Hello World!" > /usr/share/hello/hello.txt'
将
POD_NAME
替换为Pod
的名称。验证文件是否存在:
kubectl exec POD_NAME \ -- sh -c 'cat /usr/share/hello/hello.txt'
输出内容类似如下:
Hello World!
创建一个 VolumeSnapshotClass
对象
创建一个 VolumeSnapshotClass
对象,以指定卷快照的 CSI 驱动程序和 deletionPolicy
。您可以在创建 VolumeSnapshot
对象时引用 VolumeSnapshotClass
对象。
将以下清单保存为
volumesnapshotclass.yaml
。Persistent Disk
对于运行 1.21 版或更高版本的集群,请使用
v1
API 版本。apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshotClass metadata: name: my-snapshotclass driver: pd.csi.storage.gke.io deletionPolicy: Delete
在此示例中:
CSI 驱动程序使用
driver
字段来预配快照。在此示例中,pd.csi.storage.gke.io
使用 Compute Engine 永久性磁盘 CSI 驱动程序。删除绑定的
VolumeSnapshot
对象后,deletionPolicy
字段会告知 GKE 如何处理VolumeSnapshotContent
对象和底层快照。指定Delete
以删除VolumeSnapshotContent
对象和底层快照。如果要保留VolumeSnapshotContent
和底层快照,请指定Retain
。如需使用自定义存储位置,请向快照类添加
storage-locations
参数。如需使用此参数,您的集群必须使用 1.21 或更高版本。apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshotClass metadata: name: my-snapshotclass parameters: storage-locations: us-east2 driver: pd.csi.storage.gke.io deletionPolicy: Delete
如需创建磁盘映像,请将以下内容添加到
parameters
字段:parameters: snapshot-type: images image-family: IMAGE_FAMILY
将
IMAGE_FAMILY
替换为首选映像系列的名称,例如preloaded-data
。
应用清单:
kubectl apply -f volumesnapshotclass.yaml
创建 VolumeSnapshot
VolumeSnapshot
对象是对现有 PersistentVolumeClaim
对象的快照的请求。当您创建 VolumeSnapshot
对象时,GKE 会自动创建它并将它与 VolumeSnapshotContent
对象绑定在一起(该对象是集群中的资源,例如 PersistentVolume
对象)。
将以下清单保存为
volumesnapshot.yaml
。apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot metadata: name: my-snapshot spec: volumeSnapshotClassName: my-snapshotclass source: persistentVolumeClaimName: my-pvc
应用清单:
kubectl apply -f volumesnapshot.yaml
创建
Volume
快照后,GKE 会在集群中创建相应的VolumeSnapshotContent
对象。此对象用于存储VolumeSnapshot
对象的快照和绑定。您不会直接与VolumeSnapshotContents
对象进行交互:确认 GKE 创建了
VolumeSnapshotContents
对象:kubectl get volumesnapshotcontents
输出类似于以下内容:
NAME AGE snapcontent-cee5fb1f-5427-11ea-a53c-42010a1000da 55s
创建 Volume
快照内容后,您在 VolumeSnapshotClass
中指定的 CSI 驱动程序会在相应存储系统上创建快照。GKE 在存储系统上创建快照并将其绑定到集群上的 VolumeSnapshot
对象后,该快照即可供使用。您可以通过运行以下命令来检查状态:
kubectl get volumesnapshot \
-o custom-columns='NAME:.metadata.name,READY:.status.readyToUse'
如果快照可供使用,则输出类似于以下内容:
NAME READY
my-snapshot true
删除测试文件
删除您创建的测试文件:
kubectl exec POD_NAME \ -- sh -c 'rm /usr/share/hello/hello.txt'
验证文件是否不再存在:
kubectl exec POD_NAME \ -- sh -c 'cat /usr/share/hello/hello.txt'
输出内容类似如下:
cat: /usr/share/hello/hello.txt: No such file or directory
恢复卷快照
您可以在 PersistentVolumeClaim
中引用 VolumeSnapshot
,以使用现有卷中的数据预配新卷,或者将卷恢复到您在快照中捕获的状态。
如需在 PersistentVolumeClaim
中引用 VolumeSnapshot
,请将 dataSource
字段添加到 PersistentVolumeClaim
。无论 VolumeSnapshotContents
引用的是磁盘映像还是快照,都会使用相同的流程。
在此示例中,您可以引用在新 PersistentVolumeClaim
中创建的 VolumeSnapshot
,并更新 Deployment
以使用新声明。
验证您使用的是磁盘快照还是映像快照,不同之处如下:
- 磁盘快照:频繁截取快照,但不常恢复。
- 映像快照:不常截取快照,但频繁恢复。创建映像快照的速度可能也比磁盘快照慢。
如需了解详情,请参阅快照频率限制。在排查任何问题时,了解快照类型将会很有帮助。
检查
VolumeSnapshot
:kubectl describe volumesnapshot SNAPSHOT_NAME
volumeSnapshotClassName
字段指定快照类。kubectl describe volumesnapshotclass SNAPSHOT_CLASS_NAME
snapshot-type
参数将指定snapshots
或images
。如果没有指定该参数,则默认值为snapshots
。如果没有快照类(例如,如果快照是静态创建的),请检查
VolumeSnapshotContents
。sh kubectl describe volumesnapshotcontents SNAPSHOT_CONTENTS_NAME
可通过输出中快照句柄的格式确定快照的类型,如下所示:*projects/PROJECT_NAME/global/snapshots/SNAPSHOT_NAME
:磁盘快照projects/PROJECT_NAME/global/images/IMAGE_NAME
:映像快照
将以下清单保存为
pvc-restore.yaml
:Persistent Disk
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-restore spec: dataSource: name: my-snapshot kind: VolumeSnapshot apiGroup: snapshot.storage.k8s.io storageClassName: standard-rwo accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
应用清单:
kubectl apply -f pvc-restore.yaml
更新
my-deployment.yaml
文件以使用新的PersistentVolumeClaim
:... volumes: - name: my-volume persistentVolumeClaim: claimName: pvc-restore
应用更新后的清单:
kubectl apply -f my-deployment.yaml
检查快照是否已成功恢复
获取 GKE 为更新后的
Deployment
创建的新Pod
的名称:kubectl get pods -l app=hello-app
验证测试文件是否存在:
kubectl exec NEW_POD_NAME \
-- sh -c 'cat /usr/share/hello/hello.txt'
将 NEW_POD_NAME
替换为 GKE 创建的新 Pod
的名称。
输出类似于以下内容:
Hello World!
导入预先存在的快照
您可以使用当前集群外部创建的现有卷快照来手动预配 VolumeSnapshotContents
对象。例如,您可以使用在其他集群中创建的另一个 Google Cloud 资源的快照来填充 GKE 中的卷。
找到快照的名称。
Google Cloud 控制台
Google Cloud CLI
运行以下命令:
gcloud compute snapshots list
输出类似于以下内容:
NAME DISK_SIZE_GB SRC_DISK STATUS snapshot-5e6af474-cbcc-49ed-b53f-32262959a0a0 1 us-central1-b/disks/pvc-69f80fca-bb06-4519-9e7d-b26f45c1f4aa READY
将以下
VolumeSnapshot
清单保存为restored-snapshot.yaml
。apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot metadata: name: restored-snapshot spec: volumeSnapshotClassName: my-snapshotclass source: volumeSnapshotContentName: restored-snapshot-content
应用清单:
kubectl apply -f restored-snapshot.yaml
将以下
VolumeSnapshotContent
清单保存为restored-snapshot-content.yaml
。将snapshotHandle
字段替换为您的项目 ID 和快照名称。volumeSnapshotRef.name
和volumeSnapshotRef.namespace
都必须指向之前创建的VolumeSnapshot
,双向绑定才会有效。apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshotContent metadata: name: restored-snapshot-content spec: deletionPolicy: Retain driver: pd.csi.storage.gke.io source: snapshotHandle: projects/PROJECT_ID/global/snapshots/SNAPSHOT_NAME volumeSnapshotRef: kind: VolumeSnapshot name: restored-snapshot namespace: default
应用清单:
kubectl apply -f restored-snapshot-content.yaml
将以下
PersistentVolumeClaim
清单保存为restored-pvc.yaml
。Kubernetes 存储控制器会找到名为restored-snapshot
的VolumeSnapshot
,然后尝试找到或动态创建PersistentVolume
作为数据源。然后,您可以在 Pod 中使用此 PVC 来访问恢复的数据。apiVersion: v1 kind: PersistentVolumeClaim metadata: name: restored-pvc spec: dataSource: name: restored-snapshot kind: VolumeSnapshot apiGroup: snapshot.storage.k8s.io storageClassName: standard-rwo accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
应用清单:
kubectl apply -f restored-pvc.yaml
将以下
Pod
清单保存为引用PersistentVolumeClaim
的restored-pod.yaml
。CSI 驱动程序将预配PersistentVolume
并从快照进行填充。apiVersion: v1 kind: Pod metadata: name: restored-pod spec: containers: - name: busybox image: busybox args: - sleep - "3600" volumeMounts: - name: source-data mountPath: /demo/data volumes: - name: source-data persistentVolumeClaim: claimName: restored-pvc readOnly: false
应用清单:
kubectl apply -f restored-pod.yaml
验证该文件是否已恢复:
kubectl exec restored-pod -- sh -c 'cat /demo/data/hello.txt'
清理
为避免因本页中使用的资源导致您的 Google Cloud 账号产生费用,请按照以下步骤操作。
删除
VolumeSnapshot
:kubectl delete volumesnapshot my-snapshot
删除
VolumeSnapshotClass
:kubectl delete volumesnapshotclass my-snapshotclass
删除
Deployment
:kubectl delete deployments hello-app
删除
PersistentVolumeClaim
对象:kubectl delete pvc my-pvc pvc-restore
后续步骤
- 阅读 Kubernetes 卷快照文档。
- 了解卷扩展。
- 了解如何手动安装 CSI 驱动程序。
- 了解 GKE 的块存储(永久性磁盘)。