Velero备份了哪些资源
内容索引
引言
经常用velero的用户可能会有这样的疑问,velero到底备份了哪些资源呢?本篇就对这个问题进行一个简单的实验与探讨。
实验环境
Kubernetes版本:v1.19.5
velero版本:
Client:
Version: v1.5.3
Git commit: 123109a3bcac11dbb6783d2758207bac0d0817cb
Server:
Version: v1.5.3
minio版本:minio/minio:RELEASE.2021-02-14T04-01-33Z
Rook-ceph版本:rook/ceph:v1.4.9
External-snapshotter: release-2.0
Snapshot CRD: v1beta1
待备份的应用是MySQL + Wordpress组合,PVC使用Ceph的RBD。
本篇实验仅以namesapce备份作为案例,用来展示并分析velero备份的资源,给读者一个参考。
实验一:用restic方式备份
创建备份
[root]# velero backup create wp-backup1 --include-namespaces=wordpress --default-volumes-to-restic --volume-snapshot-locations default
这里备份命令只设置了namespace,并没有对资源进行任何选择。另外,--default-volumes-to-restic
是velero v1.5新引入的参数,可以显示的设置velero的备份方式为restic。
查看备份详细信息
velero backup describe wp-backup1
这个命令可以看到资源的选择设置:
Namespaces:
Included: wordpress
Excluded: <none>
Resources:
Included: *
Excluded: <none>
Cluster-scoped: auto
也可以看到备份的资源数量:
Total items to be backed up: 21
Items backed up: 21
加上--details
,可以看到更详细的信息:
velero backup describe wp-backup1 --details
Resource List:
apps/v1/Deployment:
- wordpress/wordpress
- wordpress/wordpress-mysql
apps/v1/ReplicaSet:
- wordpress/wordpress-85bc4595b5
- wordpress/wordpress-mysql-79884bb86c
discovery.k8s.io/v1beta1/EndpointSlice:
- wordpress/wordpress-kcj7g
- wordpress/wordpress-mysql-28hnk
extensions/v1beta1/Ingress:
- wordpress/wordpress-ingress
networking.k8s.io/v1/Ingress:
- wordpress/wordpress-ingress
v1/Endpoints:
- wordpress/wordpress
- wordpress/wordpress-mysql
v1/Namespace:
- wordpress
v1/PersistentVolume:
- pvc-a1b4ee95-f61c-4d52-9b0f-0a5f29c8a559
- pvc-b18f571b-17a3-4a32-9714-b32e490ed4f2
v1/PersistentVolumeClaim:
- wordpress/mysql-pv-claim
- wordpress/wp-pv-claim
v1/Pod:
- wordpress/wordpress-85bc4595b5-snntp
- wordpress/wordpress-mysql-79884bb86c-w8mjh
v1/Secret:
- wordpress/default-token-x7xvw
v1/Service:
- wordpress/wordpress
- wordpress/wordpress-mysql
v1/ServiceAccount:
- wordpress/default
Velero-Native Snapshots: <none included>
Restic Backups:
Completed:
wordpress/wordpress-85bc4595b5-snntp: wordpress-persistent-storage
wordpress/wordpress-mysql-79884bb86c-w8mjh: mysql-persistent-storage
可以看到,这次velero一共备份了21个资源,并且describe
命令可以列出所有的资源,包括版本,API类型与资源名。到这里,我们已经看到了velero在restic文件备份的情况下,对单一namespace备份时备份的所有资源。但是,读者可能还有疑问,velero是怎么选择出来的这些资源的?要进一步的答案,我们可以把velero的log收下来进一步分析。
收集velero的log
kubectl logs -n <velero-namespace> velero-xxx > velero.log
这个log可能会有点长,读者可以节选一下刚刚备份的log。例如,可以用vi打开这个log,找到备份时间点的Setting up backup log
行,这是单次备份开始时的第一条log。再往下找到Backup completed
,这是单次备份结束的log,然后把中间的log保存到另一个文件,比如include-none-exclude-none-ns-wordpress.log
。在后面章节中,我们可以通过velero的代码和收集的log来分析一下velero的资源收集过程。
实验二:用快照方式备份
创建快照备份
[root]# velero backup create wp-backup-snapshot1 --include-namespaces=wordpress --snapshot-volumes --volume-snapshot-locations default
--snapshot-volumes
也是v1.5引入的参数,表示备份过程中用CSI来生成快照并备份下来。
查看备份信息
先用velero backup describe wp-backup-snapshot1
进行查看,发现备份未完成时,先显示预估的待资源数量是24,以及当前备份了几个资源:
Estimated total items to be backed up: 24
Items backed up so far: 6
备份完之后,用velero backup describe wp-backup-snapshot1 --details
进行查看:
Total items to be backed up: 26
Items backed up: 26
Resource List:
apps/v1/Deployment:
- wordpress/wordpress
- wordpress/wordpress-mysql
apps/v1/ReplicaSet:
- wordpress/wordpress-85bc4595b5
- wordpress/wordpress-mysql-79884bb86c
discovery.k8s.io/v1beta1/EndpointSlice:
- wordpress/wordpress-kcj7g
- wordpress/wordpress-mysql-28hnk
extensions/v1beta1/Ingress:
- wordpress/wordpress-ingress
networking.k8s.io/v1/Ingress:
- wordpress/wordpress-ingress
snapshot.storage.k8s.io/v1beta1/VolumeSnapshot:
- wordpress/velero-mysql-pv-claim-7vpfs
- wordpress/velero-wp-pv-claim-fv6hf
snapshot.storage.k8s.io/v1beta1/VolumeSnapshotClass:
- csi-rbdplugin-snapclass
snapshot.storage.k8s.io/v1beta1/VolumeSnapshotContent:
- snapcontent-92604f14-79b1-4a2e-8a8e-0ac40a28cb3f
- snapcontent-ff9dd95a-297b-47c2-9430-6de87f11af70
v1/Endpoints:
- wordpress/wordpress
- wordpress/wordpress-mysql
v1/Namespace:
- wordpress
v1/PersistentVolume:
- pvc-a1b4ee95-f61c-4d52-9b0f-0a5f29c8a559
- pvc-b18f571b-17a3-4a32-9714-b32e490ed4f2
v1/PersistentVolumeClaim:
- wordpress/mysql-pv-claim
- wordpress/wp-pv-claim
v1/Pod:
- wordpress/wordpress-85bc4595b5-snntp
- wordpress/wordpress-mysql-79884bb86c-w8mjh
v1/Secret:
- wordpress/default-token-x7xvw
v1/Service:
- wordpress/wordpress
- wordpress/wordpress-mysql
v1/ServiceAccount:
- wordpress/default
可以看到,所有备份的资源数量变成的26,下面列出了所有的资源。
收集log
同样,这里参考前面章节把velero的log收好备用:include-none-exclude-none-ns-wordpress-snapshot.log
velero如何选择资源
代码分析
velero选择资源的逻辑大概如下:
用client-go
的discovery
API去刷新提取集群的所有推荐的group version
如果打开了APIGroupVersionsFeatureFlag
的功能开关,会去拿全部的而不是推荐的group version
,具体可以查阅后面参考的"Enable API group versions"。具体代码可以参考pkg/discovery/helper.go
。
那这里的group version
是指什么呢?可以用kubectl api-versions
命令得到一个集群所有的group version
:
admissionregistration.k8s.io/v1
admissionregistration.k8s.io/v1beta1
apiextensions.k8s.io/v1
apiextensions.k8s.io/v1beta1
apiregistration.k8s.io/v1
apiregistration.k8s.io/v1beta1
apps/v1
authentication.k8s.io/v1
authentication.k8s.io/v1beta1
authorization.k8s.io/v1
authorization.k8s.io/v1beta1
autoscaling/v1
autoscaling/v2beta1
autoscaling/v2beta2
batch/v1
batch/v1beta1
ceph.rook.io/v1
certificates.k8s.io/v1
certificates.k8s.io/v1beta1
coordination.k8s.io/v1
coordination.k8s.io/v1beta1
crd.projectcalico.org/v1
discovery.k8s.io/v1beta1
events.k8s.io/v1
events.k8s.io/v1beta1
extensions/v1beta1
migration.yinhestor.com/v1alpha1
networking.k8s.io/v1
networking.k8s.io/v1beta1
node.k8s.io/v1beta1
objectbucket.io/v1alpha1
policy/v1beta1
rbac.authorization.k8s.io/v1
rbac.authorization.k8s.io/v1beta1
rook.io/v1alpha2
scheduling.k8s.io/v1
scheduling.k8s.io/v1beta1
snapshot.storage.k8s.io/v1beta1
storage.k8s.io/v1
storage.k8s.io/v1beta1
v1
velero.io/v1
备份开始时,先去拿每一个group version
下面的资源类型
比如,v1
是集群的核心group
,下面有pod
,namespace
等资源类型。
针对每一个资源类型,去拿下面的所有资源
比如,针对namespace
,拿到这个集群所有的namespace。
针对备份设置的include/exclude
以及include-namespaces
等选项,来筛选每一种资源是否是待备份资源。
例如,这里我们要备份的就是wordpress
这个namespace,那么对于比如rook-ceph
下面的所有资源,都不会被选择出来。
对于上面的2 - 4,具体代码逻辑可以参考pkg/backup/item_collector.go
里面的getAllItems
实现。
结合log分析
分析完velero拿资源的逻辑,再来看之前收集的log。velero的log里,有一些在备份过程中常见的字段,这里列出来跟收集资源相关的:
Getting items for group
从一个group version
中选择有哪些项目,这里展示一下实际的log里的group
:
[root@dev-bo debug]# grep "Getting items for group" include-none-exclude-none-ns-wordpress.log | awk '{print $(NF-1)}'
group=v1
group=apiregistration.k8s.io/v1
group=apps/v1
group=events.k8s.io/v1
group=autoscaling/v1
group=batch/v1
group=batch/v1beta1
group=certificates.k8s.io/v1
group=networking.k8s.io/v1
group=policy/v1beta1
group=rbac.authorization.k8s.io/v1
group=storage.k8s.io/v1
group=admissionregistration.k8s.io/v1
group=apiextensions.k8s.io/v1
group=scheduling.k8s.io/v1
group=coordination.k8s.io/v1
group=node.k8s.io/v1beta1
group=discovery.k8s.io/v1beta1
group=ceph.rook.io/v1
group=crd.projectcalico.org/v1
group=velero.io/v1
group=migration.yinhestor.com/v1alpha1
group=objectbucket.io/v1alpha1
group=rook.io/v1alpha2
group=snapshot.storage.k8s.io/v1beta1
group=extensions/v1beta1
Getting items for resource
从一个资源类中选择有哪些项目
Listing items
从一组资源中根据label来选择项目
Skipping resource because it's cluster-scoped and only specific namespaces are included in the backup
略过一个集群范围的资源
Retrieved x items
表示velero根据用户的选择,抓取到了一个待备份的资源
Backing up item
正在备份一个资源
看过这几个log的关键字,读者应该可以跟前面代码分析的1 - 4对起来,下面我们看看从log grep出来的相应信息。
首先是restic方式备份,查看velero选择的待备份的资源:
[root]# grep Retrieved include-none-exclude-none.log | grep -v "0 item" | awk '{print $NF}'
resource=pods
resource=persistentvolumeclaims
resource=secrets
resource=endpoints
resource=serviceaccounts
resource=services
resource=replicasets
resource=deployments
resource=ingresses
resource=endpointslices
resource=ingresses
可以看到velero的备份是遵循某个顺序的,对核心的API group
,例如前面的v1
,按照的顺序是pod
、pvc
、pv
,然后才是所有其它的资源。
接下来,"Collected 19 items matching the backup spec from the Kubernetes API"
这条log,跟velero backup describe
展示的Estimated total items to be backed up
是一致的,表示通过上一节的1 - 4之后得到的一个资源数,最后实际的数量,取决于每个资源在备份时候的额外的action
。例如,备份PVC的时候,每个PVC其实会对应一个cluster-scoped
的资源,也就是PV,这样最后就会增加相应PVC数量的PV数量进来。
[root]# grep cluster-scoped include-none-exclude-none-ns-wordpress.log | awk '{print $NF}'
resource=persistentvolumes
resource=nodes
resource=apiservices
resource=certificatesigningrequests
resource=ingressclasses
resource=podsecuritypolicies
resource=clusterroles
resource=clusterrolebindings
resource=storageclasses
resource=csidrivers
resource=csinodes
resource=volumeattachments
resource=mutatingwebhookconfigurations
resource=validatingwebhookconfigurations
resource=customresourcedefinitions
resource=priorityclasses
resource=runtimeclasses
resource=ippools
resource=felixconfigurations
resource=globalnetworksets
resource=bgpconfigurations
resource=bgppeers
resource=blockaffinities
resource=ipamhandles
resource=clusterinformations
resource=ipamblocks
resource=hostendpoints
resource=ipamconfigs
resource=globalnetworkpolicies
resource=objectbuckets
resource=volumesnapshotcontents
resource=volumesnapshotclasses
上面信息展示了所有被过滤掉的资源。
[root]# grep "Backed up a total of" include-none-exclude-none-ns-wordpress.log
time="2021-05-21T10:01:07Z" level=info msg="Backed up a total of 21 items" backup=qiming-migration/wp-backup-repeat1-1621591204-mmbsx logSource="pkg/backup/backup.go:419" progress=
这条log就跟velero backup describe
在备份完成后展示的Total items to be backed up
是一致的。
[root]# grep "Backing up item" include-none-exclude-none-ns-wordpress.log | awk '{print $NF}'
resource=pods
resource=persistentvolumeclaims
resource=persistentvolumes
resource=pods
resource=persistentvolumeclaims
resource=persistentvolumes
resource=secrets
resource=namespaces
resource=endpoints
resource=endpoints
resource=serviceaccounts
resource=services
resource=services
resource=replicasets.apps
resource=replicasets.apps
resource=deployments.apps
resource=deployments.apps
resource=ingresses.networking.k8s.io
resource=endpointslices.discovery.k8s.io
resource=endpointslices.discovery.k8s.io
resource=ingresses.extensions
上面这些"Backing up item"
就展示了每一个被velero备份的资源,跟前面--details
得到的资源列表是一样的,不同的是,这里显示的是按顺序备份的资源。
对快照备份的log分析,大部分跟上面差不多,这里就展示一下最终备份的资源:
[root@dev-bo debug]# grep "Backing up item" include-none-exclude-none-ns-wordpress-snapshot.log | awk '{print $NF}'
resource=pods
resource=persistentvolumeclaims
resource=persistentvolumes
resource=volumesnapshots.snapshot.storage.k8s.io
resource=volumesnapshotclasses.snapshot.storage.k8s.io
resource=volumesnapshotcontents.snapshot.storage.k8s.io
resource=pods
resource=persistentvolumeclaims
resource=persistentvolumes
resource=volumesnapshots.snapshot.storage.k8s.io
resource=volumesnapshotcontents.snapshot.storage.k8s.io
resource=secrets
resource=namespaces
resource=endpoints
resource=endpoints
resource=serviceaccounts
resource=services
resource=services
resource=replicasets.apps
resource=replicasets.apps
resource=deployments.apps
resource=deployments.apps
resource=ingresses.networking.k8s.io
resource=endpointslices.discovery.k8s.io
resource=endpointslices.discovery.k8s.io
resource=ingresses.extensions
可以看到快照备份对每个PVC会额外备份对应的volumesnapshot和volumesnapshotcontent。例子里有2个PV,volumesnapshots, volumesnapshotcontents对于每个PV都会备份,再加上volumesnapshotclass,所以多5个。
小结
本文通过单namespace备份的方式观察了velero备份的资源,并结合velero资源收集的代码逻辑来分析备份的log,对velero备份哪些资源,如何选择这些资源,以及备份的顺序都有了一个基本的理解。感兴趣的读者可以对不同的资源选项(如:多个namespace,或者cluster-scope的资源)进行尝试,用同样的方式可以观察分析不同参数下备份的资源。
参考
Enable API group versions
velero 1.5 backup reference
velero 1.5 repo