在使用存储时,为了提高数据操作的容错性,我们通常有需要对线上数据进行 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的流程相似,如下(图片来自阿里云课堂):
当我们有了存储快照,如果我们要使用它,应该怎么做呢?我们只需要在定义PVC的时候指定.spec.dataSource为VolumeSnapshot对象,从而根据PVC对象生成新的PV对象。而对应的存储数据则是通过VolumeSnapshot所关联的VolumeSnapshotContent中恢复而来,流程如下(图片来自阿里云课堂)。
介绍了这么多,如果我们要使用Volume Snapshot,我们需要确定以下几点:
- 确保已经在你的集群中安装了Kubernetes Volume Snapshot CRDs
- 确保已经在你的集群中安装了Volume snapshot controller
- Kubernetes Volume Snapshot仅可用于CSI驱动
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)、下载项目
# git clone https://github.com/kubernetes-csi/external-snapshotter.git
(2)、部署CRDs对象
# kubectl create -f config/crd
customresourcedefinition.apiextensions.k8s.io/volumesnapshotclasses.snapshot.storage.k8s.io created
customresourcedefinition.apiextensions.k8s.io/volumesnapshotcontents.snapshot.storage.k8s.io created
customresourcedefinition.apiextensions.k8s.io/volumesnapshots.snapshot.storage.k8s.io created
(3)、查看创建的CRDs对象
# kubectl get crd|grep volumesnapshot
volumesnapshotclasses.snapshot.storage.k8s.io 2020-02-10T06:47:14Z
volumesnapshotcontents.snapshot.storage.k8s.io 2020-02-10T06:47:15Z
volumesnapshots.snapshot.storage.k8s.io 2020-02-10T06:47:15Z
2、安装Snapshot Controller
由于我们上面已经将整个项目都clone下来了,我们这里直接创建即可,如下:
# kubectl create -f deploy/kubernetes/snapshot-controller
serviceaccount/snapshot-controller created
clusterrole.rbac.authorization.k8s.io/snapshot-controller-runner created
clusterrolebinding.rbac.authorization.k8s.io/snapshot-controller-role created
role.rbac.authorization.k8s.io/snapshot-controller-leaderelection created
rolebinding.rbac.authorization.k8s.io/snapshot-controller-leaderelection created
statefulset.apps/snapshot-controller created
查看创建结果
# kubectl get pod
NAME READY STATUS RESTARTS AGE
glusterfs 1/1 Running 0 4d3h
snapshot-controller-0 1/1 Running 0 21m
# kubectl get statefulset
NAME READY AGE
snapshot-controller 1/1 21m
3、安装CSI驱动
根据自己的存储来安装对应的CSI驱动,如果不清楚的请点击详情。
由于我这里的底层存储是Glusterfs,所以我就安装Glusterfs CSI驱动。项目地址:https://github.com/gluster/gluster-csi-driver
4、创建存储快照测试用例
(1)、创建VolumeSnapshotClass对象
apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshotClass
metadata:
name: test-snapclass
driver: org.gluster.glusterfs
deletionPolicy: Delete
parameters:
csi.storage.k8s.io/snapshotter-secret-name: mysecret
csi.storage.k8s.io/snapshotter-secret-namespace: mysecretnamespace
(2)、创建VolumeSnapshot对象
apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshot
metadata:
name: test-snapshot
spec:
volumeSnapshotClassName: test-snapclass
source:
persistentVolumeClaimName: test-pvc # 已存在的pvc
5、从存储快照恢复数据测试用例
卷克隆功能借助于PVC中的dataSource字段。
要使用该功能,需要注意以下事项:
- 克隆支持(
VolumePVCDataSource
)仅适用于 CSI 驱动。 - 克隆支持仅适用于 动态供应器。
- CSI 驱动可能实现,也可能未实现卷克隆功能。
- 仅当 PVC 与目标 PVC 存在于同一命名空间(源和目标 PVC 必须在相同的命名空间)时,才可以克隆 PVC。
- 仅在同一存储类中支持克隆。
- 目标卷必须和源卷具有相同的存储类
- 可以使用默认的存储类并且 storageClassName 字段在规格中忽略了
用例如下:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-restore
namespace: demo-namespace
spec:
storageClassName: org.gluster.glusterfs
dataSource:
name: test-snapshot
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
参考文档: