本次使用velero1.7.1.对接备份存储为minio
介绍
velero 是一款云原生时代的灾难恢复和迁移工具,采用 Go 语言编写,并在 github 上进行了开源,利用 velero 用户可以安全的备份、恢复和迁移 Kubernetes 集群资源和持久卷。
开源地址:https://github.com/vmware-tanzu/velero 官方文档:https://velero.io/docs
- Velero 是一个云原生的灾难恢复和迁移工具, 采用 Go 语言编写,可以安全的备份、恢复和迁移Kubernetes集群资源和持久卷。
- 使用velero可以对集群进行备份和恢复,降低集群DR造成的影响。其基本原理就是将集群的数据备份到对象存储中,在恢复的时候将数据从对象存储中拉取下来。
- 除了灾备之外velero还能做资源移转,支持把容器应用从一个集群迁移到另一个集群。
在kubernetes的备份体系当中,etcd通常被作为主要的备份手段。与 Etcd 备份相比,直接备份 `Etcd` 是将集群的全部资源备份起来。而 `Velero` 可以对 `Kubernetes` 集群内对象级别进行备份。除了对 `Kubernetes` 集群进行整体备份外,`Velero` 还可以通过对 `Type`、`Namespace`、`Label` 等对象进行分类备份或者恢复。
组件
Velero 组件一共分两部分,分别是服务端和客户端。
- 服务端:运行在你 Kubernetes 的集群中
- 客户端:是一些运行在本地的命令行的工具,需要已配置好 kubectl 及集群 kubeconfig 的机器上
流程
- velero客户端调用kubernetes API Server创建backup任务
- Backup控制器基于watch机制通过Api Server获取到备份任务
- Backup控制器开始执行备份动作,会通过请求Api Server获取到需要备份的数据
- Backup 控制器将获取到的数据备份到指定的对象存储server端
存储后端
Velero支持两种关于后端存储的CRD,分别是BackupStorageLocation和VolumeSnapshotLocation。
- BackupStorageLocation
主要用来定义 Kubernetes 集群资源的数据存放位置,也就是集群对象数据,不是 PVC 的数据。主要支持的后端存储是 S3 兼容的存储,比如:Mino 和阿里云 OSS 等。
- VolumeSnapshotLocation
主要用来给 PV 做快照,需要云提供商提供插件。阿里云已经提供了插件,这个需要使用 CSI 等存储机制。
配置minio
Velero支持很多种存储插件,可查看:https://velero.io/docs/v1.10/supported-providers/获取插件信息,我们这里使用minio作为S3兼容的对象存储提供程序。您也可以在任意地方部署Minio对象存储,只需要保证K8S集群可以访问到即可。
---
apiVersion: v1
kind: Service
metadata:
name: minio
namespace: velero
labels:
app: minio
spec:
selector:
app: minio
ports:
- name: api
port: 9000
protocol: TCP
- name: console
port: 9001
protocol: TCP
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: minio
namespace: velero
labels:
app: minio
spec:
replicas: 1
serviceName: minio
selector:
matchLabels:
app: minio
template:
metadata:
labels:
app: minio
spec:
containers:
- name: minio
image: docker.io/bitnami/minio:2023.3.22
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9000
name: api
protocol: TCP
- containerPort: 9001
name: console
protocol: TCP
env:
- name: MINIO_ROOT_USER
value: "minio"
- name: MINIO_ROOT_PASSWORD
value: "minio123"
- name: MINIO_DEFAULT_BUCKETS
value: "velero"
volumeMounts:
- name: data
mountPath: /data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 50Gi
配置完成后,如下所示
#创建minio
kubectl apply -f minio.yaml
安装velero
安装
wget https://github.com/vmware-tanzu/velero/releases/download/v1.7.1/velero-v1.7.1-linux-amd64.tar.gz
tar -xf velero-v1.7.1-linux-amd64.tar.gz
cp velero-v1.7.1-linux-amd64/velero /usr/bin/
#验证
velero version
==============
Client:
Version: v1.7.1
Git commit: 4729274d07eae7e788233d5c995d7f45f40c9c61
Server:
Version: v1.7.0
==============
创建密钥
$ cat > credentials-velero <<EOF
[default]
aws_access_key_id = minio
aws_secret_access_key = minio123
EOF
安装velero到k8s集群
velero install \
--provider aws \
--bucket velero \
--prefix k8s-bak \
--image velero/velero:v1.7.0 \
--plugins velero/velero-plugin-for-aws:v1.3.0 \
--namespace velero \
--secret-file ./credentials-velero \
--use-volume-snapshots=false \
--use-restic \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://192.168.233.3:30873
# 可使用如下命令查看运行日志
kubectl logs deployment/velero -n velero
# 查看velero创建的api对象
kubectl api-versions | grep velero
velero.io/v1
# 查看备份位置
velero backup-location get
=========
NAME PROVIDER BUCKET/PREFIX PHASE LAST VALIDATED ACCESS MODE DEFAULT
default aws velero/k8s-bak Available 2024-06-13 17:05:12 +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守护进程,托管FSB模块;
- --use-volume-snapshots:是否启使用快照;
- --namespace:指定部署的namespace名称,默认为velero;
- --backup-location-config:指定对象存储地址信息;
卸载
#如果您想从集群中完全卸载Velero,则以下命令将删除由velero install创建的所有资源:
kubectl delete namespace/velero clusterrolebinding/velero
kubectl delete crds -l component=velero
备份
备份命令:velero create backup NAME [flags]
backup选项:
- --exclude-namespaces stringArray : 要从备份中排除的名称空间
- --exclude-resources stringArray: 要从备份中排除的资源,如storageclasses.storage.k8s.io
- --include-cluster-resources optionalBool[=true]: 包含集群资源类型
- --include-namespaces stringArray: 要包含在备份中的名称空间(默认'*')
- --include-resources stringArray: 备份中要包括的资源
- --labels mapStringString: 给这个备份加上标签
- -o, --output string: 指定输出格式,支持'table'、'json'和'yaml';
- -l, --selector labelSelector: 对指定标签的资源进行备份
- --snapshot-volumes optionalBool[=true]: 对 PV 创建快照
- --storage-location string: 指定备份的位置
- --ttl duration: 备份数据多久删掉
- --volume-snapshot-locations strings: 指定快照的位置,也就是哪一个公有云驱动
备份
elero backup create ops-bak --include-namespaces ops --default-volumes-to-restic
==========
Backup request "default" submitted successfully.
Run `velero backup describe default` or `velero backup logs default` for more details.
=============
- --include-namespaces:指定命名空间
- --selector:标签选择器,如app=nginx
查看备份信息
$ velero backup get
# 查看备份详细信息
$ velero backup describe
# 查看备份日志
$ velero backup logs nginx-backup
进入minio查看备份内容
定时备份
更多cron示例请参考:cron package’s documentation
# 使用cron表达式备份
$ velero schedule create nginx-daily --schedule="0 1 * * *" --include-namespaces nginx-example
# 使用一些非标准的速记 cron 表达式
$ velero schedule create nginx-daily --schedule="@daily" --include-namespaces nginx-example
# 手动触发定时任务
$ velero backup create --from-schedule nginx-daily
注意事项
- 在velero备份的时候,备份过程中创建的对象是不会被备份的。
velero restore
恢复不会覆盖已有的资源
,只恢复当前集群中不存在的资源
。已有的资源不会回滚到之前的版本,如需要回滚,需在restore之前提前删除现有的资源。- 可以将velero作为一个cronjob来运行,定期备份数据。
恢复
模拟故障
#删除ops空间和里面的资源
kubectl delete ns ops
恢复
使用velero命令行工具执行恢复操作,相关命令参数说明如下:
--exclude-namespaces stringArray Namespaces to exclude from the restore.
--exclude-resources stringArray Resources to exclude from the restore, formatted as resource.group, such as storageclasses.storage.k8s.io.
--from-backup string Backup to restore from
--from-schedule string Schedule to restore from
--include-cluster-resources optionalBool[=true] Include cluster-scoped resources in the restore.
--include-namespaces stringArray Namespaces to include in the restore (use '*' for all namespaces) (default *)
--include-resources stringArray Resources to include in the restore, formatted as resource.group, such as storageclasses.storage.k8s.io (use '*' for all resources).
--labels mapStringString Labels to apply to the restore.
--namespace-mappings mapStringString Namespace mappings from name in the backup to desired restored name in the form src1:dst1,src2:dst2,...
--preserve-nodeports optionalBool[=true] Whether to preserve nodeports of Services when restoring.
# 是否连同持久存储数据一起恢复
--restore-volumes optionalBool[=true] Whether to restore volumes from snapshots.
-l, --selector labelSelector Only restore resources matching this label selector. (default <none>)
进行恢复
[root@node1 velero]# velero backup get
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
ops-bak Completed 0 0 2024-06-13 16:38:50 +0800 CST 29d default <none>
[root@node1 velero]# velero restore create --from-backup ops-bak
Restore request "ops-bak-20240613172336" submitted successfully.
Run `velero restore describe ops-bak-20240613172336` or `velero restore logs ops-bak-20240613172336` for more details.
[root@node1 velero]#
检查恢复的资源
[root@node1 velero]# velero restore get
NAME BACKUP STATUS STARTED COMPLETED ERRORS WARNINGS CREATED SELECTOR
ops-bak-20240613172336 ops-bak Completed 2024-06-13 17:23:36 +0800 CST 2024-06-13 17:23:37 +0800 CST 0 0 2024-06-13 17:23:36 +0800 CST <none>
#查看详细信息
[root@node1 velero]#velero restore describe ops-bak-20240613172336
===========
Name: ops-bak-20240613172336
Namespace: velero
Labels: <none>
Annotations: <none>
Phase: Completed
Total items to be restored: 17
Items restored: 17
Started: 2024-06-13 17:23:36 +0800 CST
Completed: 2024-06-13 17:23:37 +0800 CST
Backup: ops-bak
Namespaces:
Included: all namespaces found in the backup
Excluded: <none>
Resources:
Included: *
Excluded: nodes, events, events.events.k8s.io, backups.velero.io, restores.velero.io, resticrepositories.velero.io
Cluster-scoped: auto
Namespace mappings: <none>
Label selector: <none>
Restore PVs: auto
Preserve Service NodePorts: auto
==============
#检查恢复的资源
[root@node1 velero]# kubectl get all -n ops
================
NAME READY STATUS RESTARTS AGE
pod/mysql-9b877f47-hcjp4 1/1 Running 0 13m
pod/myweb-76c98cd497-576tn 1/1 Running 0 13m
pod/myweb-76c98cd497-h4zvw 1/1 Running 0 13m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/mysql ClusterIP 10.233.45.112 <none> 3306/TCP 13m
service/myweb NodePort 10.233.21.217 <none> 8080:30001/TCP 13m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/mysql 1/1 1 1 13m
deployment.apps/myweb 2/2 2 2 13m
NAME DESIRED CURRENT READY AGE
replicaset.apps/mysql-9b877f47 1 1 1 13m
replicaset.apps/myweb-76c98cd497 2 2 2 13m
========