集群备份及还原工具Velero
Velero是一个云原生的灾难恢复和迁移工具,它本身也是开源的, 采用 Go 语言编写,可以安全的备份、恢复和迁移Kubernetes集群资源和持久卷。
特点
备份可以按集群资源的子集,按命名空间、资源类型标签选择器进行过滤,从而为备份和恢复的内容提供高度的灵活性
支持复制当前 Kubernetes 集群的资源到其它 Kubernetes 集群,注意:只备份kubernetes中的元数据,不会备份PVC等数据内容
通过聚合 API 服务器公开的资源可以轻松备份和恢复,即使它们存储在单独的 etcd 数据库中
官网: https://velero.io/
Github 地址:https://github.com/vmware-tanzu/velero
官方文档:https://velero.io/docs/Velero 主要功能
备份功能
集群资源备份:能够备份 Kubernetes 集群中的各种资源对象,包括 Deployment、Service、ConfigMap、Secret、PersistentVolumeClaims 等几乎所有常见资源类型。例如,可以定期备份重要的应用部署配置以及相关的服务定义等,方便在需要时进行还原。
持久卷数据备份:除了资源对象本身,Velero 还支持对与应用相关联的持久卷(Persistent Volumes)中的数据进行备份。这对于保存有重要业务数据(如数据库文件、用户上传文件等)的应用来说至关重要,确保数据不会因意外删除、集群故障等情况丢失。
可基于文件系统备份(FileSystem Backup)备份Pod卷中的数据,并借助于restc或kopia上传到对象存储系统。
支持基于快照备份PV,这种方式较之FSB能确保文件的一致性;它支持两种操作: 1 仅创建PV快照,2 创建PV快照,并借助于restic或kopia上传到对象存储系统上。
恢复功能
资源还原:可以将之前备份的资源对象按照备份时的状态准确地还原到集群中,无论是因为误操作删除了某个关键服务,还是集群整体出现故障重建后,都能快速恢复应用部署和配置。
数据恢复:与资源还原配合,能把持久卷中的数据也恢复到相应的存储位置,使整个应用恢复到备份时刻的可用状态,保障业务的连续性。
灾难恢复与迁移支持
跨集群迁移:方便将应用及数据从一个 Kubernetes 集群迁移到另一个集群,比如从测试环境集群迁移到生产环境集群,或者在进行数据中心迁移、云平台更换等场景下,实现平滑的资源和数据转移。
灾难恢复预案:作为灾难恢复计划的关键部分,通过定期备份,在遇到如集群硬件故障、数据中心灾难等极端情况时,能快速依据备份在新的环境中恢复集群的关键业务应用,最大限度减少业务停机时间和损失
Velero CLI 二进制安装
root@k8s-master01:~#wget https://github.com/vmware-tanzu/velero/releases/download/v1.14.0/velero-v1.14.0-linux-amd64.tar.gz
root@k8s-master01:~#tar xf velero-v1.14.0-linux-amd64.tar.gz
root@k8s-master01:~#cd velero-v1.14.0-linux-amd64/
root@k8s-master01:~#mv velero /usr/local/bin/
root@k8s-master01:~#velero version
Client:
Version: v1.14.0
Git commit: 2fc6300f2239f250b40b0488c35feae59520f2d3
Server:
Version: v1.14.0启用命令补全
#方法1
root@k8s-master01:~#echo 'source <(velero completion bash)' >> ~/.bashrc
#方法2
root@k8s-master01:~#velero completion bash > /etc/bash_completion.d/velero可用子命令如下
backup :用于处理备份相关的操作,比如创建、查看、管理备份等。
backup-location :针对备份存储位置进行相关操作,像配置、查看备份存储的位置等工作。
bug :用来报告 velero 的相关问题(比如遇到的故障、不符合预期的行为等)。
client :涉及 velero 客户端相关的命令操作。
completion :可以生成命令补全脚本,方便在命令行中更便捷地输入命令。
create :创建各种 velero 资源,像备份计划、备份任务等资源都可以通过它来创建。
debug :生成用于调试的相关文件包,辅助排查 velero 使用过程中出现的问题。
delete :删除 velero 相关资源,例如不再需要的备份、备份计划等资源都能用此命令删除。
describe :查看并描述 velero 相关资源的详细信息,帮助了解资源的具体配置和状态等情况。
get :获取 velero 相关资源的基本信息,比如列出已有的备份、备份计划等。
help :可以查看关于任何 velero 命令的帮助内容,就是你现在看到的这种详细的使用说明。
install :在 Kubernetes 集群中安装 velero 工具。
plugin :用于处理插件相关的操作,比如安装、查看、管理插件等(插件可以扩展 velero 的功能)。
repo :针对仓库进行相关操作,不过文档里没详细说具体仓库相关的操作内容,可能要进一步看对应子命令的帮助。
restore :处理资源恢复相关的操作,能将之前备份的数据等资源恢复到集群中。
schedule :用于创建和管理备份计划,设定按一定时间周期自动执行备份任务等。
snapshot-location :对快照存储位置进行操作(可能和备份过程中的某些快照存储相关)。
uninstall :从 Kubernetes 集群中卸载 velero 工具。
version :打印 velero 版本以及相关联的镜像信息。
配置 Velero CLI 访问 MinIO 认证密钥
root@k8s-master01:~#cat credentials-velero
[default]
aws_access_key_id = g6VCbWc6jrMJE7z5MkR0
aws_secret_access_key = wlgiGc7Nl2UPkIH2Kb5nYEVjUKheSho1KCMf16QG安装 Velero Server
备份到部署的MinIO
#注意:minio.org需要coreDNS解析,不能用hosts文件解析
root@k8s-node01:~#velero install --provider=aws --image velero/velero:v1.14.0 --backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://10.0.0.100:9000 --secret-file=./credentials-velero --plugins=velero/velero-plugin-for-aws:v1.11.0 --bucket=velero --use-volume-snapshots=false --namespace velero --use-node-agent --wait查看备份位置信息
root@k8s-master01:~#velero backup-location get
NAME PROVIDER BUCKET/PREFIX PHASE LAST VALIDATED ACCESS MODE DEFAULT
default aws velero Available 2024-07-03 21:49:06 +0800 CST ReadWrite true选项说明:
--kubeconfig (可选):指定 kubeconfig 认证文件,默认使用 .kube/config
--provider :定义插件提供方
--image :定义运行velero的镜像,默认与velero客户端一致
--plugins :指定使用aws s3兼容的插件镜像
--bucket :指定对象存储Bucket桶名称
--secret-file :指定对象存储认证文件
--use-node-agent :启用文件系统备份,创建Velero Node Agent守护进程
--uploader-type=restic :使用Restic工具备份
--privileged-node-agent : 节点代理需要在特权模式下运行
--use-volume-snapshots :是否启使用快照
--namespace :指定部署所在namespace名称,默认为velero
--backup-location-config :指定对象存储地址信息,需要注意的是如果指定域名的话,服务器端必须能解析到, s3ForcePathStyle 为 true 这通常用于兼容一些非标准的 S3 访问方式
--wait :指示安装过程要等待,直到 Velero 的部署及相关配置完成并处于可用状态才结束该命令的执行,便于使用者直接确认安装结果,避免后续立即使用时出现因为安装未完成导致的问题。
卸载 Velero Server
#方法1
[root@master1 ~]#velero uninstall --namespace velero
#方法2
[root@master1 ~]#kubectl delete namespace/velero clusterrolebinding/velero
[root@master1 ~]#kubectl delete crds -l component=velero范例:备份数据至minio中,并尝试恢复数据
#创建测试应用
root@k8s-master01:~#kubectl create ns demo
root@k8s-master01:~#kubectl create deployment myapp --image registry.cn-zhangjiakou.aliyuncs.com/image_packs/demoapp:v1 --replicas 3 -n demo
root@k8s-master01:~#kubectl get pod -n demo
NAME READY STATUS RESTARTS AGE
myapp-84fc459bb7-2tr8g 1/1 Running 0 6s
myapp-84fc459bb7-2wdds 1/1 Running 0 6s
myapp-84fc459bb7-r4wvg 1/1 Running 0 6s#HostPath 存储资源
root@k8s-master01:~#cat storage-hostpath-redis.yaml
apiVersion: v1
kind: Pod
metadata:
name: hostpath-redis
namespace: demo
spec:
nodeName: k8s-node01 # 指定运行在指定worker主机上
volumes:
- name: redis-backup
hostPath:
path: /backup/redis # 宿主机的目录会自动创建
containers:
- name: hostpath-redis
image: registry.cn-beijing.aliyuncs.com/wangxiaochun/redis:6.2.5
volumeMounts:
- name: redis-backup
mountPath: /data
root@k8s-master01:~#kubectl exec -it hostpath-redis -n demo -- sh
# redis-cli set name "huahua"
OK
# redis-cli bgsave
Background saving started
# ls
dump.rdb#emptydir 存储资源
root@k8s-master01:#cat storage-emptydir-redis.yaml
apiVersion: v1
kind: Pod
metadata:
name: redis-emptydir-pod
namespace: demo
spec:
containers:
- name: redis
image: registry.cn-beijing.aliyuncs.com/wangxiaochun/redis:7.2.5
ports:
- containerPort: 6379
name: redis
volumeMounts:
- mountPath: /data
name: data
volumes:
- name: data
emptyDir: {}
root@k8s-master01:~#kubectl exec -it redis-emptydir-pod -n demo -- sh
# redis-cli set age 18
OK
# redis-cli bgsave
Background saving started
# ls
dump.rdbroot@k8s-master01:~#cat redis-pvc-sc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: redis-pvc
namespace: demo
spec:
storageClassName: sc-nfs
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
---
apiVersion: v1
kind: Pod
metadata:
name: redis-pvc-pod
namespace: demo
spec:
containers:
- name: redis
image: registry.cn-beijing.aliyuncs.com/wangxiaochun/redis:7.2.5
ports:
- containerPort: 6379
name: redis
volumeMounts:
- mountPath: /data
name: data
volumes:
- name: data
persistentVolumeClaim:
claimName: redis-pvc
root@k8s-master01:~#kubectl exec -it redis-pvc-pod -n demo -- sh
# redis-cli set name "cancan"
OK
# redis-cli bgsave
Background saving started
# ls
dump.rdb备份数据
root@k8s-master01:~#TIME=`date +%F-%H-%M-%S`
root@k8s-master01:~#velero backup create k8s-backup-$TIME --kubeconfig ~/.kube/config --include-namespaces=demo --default-volumes-to-fs-backup --snapshot-volumes=false
root@k8s-master01:~#velero backup get
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
k8s-backup-2025-02-01-22-06-58 Completed 0 0 2025-02-01 22:07:29 +0800 CST 27d default <none>
k8s-backup-2025-02-02-19-53-44 Completed 0 0 2025-02-02 19:54:17 +0800 CST 27d default <none>
k8s-backup-2025-02-04-21-03-23 Completed 0 0 2025-02-04 21:03:29 +0800 CST 29d default <none>进入minio中可以看到velero桶下会生成一个backups文件夹,里面存放的就是我们备份的数据。
数据恢复
注意:
velero restore 恢复时不会覆盖已有的资源,只恢复当前集群中不存在的资源。
已有的资源不会回滚到之前的版本,如需要回滚,需在restore之前提前删除现有的资源。
#删除资源
root@k8s-master01:~#kubectl delete ns demo
namespace "demo" deleted
root@k8s-master01:~#kubectl get ns
NAME STATUS AGE
calico-apiserver Active 39d
calico-system Active 39d
default Active 39d
ingress-nginx Active 25d
kube-node-lease Active 39d
kube-public Active 39d
kube-system Active 39d
openelb-system Active 34d
tigera-operator Active 39d
velero Active 3d#恢复数据并验证
root@k8s-master01:~#velero restore create --from-backup k8s-backup-2025-02-04-21-03-23 --wait
Restore request "k8s-backup-2025-02-02-19-53-44-20250204214705" submitted successfully.
Waiting for restore to complete. You may safely press ctrl-c to stop waiting - your restore will continue in the background.
..
Restore completed with status: Completed. You may check for more information using the commands `velero restore describe k8s-backup-2025-02-02-19-53-44-20250204214705` and `velero restore logs k8s-backup-2025-02-02-19-53-44-20250204214705`.
root@k8s-master01:~#kubectl get pods -n demo
NAME READY STATUS RESTARTS AGE
hostpath-redis 1/1 Running 0 80s
myapp-547df679bb-42k92 1/1 Running 0 80s
myapp-547df679bb-5zl24 1/1 Running 0 80s
myapp-547df679bb-s4sdl 1/1 Running 0 80s
redis-emptydir-pod 1/1 Running 0 80s
redis-pvc-pod 1/1 Running 0 80s
root@k8s-master01:~#kubectl exec -it hostpath-redis -n demo -- sh
# redis-cli get name
"huahua"
root@k8s-master01:~#kubectl exec -it redis-emptydir-pod -n demo -- sh
# redis-cli get age
"18"
root@k8s-master01:~#kubectl exec -it redis-pvc-pod -n demo -- sh
# redis-cli get name
"cancan"