Kubernetes+Minio+Velero:终极备份解决方案
转载:Kubernetes+Minio+Velero:终极备份解决方案
1.Velero介绍
1.1 为何需要Velero
对于 Kubernetes 集群的备份,其实定期备份etcd数据库就可以了,但etcd的备份通常是针对整个集群进行备份与恢复,如果只是想恢复某个特定名称空间中的资源时,etcd的备份与恢复就难以实现,因此就有了velero。 Velero 可以对 Kubernetes 集群整体进行备份,还能对集群内不同的Namespace资源进行分别备份和恢复。
1.2 什么是velero
Velero 是一个开源的Kubernetes集群备份与恢复工具,由 Go 语言编写,这个项目目前已经被 VMware 收购,但仍然保持开源。
Velero 的工作方式是将我们的 Kubernetes 集群的数据备份到对象存储中,当我们需要恢复数据时,Velero 会从这个对象存储服务中拉取数据,然后在集群中恢复它。
当然Velero除了备份和恢复之外,还可以帮助我们进行应用的迁移。比如,如果我们有一个应用正在运行在集群 A,我们想把它迁移到集群 B,借助 Velero 备份与恢复模式,可以让这个过程变得非常简单。
1.3 Velero应用场景
-
1、灾备场景:提供备份恢复Kubernetes集群的能力
-
2、迁移场景:提供复制集群资源到其他集群的能力
1.4 Velero工作流程
Velero备份工作逻辑:
-
1、velero客户端执行备份的创建命令后,Velero服务端会将该命令转换成一个APIServer的请求,而后通过kubeconfig连接对应的APIServer发送请求。
-
2、APIServer收到这个请求后,会创建一个Backup资源(该资源包含了备份的资源相关信息),而后将其存储在etcd数据库中。
-
3、Velero Server 运行了一个BackupController控制器,主要用于监视新创建的Backup资源,一旦监控到新的 Backup 对象时,它会开始执行备份过程。
-
4、BackupController 在执行备份时,会先通过APIServer获取要备份资源,而这些备份资源 API Server 会从 etcd 中获取这些信息。
-
5、BackupController 会将从 API Server 获取的数据写入到对象存储中。(如 S3 兼容的minIO存储服务)
Velero恢复工作逻辑:
-
1、velero客户端执行恢复命令后,velero服务端会将该命令转换成一个APIServer的请求,而后通过kubeconfig连接对应的APIServer发送请求。
-
2、APIServer收到这个请求后,会创建一个Restore资源,而后将其存储在etcd数据库中。
-
3、Velero Server 运行了的RestoreController控制器,主要用于监视新创建的Restore资源,当监控到Restore对象时候则会执行恢复逻辑。
-
4、当RestoreController控制器在恢复数据时,首先从对象存储获取此前备份数据,然后通过APIServer完成etcd的更新,进而完成集群的恢复。
1.5 Velero支持的后端存储
-
1、AWS S3 以及兼容 S3 的存储,比如:MinIO、腾讯的COS
-
2、Aliyun OSS 存储(插件很久没更新了)
-
2、Azure BloB 存储
-
3、Google Cloud 存储
2.Velero结合MinIO备份与恢复实践
实现思路:
-
1、部署 MinIO 服务,可以通过Docker部署,也可以通过Kubernetes进行部署。
-
2、创建一个 MinIO 存储桶,用于存储 Velero 备份。
-
3、获取 MinIO 的用户与密码。后期配置Velero需要通过这些凭证来访问MinIO。
-
4、安装 Velero 客户端工具,需要部署在已经配置好kubectl,同时拥有kubeconfig的节点上。
-
5、安装 Velero 服务端,通过客户端命令创建出服务端的Pod,然后给该Pod传递对应存储的地址,以及存储访问存储的凭据。
-
6、调用 Velero 进行集群的整体备份,或者某个名称空间的备份。
2.1 部署minIO
1、安装Docker
[root@docker-node1 ~]# yum install yum-utils device-mapper-persistent-data lvm2 -y
[root@docker-node1 ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@docker-node1 ~]# yum install docker-ce -y
[root@docker-node1 ~]# systemctl start docker
2、使用Docker运行minIO
对象存储
-
9000端口:MinIO的默认端口,用于处理来自客户端的API请求,包括上传、下载,以及管理存储在MinIO上的对象。
-
9001端口:这个端口用于提供MinIO Console服务。MinIO Console是一个独立的服务,提供了图形界面的方式管理MinIO。
[root@docker-node1 ~]# docker run -d --name minion \
-p 9000:9000 \
-p 9001:9001 \
--restart=always \
-e "MINIO_ACCESS_KEY=admin" \
-e "MINIO_SECRET_KEY=minio_oldxu" \
-v /data/minion:/data \
minio/minio:latest \
server /data --console-address ":9001"
3、通过http://IP:9001
访问minIO,输入用户名admin
,密码minio_oldxu
4、创建一个名为k8s-data
的buckets存储桶(Buckets-->Create a Bucket
)
2.2 下载velero客户端
最好将velero客户端部署在Kubernetes的Master节点上。如果部署在其他节点则需要考虑创建出对应的kubeconfig文件。
1、安装velero客户端
[root@master01 ~]# wget https://github.com/vmware-tanzu/velero/releases/download/v1.11.1/velero-v1.11.1-linux-amd64.tar.gz
[root@master01 ~]# tar xf velero-v1.11.1-linux-amd64.tar.gz
[root@master01 ~]# cp velero-v1.11.1-linux-amd64/velero /usr/local/bin/
2、创建一个名为 velero_auth.txt
的文件,填写 MinIO 的用户名称
以及用户密码
。文件内容应如下:
[root@master01 ~]# cat > velero_auth.txt <<EOF
[default]
aws_access_key_id = admin
aws_secret_access_key = minio_oldxu
EOF
2.3 安装velero服务端
1、将velero服务端以Pod形式运行在Kubernetes环境中。https://github.com/vmware-tanzu/velero-plugin-for-aws
[root@master01 ~]# kubectl create namespace velero-system
[root@master01 ~]# velero install \
--kubeconfig /root/.kube/config \
--provider aws \
--plugins uhub.service.ucloud.cn/oldxu/velero-plugin-for-aws:v1.7.1 \
--image uhub.service.ucloud.cn/oldxu/velero:v1.11.1 \
--bucket k8s-data \
--secret-file ./velero_auth.txt \
--use-node-agent \
--default-volumes-to-fs-backup \
--use-volume-snapshots=false \
--namespace velero-system \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://10.0.0.191:9000
# --kubeconfig 指定 kubeconfig 文件的路径,这个文件包含了 Kubernetes API server 的地址和认证信息,用于连接到 Kubernetes 集群。
# --provider 指定云服务提供商的名称。虽然这里指定的是 aws,但实际上你可以使用任何兼容 S3 的存储后端。例如:Minio对象存储。
# --plugins 指定要加载的插件的镜像。这里指定的是 AWS 插件,版本为 v1.7.1。 官方镜像:velero/velero-plugin-for-aws:v1.7.1
# --image 指定 Velero 服务端镜像,这里使用的是 v1.11.1 版本。官方镜像:velero/velero:v1.11.1
# --bucket 指定用于存储备份数据的存储桶的名称。
# --secret-file 指定对应存储认证信息的文件的路径。这个文件通常包含 Access Key 和 Secret Key。
# --use-node-agent 创建Velero Node Agent守护进程,启用文件系统备份,通常用于备份pvc中的数据;
# --default-volumes-to-fs-backup 将 Pod Volume 备份到文件系统备份
# --use-volume-snapshots=false 指明是否备份pv中的数据,但这需要对象存储支持PV快照。false表示不使用。
# --namespace 指定部署 Velero服务端到 Kubernetes 哪个名称空间。
# --backup-location-config 指定备份存储位置的配置。
2、检查velero对应的Pod是否正常运行
[root@master01 ~]# kubectl get pod -n velero-system
NAME READY STATUS RESTARTS AGE
node-agent-jlw4s 1/1 Running 0 107s
node-agent-nhxzv 1/1 Running 0 107s
node-agent-jqdlz 1/1 Running 0 107s
velero-848574b558-qmcmv 1/1 Running 0 107s
3、查看velero服务端的默认备份BUCKET
[root@master01 ~]# velero backup-location get --namespace=velero-system
NAME PROVIDER BUCKET/PREFIX PHASE LAST VALIDATED ACCESS MODE DEFAULT
default aws k8s-data Available 2023-08-29 14:29:53 +0800 CST ReadWrite true
4、查看velero的服务端和客户端版本(可选)
[root@master01 ~]# velero version --namespace=velero-system
Client:
Version: v1.11.1
Git commit: bdbe7eb242b0f64d5b04a7fea86d1edbb3a3587c
Server:
Version: v1.11.1
2.4 运行有状态应用
1、创建名称空间
[root@master01 ~]# kubectl create namespace kube-mysql
2、创建一个headlessService
[root@master01 ~]# cat 01-mysql-headless.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql-svc
namespace: kube-mysql
spec:
clusterIP: None
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
2、创建一个StatefulSet控制器的MySQL应用,然后通过动态存储自动创建pv
[root@master01 ~]# cat 02-mysql-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: kube-mysql
spec:
serviceName: "mysql-svc"
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: db
image: uhub.service.ucloud.cn/oldxu/mysql:5.7
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: oldxu
ports:
- containerPort: 3306
volumeMounts:
- name: data
mountPath: /var/lib/mysql/
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "nfs-provisioner-storage"
resources:
requests:
storage: 5Gi
3、获取MySQL的Pod地址
[root@master01 mysql_test_yaml]# kubectl get pod -n kube-mysql -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql-0 1/1 Running 0 2m10s 192.168.1.67 node01.oldxu.net <none> <none>
4、模拟产生一些数据
[root@master01 ~]# mysql -h 192.168.1.67 -uroot -poldxu
MySQL [(none)]>
MySQL [(none)]> create database oldxu;
MySQL [(none)]> create database velero;
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| oldxu |
| performance_schema |
| sys |
| velero |
+--------------------+
7 rows in set (0.00 sec)
2.5 velero备份实践
1、备份mysql所在的kube-mysql
名称空间
[root@master01 ~]# velero backup create backup-kube-mysql-$(date +%Y%m%d%H%M%S) \
--kubeconfig=/root/.kube/config \
--include-namespaces kube-mysql \
--default-volumes-to-fs-backup \
--namespace velero-system
# --include-namespaces 参数指定了备份应该default名称空间资源。如果你想备份多个名称空间,可以使用--include-namespaces default,kube-system
# --default-volumes-to-fs-backup 备份pod所关联的pvc数据
# --namespace velero-system 参数在这里的作用是告诉 Velero 客户端,它应该在哪个命名空间中查找 Velero 服务端的资源
2、也可以直接备份所有名称空间
[root@master01 ~]# velero backup create full-backup-$(date +%Y%m%d%H%M%S) \
--kubeconfig=/root/.kube/config \
--default-volumes-to-fs-backup \
--namespace velero-system
3、通过客户端命令查看备份的结果
[root@master01 ~]# velero backup get --namespace=velero-system
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
backup-kube-mysql-20230830160710 Completed 0 0 2023-08-30 16:07:11 +0800 CST 29d default <none>
full-backup-20230830160723 Completed 0 0 2023-08-30 16:07:24 +0800 CST 29d default <none>
2.6 模拟集群灾难
1、删除kube-mysql
名称空间的mysql数据库
[root@master01 ~]# kubectl delete statefulsets.apps mysql -n kube-mysql
[root@master01 ~]# kubectl delete service mysql-svc -n kube-mysql
2、删除mysql对应的pvc
[root@master01 ~]# kubectl delete pvc data-mysql-0 -n kube-mysql
2.7 velero恢复实践
1、velero执行恢复操作
[root@master01 ~]# velero restore create \
--from-backup backup-kube-mysql-20230906163027 \
--wait \
--kubeconfig=/root/.kube/config \
--namespace=velero-system
当执行恢复操作时,如果该Pod有持久卷数据需要恢复,那么 Velero 会在每个需要恢复的 pod 中添加一个名称为restore-wait
的 init container
。这个 init container
的镜像地址是velero/velero-restore-helper:v1.11.1
,它主要的任务是从备份中恢复 Persistent Volume
的数据。
2、检查数据是否恢复成功
[root@master01 ~]# mysql -h 192.168.1.70 -uroot -poldxu
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| oldxu |
| performance_schema |
| sys |
| velero |
+--------------------+
7 rows in set (0.00 sec)
2.8 velero周期性备份
Velero 默认提供了 schedule 的功能,该功能可以实现周期性的的备份任务。但velero周期性备份任务不会清理历史的备份数据,需要定期手动删除,当然也可以指定--ttl
选项为创建的备份指定过期时间。
1、创建一个每天凌晨 3 点执行备份任务
[root@-master01 ~]# velero schedule create all-namespace-backup \
--default-volumes-to-fs-backup \
--schedule="0 3 * * *" \
--namespace=velero-system
# all-namespace-backup 是备份计划的名称,--schedule="0 1 * * *" 定义了备份计划的时间表。
2、创建每小时都备份default名称空间
的任务,但备份的内容仅保留24小时,超过24小时会被自动删除。
[root@master01 ~]# velero schedule create default-namespace-backup \
--schedule="0 */1 * * *" \
--include-namespaces default \
--default-volumes-to-fs-backup \
--ttl 24h0m0s \
--namespace=velero-system
3、检查备份的结果
[root@master01 ~]# velero schedule get --namespace=velero-system
NAME STATUS CREATED SCHEDULE BACKUP TTL LAST BACKUP SELECTOR PAUSED
all-namespace-backup Enabled 2023-07-17 14:36:22 +0800 CST 0 3 * * * 0s n/a <none> false
default-namespace-backup Enabled 2023-07-17 14:40:10 +0800 CST * */1 * * * 24h0m0s n/a <none> false