在使用存储时,为了提高数据操作的容错性,我们通常有需要对线上数据进行 snapshot ,以及能快速 restore 的能力。另外,当需要对线上数据进行快速的复制以及迁移等动作,如进行环境的复制、数据开发等功能时,都可以通过存储快照来满足需求,而 K8s 中通过 CSI Snapshotter controller 来实现存储快照的功能。

K8S的Volume Snapshot(存储快照)在v1.12版本中进入alpha版,在v1.17版进入Beta版。

在K8S中,我们是通过PV和PVC来使用存储,而存储快照也是参考了PV和PVC的设计思想,当用户要使用存储快照的功能时,就通过VolumeSnapshot对象来声明,并指定相应的VolumeSnapshotClass对象,之后由集群中相关的组件来动态生成存储快照和相应的对象VolumeSnapshotContent。

其动态生成VolumeSnapshotContent的过程和动态生成PV的流程相似,如下(图片来自阿里云课堂):
image.png

当我们有了存储快照,如果我们要使用它,应该怎么做呢?我们只需要在定义PVC的时候指定.spec.dataSource为VolumeSnapshot对象,从而根据PVC对象生成新的PV对象。而对应的存储数据则是通过VolumeSnapshot所关联的VolumeSnapshotContent中恢复而来,流程如下(图片来自阿里云课堂)。
image.png

介绍了这么多,如果我们要使用Volume Snapshot,我们需要确定以下几点:

Kubernetes支持三种存储插件:

  • in-tree
  • Flex
  • CSI

但是Volume Snapshot仅支持CSI,所以如果要使用Volume Snapshot,就需要你确保CSI驱动已经存在于你的集群中,要查看有哪些CSI驱动可以应用于K8S集群,请点击详情

使用Volume Snapshot

1、安装CRDs

项目地址:https://github.com/kubernetes-csi/external-snapshotter/tree/master/config/crd

(1)、下载项目

  1. # git clone https://github.com/kubernetes-csi/external-snapshotter.git

(2)、部署CRDs对象

  1. # kubectl create -f config/crd
  2. customresourcedefinition.apiextensions.k8s.io/volumesnapshotclasses.snapshot.storage.k8s.io created
  3. customresourcedefinition.apiextensions.k8s.io/volumesnapshotcontents.snapshot.storage.k8s.io created
  4. customresourcedefinition.apiextensions.k8s.io/volumesnapshots.snapshot.storage.k8s.io created

(3)、查看创建的CRDs对象

  1. # kubectl get crd|grep volumesnapshot
  2. volumesnapshotclasses.snapshot.storage.k8s.io 2020-02-10T06:47:14Z
  3. volumesnapshotcontents.snapshot.storage.k8s.io 2020-02-10T06:47:15Z
  4. volumesnapshots.snapshot.storage.k8s.io 2020-02-10T06:47:15Z

2、安装Snapshot Controller

项目地址:https://github.com/kubernetes-csi/external-snapshotter/tree/master/deploy/kubernetes/snapshot-controller

由于我们上面已经将整个项目都clone下来了,我们这里直接创建即可,如下:

  1. # kubectl create -f deploy/kubernetes/snapshot-controller
  2. serviceaccount/snapshot-controller created
  3. clusterrole.rbac.authorization.k8s.io/snapshot-controller-runner created
  4. clusterrolebinding.rbac.authorization.k8s.io/snapshot-controller-role created
  5. role.rbac.authorization.k8s.io/snapshot-controller-leaderelection created
  6. rolebinding.rbac.authorization.k8s.io/snapshot-controller-leaderelection created
  7. statefulset.apps/snapshot-controller created

查看创建结果

  1. # kubectl get pod
  2. NAME READY STATUS RESTARTS AGE
  3. glusterfs 1/1 Running 0 4d3h
  4. snapshot-controller-0 1/1 Running 0 21m
  5. # kubectl get statefulset
  6. NAME READY AGE
  7. snapshot-controller 1/1 21m

3、安装CSI驱动

根据自己的存储来安装对应的CSI驱动,如果不清楚的请点击详情

由于我这里的底层存储是Glusterfs,所以我就安装Glusterfs CSI驱动。项目地址:https://github.com/gluster/gluster-csi-driver

4、创建存储快照测试用例

(1)、创建VolumeSnapshotClass对象

  1. apiVersion: snapshot.storage.k8s.io/v1beta1
  2. kind: VolumeSnapshotClass
  3. metadata:
  4. name: test-snapclass
  5. driver: org.gluster.glusterfs
  6. deletionPolicy: Delete
  7. parameters:
  8. csi.storage.k8s.io/snapshotter-secret-name: mysecret
  9. csi.storage.k8s.io/snapshotter-secret-namespace: mysecretnamespace

(2)、创建VolumeSnapshot对象

  1. apiVersion: snapshot.storage.k8s.io/v1beta1
  2. kind: VolumeSnapshot
  3. metadata:
  4. name: test-snapshot
  5. spec:
  6. volumeSnapshotClassName: test-snapclass
  7. source:
  8. persistentVolumeClaimName: test-pvc # 已存在的pvc

5、从存储快照恢复数据测试用例

卷克隆功能借助于PVC中的dataSource字段。
要使用该功能,需要注意以下事项:

  • 克隆支持(VolumePVCDataSource)仅适用于 CSI 驱动。
  • 克隆支持仅适用于 动态供应器。
  • CSI 驱动可能实现,也可能未实现卷克隆功能。
  • 仅当 PVC 与目标 PVC 存在于同一命名空间(源和目标 PVC 必须在相同的命名空间)时,才可以克隆 PVC。
  • 仅在同一存储类中支持克隆。
    • 目标卷必须和源卷具有相同的存储类
    • 可以使用默认的存储类并且 storageClassName 字段在规格中忽略了

用例如下:

  1. apiVersion: v1
  2. kind: PersistentVolumeClaim
  3. metadata:
  4. name: pvc-restore
  5. namespace: demo-namespace
  6. spec:
  7. storageClassName: org.gluster.glusterfs
  8. dataSource:
  9. name: test-snapshot
  10. kind: VolumeSnapshot
  11. apiGroup: snapshot.storage.k8s.io
  12. accessModes:
  13. - ReadWriteOnce
  14. resources:
  15. requests:
  16. storage: 1Gi

参考文档: