velero 简介
Velero 是一个云原生的灾难恢复和迁移工具,采用 Go 语言编写,可以安全的备份、恢复和迁移Kubernetes集群资源和持久卷。Velero 是西班牙语,意思是帆船,非常符合 Kubernetes 社区的命名风格。
Velero 目前包含以下特性:
- 支持
Kubernetes
集群数据备份和恢复
- 支持复制当前
Kubernetes
集群的资源到其它Kubernetes
集群
- 支持复制生产环境到开发以及测试环境
Velero 组件一共分两部分,分别是服务端和客户端。
- 服务端:运行在
Kubernetes
集群中
- 客户端:运行在本地的 velero 命令行工具,需要在机器上已配置好
kubectl
及集群kubeconfig
velero 使用场景
灾备场景
:提供备份恢复 k8s 集群的能力
迁移场景
:提供拷贝集群资源到其他集群的能力(复制同步开发,测试,生产环境的集群配置,简化环境配置)
velero 与 etcd 备份区别
- 直接备份
Etcd
是将集群的全部资源备份起来,而 Velero
可以对 Kubernetes
集群内对象级别进行备份。
- 除了对
Kubernetes
集群进行整体备份外,Velero
还可以通过对 Type
、Namespace
、Label
等对象进行分类备份或者恢复。
官方网站:https://velero.io
项目地址:https://github.com/vmware-tanzu/velero
velero 原理
每个 Velero 操作包括按需备份、计划备份、恢复,都是一个自定义资源,使用 Kubernetes 自定义资源定义 (CRD) 定义并存储在 etcd 中。Velero 还包括处理自定义资源以执行备份、恢复和所有相关操作的控制器。
Velero 在 Kubernetes 集群中创建了很多 CRD 以及相关的控制器,进行备份恢复等操作实质上是对相关 CRD 的操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# kubectl -n velero get crds -l component=velero
NAME CREATED AT
backups.velero.io 2021-08-06T08:29:34Z
backupstoragelocations.velero.io 2021-08-06T08:29:34Z
deletebackuprequests.velero.io 2021-08-06T08:29:34Z
downloadrequests.velero.io 2021-08-06T08:29:34Z
podvolumebackups.velero.io 2021-08-06T08:29:34Z
podvolumerestores.velero.io 2021-08-06T08:29:34Z
resticrepositories.velero.io 2021-08-06T08:29:34Z
restores.velero.io 2021-08-06T08:29:34Z
schedules.velero.io 2021-08-06T08:29:34Z
serverstatusrequests.velero.io 2021-08-06T08:29:35Z
volumesnapshotlocations.velero.io 2021-08-06T08:29:35Z
|
您可以备份或恢复集群中的所有对象,也可以按类型、命名空间和/或标签过滤对象。Velero 非常适合灾难恢复用例,以及在集群上执行系统操作(如升级)之前对应用程序状态进行快照。
Velero 工作原理图如下图所示,当用户执行备份命令时,备份过程说明如下:
- 调用自定义资源 API 创建备份对象(1)。
- BackupController 控制器检测到生成的备份对象时(2)执行备份操作(3)。
- 将备份的集群资源和存储卷快照上传到 Velero 的后端存储(4)和(5)。
Velero 将对象存储视为事实的来源,当执行还原操作时,Velero 会将指定备份对象的数据从后端存储同步到 Kubernetes 集群完成还原工作。同样,如果一个备份对象存在于 Kubernetes 但不在对象存储中,它将从 Kubernetes 中删除,因为备份 tarball 不再存在。
velero 安装
velero 安装分为两部分,velero CLI 命令行安装及服务端安装,前提条件:
- 准备一个生产 k8s 集群 cluster1,及一个灾备 k8s 集群 cluster2,当然也可以在同一个集群备份恢复
- 在灾备环境部署 minio 对象存储,当然也可以使用公有云对象存储
minio 对象存储安装
velero 依赖对象存储保存备份数据,这里部署 minio 替代公有云对象存储。灾备环境准备一个节点部署 minio 对象存储,两个集群 velero 服务端将指向同一个对象存储的同一个 bucket,cluster1 向桶内备份数据,cluster2 向桶内读取备份数据进行恢复,借鉴下图进行理解:
可以在 k8s 集群内直接使用 yaml 或官方 minio operator 部署,这里在集群外使用 docker 安装 minio 对象存储:
1
2
3
4
5
6
7
8
|
docker run -d --name minio \
--restart always \
-p 9000:9000 \
-p 9001:9001 \
-e "MINIO_ROOT_USER=minio" \
-e "MINIO_ROOT_PASSWORD=minio123" \
-v minio-data:/data \
minio/minio server /data --console-address ":9001"
|
访问对象存储控制台http://prod.minio.cloudcele.com:9001
,创建名为 velero 的 bucket 桶,名称自定义:
安装 velero CLI 客户端
参考:https://velero.io/docs/v1.6/basic-install/
分别在 cluster1 和 cluster2 准备一个节点,安装 veleroCLI,本地有 kubeconfig 文件,能够访问到两个 k8s 集群即可:
下载客户端
1
|
wget https://github.com/vmware-tanzu/velero/releases/download/v1.6.2/velero-v1.6.2-linux-amd64.tar.gz
|
解压安装
1
2
|
tar -zxvf velero-v1.6.2-linux-amd64.tar.gz
cp velero-v1.6.2-linux-amd64/velero /usr/local/bin/
|
查看 velero CLI 版本
安装 velero 服务端
参考:https://velero.io/docs/v1.6/contributions/minio/
分别在 cluster1 和 cluster2 集群中部署 velero 服务端,本地创建 minio 对象存储访问凭证:
1
2
3
4
5
|
cat >credentials-velero <<EOF
[default]
aws_access_key_id = minio
aws_secret_access_key = minio123
EOF
|
使用 velero CLI 在生产和灾备集群安装 velero,指向同一个对象存储:
1
2
3
4
5
6
7
8
9
10
|
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.2.0 \
--namespace velero \
--bucket velerobak \
--default-volumes-to-restic \
--use-restic \
--secret-file ./credentials-velero \
--use-volume-snapshots=false \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://192.168.0.21:9000
|
该--use-restic
参数指定使用官方默认支持的 restic 将持久化卷备份到对象存储,而公有云厂商提供的 k8s 有对应的 CSI 实现和 velero 插件支持。
查看集群中创建的 pods
1
2
3
4
5
6
7
|
[root@master ~]# kubectl -n velero get pods
NAME READY STATUS RESTARTS AGE
restic-22m9g 1/1 Running 2 16m
restic-4rb8r 1/1 Running 2 16m
restic-k8b75 1/1 Running 1 16m
restic-p88xh 1/1 Running 0 16m
velero-79dc999699-rjf9p 1/1 Running 1 16m
|
或者使用 helm 部署 velero(不推荐):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts
helm install velero vmware-tanzu/velero \
--namespace velero \
--create-namespace \
--set cleanUpCRDs=true \
--set configuration.provider=aws \
--set-file credentials.secretContents.cloud=./credentials \
--set deployRestic=true \
--set snapshotsEnabled=false \
--set configuration.backupStorageLocation.name=minio \
--set configuration.backupStorageLocation.bucket=velero \
--set configuration.backupStorageLocation.config.region=minio \
--set configuration.backupStorageLocation.config.s3ForcePathStyle=true \
--set configuration.backupStorageLocation.config.s3Url=http://192.168.0.21:9000 \
--set "initContainers[0].name"=velero-plugin-for-aws \
--set "initContainers[0].image"=velero/velero-plugin-for-aws:v1.2.0 \
--set "initContainers[0].volumeMounts[0].mountPath"=/target \
--set "initContainers[0].volumeMounts[0].name"=plugins \
vmware-tanzu/velero
|
卸载 velero
1
2
|
kubectl delete namespace/velero clusterrolebinding/velero
kubectl delete crds -l component=velero
|
velero 备份
在 cluster1 备份应用及 pv 卷,首先创建 veleroCLI 中自带的示例应用:
1
2
3
|
cd velero-v1.6.2-linux-amd64/examples/nginx-app
kubectl apply -f with-pv.yaml
|
查看创建的应用及持久卷,注意这里使用 storageclass 动态申请持久卷,在恢复的目标集群,建议提供相同名称的 storageclass:
1
2
3
4
5
6
7
|
[root@product-cluster nginx-app]# kubectl -n nginx-example get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-5ccc99bffb-swvr2 2/2 Running 0 6m59s
[root@product-cluster nginx-app]# kubectl -n nginx-example get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-fd5eee69-ca7f-4e94-a749-7d4e04dc4a7c 50Mi RWO Delete Bound nginx-example/nginx-logs longhorn 6m54s
|
执行备份,备份 nginx-example 这个命名空间下的所有资源:
1
|
velero backup create mybackup-01 --include-namespaces=nginx-example
|
查看备份百分比进度
1
|
velero backup describe mybackup-01
|
查看备份的所有资源列表
1
|
velero backup describe mybackup-01 --details
|
备份完成后可以查看备份日志
1
|
velero backup logs mybackup-01
|
查看备份任务最终执行状态
查看对象存储中保存的备份数据
velero 恢复
由于指向同一个对象存储,cluster2 中的 velero 同样能看到 cluster1 中备份:
1
2
3
|
[root@disaster-cluster ~]# velero backup get
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
mybackup-01 Completed 0 1 2021-09-18 17:48:24 +0800 CST 29d default <none>
|
在集群 cluster2 恢复应用及 pv 卷:
1
|
[root@disaster-cluster ~]# velero restore create --from-backup=mybackup-01
|
查看恢复的应用及数据
1
2
3
4
5
6
7
|
[root@disaster-cluster ~]# kubectl -n nginx-example get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-5ccc99bffb-swvr2 2/2 Running 0 7m10s
[root@disaster-cluster ~]# kubectl -n nginx-example get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-c9713a25-a3f6-4179-89df-fd6e27ea5055 5Gi RWO Delete Bound ns-panda/mysql-pv-claim longhorn 31h
|
velero 常用命令
备份单个 namespace 下的所有资源:
1
|
velero backup create mybackup-01 --include-namespaces=mynamespace
|
备份多个 namespace 下的所有资源:
1
|
velero backup create mybackup --include-namespaces=mynamespaceA,mynamespaceB
|
创建一小时后自动删除的备份
1
|
velero backup create mybackup --include-namespaces=mynamespace --ttl=1h
|
获取备份列表
获取 mybackup 这个备份的详情信息
1
|
velero backup describe mybackup
|
删除 mybackup 这个备份
1
|
velero backup delete mybackup
|
从某一个备份上恢复,如果备份有多个命名空间也可以只恢复其中一个
1
|
velero restore create --from-backup=mybackup-01 --include-namespaces=mynamespace
|
每天 1 点创建一个 72 小时删除的 mynamespace 备份
1
|
velero schedule create myschedule --schedule="0 1 * * *" --ttl 72h --include-namespaces=mynamespace
|
查看备份位置配置
1
|
kubectl -n velero get BackupStorageLocation -o yaml
|
参考:https://cloud.tencent.com/developer/article/1765348