概念
VSL:VolumeSnapshotLocation,卷快照地址
Velero定义了一个VolumeSnapshotter的接口,这个接口需要被第三方存储厂商实现,来提供卷快照的功能,支持云厂商VSL需要实现Velero定义的一个VolumeSnapshotter的接口
Velero源码Git:github.com/vmware-tanz…
源码中VolumeSnapshotter接口的内容(v1.8.0)
位置:velero/pkg/plugin/velero/volume_snapshotter.go
接口中包含有7个功能函数,如要支持VSL,就需要针对这个接口功能的实现,该接口的定义能明白VSL的含义是:velero在备份期间,执行持久卷的快照;在恢复期间,还原快照中的持久卷
插件框架的主要代码在velero/pkg/plugin/framework,核心是Server接口。插件的注册、获取、删除,以及run插件服务都在此,而今天我们讲的VSL插件,就是通过Server注册进Velero服务中,并启动Server提供插件服务
Server中通过NewServer()方法来初始化一个新的Server对象以供调用
云厂商VSL
AWS
代码解析
源码Git:github.com/vmware-tanz…
- 从源码中可以看出引入了Velero中插件的框架并起名veleroplugin,main函数启动时,创建了一个NewServer()
- NewServer返回了一个Server,而这个Server其实是一个接口类型的对象,AWS插件实例化出一个Server接口后,实现了其中4个接口:BindFlags、RegisterObjectStore、RegisterVolumeSnapshotter、Serve,而AWS实现的插件注册即图中圈出的接口
BindFlags: 定义插件服务器的命令行标志,此方法必须在调用.Serve()之前调用
RegisterObjectStore: 注册一个对象存储,接受的格式:插件名称<DNS子域>/<非空名称>
RegisterVolumeSnapshotter: 注册一个卷快照,接受的格式:插件名称<DNS子域>/<非空名称>
Serve: 运行插件服务器
- 通过简单了解4个函数后,大体能知道AWS实现VSL的插件方式流程,即:
- 加载velero插件
- 初始化一个插件Server
- 注册插件、实现规定接口
- run服务
- 对于该插件实现的接口功能有2个,这次主要关注newAwsVolumeSnapshotter
- newAwsVolumeSnapshotter函数返回了一个interface类型,继续深入可以看到最终结果,
log暂且不用太关注,主要来看ec2这个对象,EC2是AWS的弹性计算云模块,我们则通过EC2提供的API来调用该对象的方法
- EC2对象里初始化了一个客户端,该客户端实现基本客户端请求和响应处理
- 初始化完毕后,就可以用VolumeSnapshotter对象调用指定的方法,例如调用创建快照的方法,该方法需要传递3个参数:snapshotID,volumeAZ(该参数并未调用),和tags,该方法运行成功后,会返回快照的ID字符串,否则返回空字符串
而当前方法中的volumeID参数也可以通过GetVolumeID方法获取
- 创建好快照后,可以调用CreateVolumeFromSnapshot方法根据快照创建Volume
该方法需要传递snapshotID, volumeType, volumeAZ(该参数并未调用), iops共4个参数,其中snapshotID通过步骤8执行后获得,volumeType可通过GetVolumeInfo方法获得,对于iops参数(磁盘吞吐量指标), 如果使用预配置的 IOPS则指定,否则就不指定
功能测试
测试前的准备工作:可用的K8S集群环境、云厂商对象存储功能
- 设置Velero的凭证配置文件,此处用的阿里云的AK/SK,大家可以自行定义
vim credentials-velero
[default]
aws_access_key_id=<输入合法的AK>
aws_secret_access_key=<输入合法的SK>
- 安装velero(指定AWS插件、BUCKET、VSL配置信息、NameSpace等)
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.3.1,velero/velero-plugin-for-csi:v0.2.0 \
--bucket <bucket> \
--prefix <prefix> \
--secret-file ./credentials-velero \
--backup-location-config region=<region>,s3ForcePathStyle="false",s3Url=https://oss-<region>.aliyuncs.com \
--snapshot-location-config region=region> \
--namespace velero-yx \
--wait
成功安装完成后会有提示,这时候velero就安装到k8s中,命名空间是velero-yx,这里需要注意的是,BSL的状态应该为:Available
- 创建VolumeSnapshotClass对象,因为使用的是腾讯云集群,所以CSI驱动要选择腾讯版本
# 新建snapshotclass.yaml文件
vim snapshotclass.yaml
# 创建VolumeSnapshotClass对象
apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshotClass
metadata:
name: cbs-snapclass
labels:
velero.io/csi-volumesnapshot-class: "true"
driver: com.tencent.cloud.csi.cbs
deletionPolicy: Retain
# 应用到集群
kubectl apply -f snapshotclass.yaml
执行以下命令,查看对象是否创建成功,
- 创建 VolumeSnapshotLocation 对象以供 Velero 在拍摄卷快照时使用
velero snapshot-location create yx-vsl1 \
--provider aws \
-n velero-yx \
--config region=cn-beijing
查看VSL详细信息
[root@i-encdmzhz ~]# velero snapshot-location get yx-vsl1 -n velero-yx -o json
{
"kind": "VolumeSnapshotLocation",
"apiVersion": "velero.io/v1",
"metadata": {
"name": "yx-vsl1",
"namespace": "velero-yx",
"selfLink": "/apis/velero.io/v1/namespaces/velero-yx/volumesnapshotlocations/yx-vsl1",
"uid": "34484778-e449-4e47-a32d-0cd4cdd2b5d7",
"resourceVersion": "323710390",
"generation": 1,
"creationTimestamp": "2022-03-15T02:22:51Z",
"managedFields": [
{
"manager": "velero",
"operation": "Update",
"apiVersion": "velero.io/v1",
"time": "2022-03-15T02:22:51Z",
"fieldsType": "FieldsV1",
"fieldsV1": {"f:spec":{".":{},"f:config":{".":{},"f:region":{}},"f:provider":{}},"f:status":{}}
}
]
},
"spec": {
"provider": "aws",
"config": {
"region": "cn-beijing"
}
},
"status": {
}
}
- 备份apps命名空间资源并创建卷快照。这里注意,需要确定当前apps命名空间Pod绑定的PV资源删除回收策略是
Retain
,如果是Delete
则会导致快照失败创建velero备份任务,并指定备份
apps
命名空间
velero backup create yx-bk1 \
--include-namespaces=apps \
--snapshot-volumes=true \
--default-volumes-to-restic=false \
-n velero-yx \
--storage-location default \
--volume-snapshot-locations yx-vsl1
- 查看备份任务信息,这里
Phase
为Completed
表示备份完成(其余状态都代表失败,需要去日志查看详情)
[root@i-encdmzhz ~]# velero backup describe yx-bk1 -n velero-yx
Name: yx-bk1
Namespace: velero-yx
Labels: velero.io/storage-location=default
Annotations: velero.io/source-cluster-k8s-gitversion=v1.20.6-tke.12
velero.io/source-cluster-k8s-major-version=1
velero.io/source-cluster-k8s-minor-version=20+
Phase: Completed
Errors: 0
Warnings: 1
Namespaces:
Included: apps
Excluded: <none>
Resources:
Included: *
Excluded: <none>
Cluster-scoped: auto
Label selector: <none>
Storage Location: default
Velero-Native Snapshot PVs: true
TTL: 720h0m0s
Hooks: <none>
Backup Format Version: 1.1.0
Started: 2022-03-15 10:40:35 +0800 CST
Completed: 2022-03-15 10:40:42 +0800 CST
Expiration: 2022-04-14 10:40:35 +0800 CST
Total items to be backed up: 20
Items backed up: 20
Velero-Native Snapshots: <none included>
备份完成后,可以登录阿里云OSS桶中查看备份文件
可以查看快照及详细信息
[root@i-encdmzhz ~]# kubectl get volumesnapshot -n apps velero-mysql-stcxj -o json
{
"apiVersion": "snapshot.storage.k8s.io/v1beta1",
"kind": "VolumeSnapshot",
"metadata": {
"creationTimestamp": "2022-03-15T09:08:40Z",
"finalizers": [
"snapshot.storage.kubernetes.io/volumesnapshot-as-source-protection"
],
"generateName": "velero-mysql-",
"generation": 1,
"labels": {
"velero.io/backup-name": "yx-bk1"
},
"managedFields": [
{
"apiVersion": "snapshot.storage.k8s.io/v1beta1",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:metadata": {
"f:generateName": {},
"f:labels": {
".": {},
"f:velero.io/backup-name": {}
}
},
"f:spec": {
".": {},
"f:source": {
".": {},
"f:persistentVolumeClaimName": {}
},
"f:volumeSnapshotClassName": {}
}
},
"manager": "velero-plugin-for-csi",
"operation": "Update",
"time": "2022-03-15T09:08:40Z"
},
{
"apiVersion": "snapshot.storage.k8s.io/v1beta1",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:metadata": {
"f:finalizers": {
".": {},
"v:\"snapshot.storage.kubernetes.io/volumesnapshot-as-source-protection\"": {}
}
},
"f:status": {
".": {},
"f:boundVolumeSnapshotContentName": {},
"f:creationTime": {},
"f:readyToUse": {},
"f:restoreSize": {}
}
},
"manager": "snapshot-controller",
"operation": "Update",
"time": "2022-03-15T09:08:45Z"
}
],
"name": "velero-mysql-stcxj",
"namespace": "apps",
"resourceVersion": "327684042",
"selfLink": "/apis/snapshot.storage.k8s.io/v1beta1/namespaces/apps/volumesnapshots/velero-mysql-stcxj",
"uid": "f1b089ef-38c6-4723-b947-bc294b496254"
},
"spec": {
"source": {
"persistentVolumeClaimName": "mysql"
},
"volumeSnapshotClassName": "cbs-snapclass"
},
"status": {
"boundVolumeSnapshotContentName": "snapcontent-f1b089ef-38c6-4723-b947-bc294b496254",
"creationTime": "2022-03-15T09:08:43Z",
"readyToUse": true,
"restoreSize": "10Gi"
}
}
-
模拟灾难场景,我们将备份好的apps命名空间删除,可以看到namespace中已经没有apps了
-
从备份恢复时,将从快照创建一个克隆卷并绑定到恢复的 PVC
velero restore create yx-re1 \
--from-backup yx-bk1 \
-n velero-yx
通过查看任务详情,可以看到任务的状态是Completed
[root@i-encdmzhz ~]# velero restore describe yx-re1 -n velero-yx
Name: yx-re1
Namespace: velero-yx
Labels: <none>
Annotations: <none>
Phase: Completed
Started: 2022-03-15 11:02:34 +0800 CST
Completed: 2022-03-15 11:02:39 +0800 CST
Backup: yx-bk1
Namespaces:
Included: all namespaces found in the backup
Excluded: <none>
Resources:
Included: *
Excluded: nodes, events, events.events.k8s.io, backups.velero.io, restores.velero.io, resticrepositories.velero.io
Cluster-scoped: auto
Namespace mappings: <none>
Label selector: <none>
Restore PVs: auto
-
那我们再去查看命名空间列表,可以看到apps已经恢复了,并且POD的状态也是
Running
-
查看通过快照创建的PVC以及PV的信息
至此,通过VSL快照的方式恢复集群资源到这里就结束了
参考资料
tanzucommunityedition.io/docs/latest…
www.digitalocean.com/community/t…