kubernetes 集群迁移,备份还原神器 velero .
动机
因某种原因,需要对业务 k8s 集群进行迁移,迁移过程中,需要对以下场景进行测试:
环境
-
Velero 版本:1.11.1
-
backup 集群:
3 master 3 worker 节点,vke 1.24 版本(csi类型:PTESSD)
-
restore 集群:
3 master 3 worker 节点,vke 1.24 版本(csi类型:ESSD)
-
backup 集群做备份,到 restore 集群进行还原。
-
因为我们的场景是私有云,不可以使用云盘快照等功能,因此需要借助 restic 对文件系统进行备份还原,以下都是基于 restic 功能的介绍。
前置准备
两个集群都要准备 ak/sk ,并写入 credentials-velero 文件。
1
2
3
4
5
|
cat credentials-velero
[default]
aws_access_key_id=AKLTNDk5NWMwNjBjOTUxNGQ4ZDg2YzIwMGZlNz...
aws_secret_access_key=WkRjNU5UWTNZamcwWW1WbE5EQTFOemcyTUdRell6WXpNV0...
|
安装 velero 到 backup/restore 集群,用下面同一份安装命令即可。
1
2
3
4
5
6
7
8
9
10
|
velero install \
--use-node-agent \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.8.2 \
--bucket hwh-velero-repo \
--secret-file ./credentials-velero \
--uploader-type restic \
--default-volumes-to-fs-backup \
--backup-location-config region=cn-guangzhou-swd,s3ForcePathStyle="false",s3Url=https://tos-s3.miracle.ac.cn \
--use-volume-snapshots=false
|
检查是否安装完成。
1
2
3
4
|
kubectl logs deployment/velero -n velero
Defaulted container "velero" out of: velero, velero-velero-plugin-for-aws (init)
Error from server (BadRequest): container "velero" in pod "velero-5bf88458ff-95knw" is waiting to start: PodInitializing
|
检查 pod 状态
1
2
3
4
5
6
|
kubectl get pod -n velero
NAME READY STATUS RESTARTS AGE
node-agent-4bjz7 1/1 Running 0 3m55s
node-agent-fk22l 1/1 Running 0 3m55s
node-agent-jgrkk 1/1 Running 0 3m55s
velero-5bf88458ff-95knw 1/1 Running 0 3m55s
|
测试数据
在 backup vke 集群里面启动一个 busybox 的 pod ,并挂载 ssd 云盘,里面有一个 data.csv 文件。
md5 校验和:
48ed7a0e989dae4e3d795cfd9e5aff39 data.csv。
d8784feca171cd5c9bfb759289f02459 testdata.rar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
kubectl exec -it hwh-busybox-699d99c959-jngf4 -n hwh -- sh
/ # cd /opt/data/
/opt/data # ls
data.csv lost+found
/opt/data # md5sum data.csv
48ed7a0e989dae4e3d795cfd9e5aff39 data.csv
kubectl exec -it hwh-busybox-tos-9f68fbc78-qr6vv -n hwh -- sh
/ # cd /opt/data/
/opt/data # ls
data.txt testdata.rar
/opt/data # md5sum testdata.rar
d8784feca171cd5c9bfb759289f02459 testdata.rar
|
过程
备份过程业务服务是否需要暂停,需要跟业务侧确定,需要暂停则需要将服务的 pod 数量设置为 0 .
正常的备份还原
backup集群执行备份:
1
2
3
4
5
|
velero backup create demo-1
Backup request "demo-1" submitted successfully.
Run `velero backup describe demo-1` or `velero backup logs demo-1` for more details.
|
检查备份过程:
1
2
3
|
velero backup describe demo-1
# 备份完成后,Phase 字段的值是 Completed
|
如果备份过程出现异常,查看日志:
1
|
velero backup logs demo-1
|
restore集群执行还原:
1
|
velero restore create --from-backup demo-1
|
查看备份过程:
1
2
3
4
5
6
|
# 查看何时完成
# 还原完成后,Phase 字段的值是 Completed
velero restore describe demo-1-20240108165612
# 查看还原的卷的信息
kubectl -n velero get podvolumerestores -l velero.io/restore-name=demo-1-20240108165612 -o yaml
|
storageClass 变更
有时候,我们可能会在还原的集群上确实某个 backup 集群没有的 storageClass ,我们可以通过配置 configmap 来做一层映射,将数据在 restore 集群上的另一个 storageClass 上创建 pvc 来存储。
比如:
1
2
3
4
5
6
7
8
9
10
|
apiVersion: v1
kind: ConfigMap
metadata:
name: change-storage-class-config
namespace: velero
labels:
velero.io/plugin-config: ""
velero.io/change-storage-class: RestoreItemAction
data:
ebs-ssd: ebs-essd
|
然后对里面的文件做 MD5 校验,值不变则说明数据完整。
持久化卷过滤
还有另外一情况,我们使用的 pv/pvc 使用的是 oss 或者 nas ,里面的文件比较大比较多,我们不希望他备份到 oss 再同步回来,而是希望备份的过程中,不拷贝这些文件,然后在还原的时候,重新挂载到对应的远程存储的相同目录,来实现快速迁移。注意:这种情况只适用于 restic 类型的备份模式。我们在安装的时候已经指明 --uploader-type restic
和 --default-volumes-to-fs-backup
了。
我们可以先通过给 pod 打 annotate 声明哪个卷不需要备份。
1
|
kubectl -n hwh annotate pod/hwh-busybox-tos-9f68fbc78-qr6vv backup.velero.io/backup-volumes-excludes=data
|
然后再进行备份,还原即可。
测试结果
迁移后对文件进行校验。
1
2
3
4
5
6
7
8
9
10
11
|
kubectl exec -it -n hwh hwh-busybox-699d99c959-jngf4 -- sh
Defaulted container "busybox" out of: busybox, restore-wait (init)
/ #
/ # cd /opt/data/
/opt/data # ls
data.csv lost+found
/opt/data # md5sum data.csv
48ed7a0e989dae4e3d795cfd9e5aff39 data.csv
/opt/data # cat data.csv |wc -l
16
|
数据完整。
我们在 pod 里面存入一个 400+M 的文件,并确定一下 MD5 的值。
backup集群:
1
2
3
4
5
6
7
|
kubectl exec -it hwh-busybox-tos-9f68fbc78-qr6vv -n hwh -- sh
/ # cd /opt/data/
/opt/data # ls
data.txt testdata.rar
/opt/data # md5sum testdata.rar
d8784feca171cd5c9bfb759289f02459 testdata.rar
|
restore集群:
1
2
3
4
5
6
7
8
9
10
|
kubectl exec -it -n hwh hwh-busybox-tos-9f68fbc78-qr6vv -- sh
/ # cd /opt/data/
/opt/data # ls
data.txt testdata.rar
/opt/data # md5sum testdata.rar
d8784feca171cd5c9bfb759289f02459 testdata.rar
/opt/data # du -sh *
512 data.txt
458.3M testdata.rar
|
数据完整。
冻结/解冻文件系统
如果文件系统频繁写入数据,需要临时不给写入,可以用 fsfreeze 命令来临时将文件系统设置为只读,等备份完以后解冻。
1
2
3
4
5
|
kubectl annotate pod -n plosp -l app=solr-knowlege-plosp \
pre.hook.backup.velero.io/command='["/sbin/fsfreeze", "--freeze", "/opt/solr/server/solr/mycores"]' \
pre.hook.backup.velero.io/container=c0 \
post.hook.backup.velero.io/command='["/sbin/fsfreeze", "--unfreeze", "/opt/solr/server/solr/mycores"]' \
post.hook.backup.velero.io/container=c0
|
container 字段:要冻结文件系统的 pod 里面的容器名。
其他实用功能:
-
pvc annotation 在 restore 逻辑的时候,进行清空。目的:由于之前使用的 glusterfs,pvc annotation 做有相关的关联,因此 pvc 的 annotation 在备份的时候需要被清空,然后由 sc 再次提供。
-
对 pvc 中的 resources.requests 判断,由于 iaas 侧的 PTSSD 创建云硬盘最低 20G 起步,因此之前旧的 PVC 低于 20G 的时候,自动设置为 20Gi。
-
基于 image 的映射,通过在 configmap 中指定,key 为 oldRepo,value 为 newRepo。configmap 的命名规则为 “change-” + namespace + “-image-registry”。
总结
-
总体相当简单易用,不过需要注意集群版本和 velero 对应的版本关系,不然可能出现备份或还原后,很容易出现操作已经完成了,但状态卡在 InProgress 中。
-
但是如果文件系统的文件数量比较庞大,或者总体体积比较大,备份就会经常失败,比如我们的场景下是 80GB 以上的文件系统经常备份失败,原因就是前面提到的 2 种情况。
-
所以为了解决文件系统比较庞大而导致的备份失败,我们选择了用 rsync 去做对拷。