用 Minio 启动 Velero 实现 Kubernetes资源备份
Velero 简介
https://github.com/vmware-tanzu/velero
. Velero 属于 VMWare 开源的 Kubernetes 集群备份、恢复、迁移工具.
. 可以提供 Kubernetes 备份功能更,在 Kubernetes 集群出现问题之后,能够快速的恢复.
. 并且也提供了集群迁移功能,可以将 Kubernetes 资源迁移到其他集群.
. Velero 将备份的信息在对象存储中, 默认情况下可以使用 AWS、Azure、GCP 的对象存储.
. 对于 K8s 集群数据的备份和恢复,以及复制当前集群数据到其他集群等都非常方便。可以在两个集群间克隆应用和命名空间,来创建一个临时性的开发环境.
什么是 Velero
Velero 是一个云原生的灾难恢复和迁移工具,它本身也是开源的, 采用 Go 语言编写,可以安全的备份、恢复和迁移Kubernetes集群资源和持久卷.
Velero 是非常符合 Kubernetes 社区的命名风格。Velero 的开发公司 Heptio,之前已被 VMware 收购,其创始人 2014 就职于 Google,当时被认为是 Kubernetes.
Velero 是一种云原生的 Kubernetes 优化方法,支持标准的 K8S 集群,既可以是私有云平台也可以是公有云。除了灾备之外它还能做资源移转,支持把容器应用从一个集群迁移到另一个集群.
Heptio Velero ( 以前的名字为 ARK) 是一款用于 Kubernetes 集群资源和持久存储卷(PV)的备份、迁移以及灾难恢复等的开源工具.
使用 velero 可以对集群进行备份和恢复,降低集群 DR 造成的影响。velero 的基本原理就是将集群的数据备份到对象存储中,在恢复的时候将数据从对象存储中拉取下来.
备份过程
1 . 本地 Velero 客户端发送备份指令
2 . Kubernetes 集群内就会创建一个 Backup 对象
3 . BackupController 监测 Backup 对象并开始备份过程
4 . BackupController 会向 API Server 查询相关数据
5 . BackupController 将查询到的数据备份到远端的对象存储
支持备份存储
. AWS S3 以及兼容 S3 的存储,比如:Minio
. Azure BloB 存储
. Google Cloud 存储
. Aliyun OSS 存储
Velero 特性
Velero 目前包含以下特性:
- 支持 Kubernetes 集群数据备份和恢复
- 支持复制当前 Kubernetes 集群的资源到其它 Kubernetes 集群
- 支持复制生产环境到开发以及测试环境
Velero 组件
Velero 组件一共分两部分,分别是服务端和客户端:
- 服务端:运行在你 Kubernetes 的集群中
- 客户端:是一些运行在本地的命令行的工具,需要已配置好 kubectl 及集群 kubeconfig 的机器上
测试环境
注意,K8s 与velero 的兼容性
注意,本示例备份存储为 minio, 其没有对 pvc 及快照做备份
前提
. 访问 Kubernetes 集群,版本 1.7 或更高
. 集群上的一个 DNS 服务器
. 安装了 kubectl
. 足够的磁盘空间来存储 Minio 中的备份。你将需要足够的磁盘空间来处理任何备份,再加上至少1GB的额外空间。如果少于1GB的可用磁盘空间,Minio 将无法运行
注意: 文件系统备份支持需要 Kubernetes 1.10 或更高版本,或启用挂载传播功能的早期版本,参见 文件系统备份
k8s 版本
代码语言:javascript复制$ kubectl get no
NAME STATUS ROLES AGE VERSION
ubuntu Ready control-plane 119d v1.24.3
velero 版本(本环境用当前最新版v1.10.0测试)
代码语言:javascript复制$ velero version
Client:
Version: v1.10.0
Git commit: 367f563072659f0bcd809bc33507fd75cd722344
Server:
Version: v1.10.0
Install
Install Velero-cli
参阅安装 Velero CLI 的不同选项
CLI安装比较简单,不再做以说明.
Install Minio
根据以下配置创建 Minio.yaml 文件:
代码语言:javascript复制---
apiVersion: v1
kind: Namespace
metadata:
name: velero
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: velero
name: minio
labels:
component: minio
spec:
strategy:
type: Recreate
selector:
matchLabels:
component: minio
template:
metadata:
labels:
component: minio
spec:
volumes:
- name: storage
emptyDir: {}
- name: config
emptyDir: {}
containers:
- name: minio
image: minio/minio:latest
imagePullPolicy: IfNotPresent
args:
- server
- /storage
- --config-dir=/config
env:
- name: MINIO_ACCESS_KEY
value: "minio"
- name: MINIO_SECRET_KEY
value: "minio123"
ports:
- containerPort: 9000
volumeMounts:
- name: storage
mountPath: "/storage"
- name: config
mountPath: "/config"
---
apiVersion: v1
kind: Service
metadata:
namespace: velero
name: minio
labels:
component: minio
spec:
# ClusterIP is recommended for production environments.
# Change to NodePort if needed per documentation,
# but only if you run Minio in a test/trial environment, for example with Minikube.
type: ClusterIP
ports:
- port: 9000
targetPort: 9000
protocol: TCP
selector:
component: minio
---
apiVersion: batch/v1
kind: Job
metadata:
namespace: velero
name: minio-setup
labels:
component: minio
spec:
template:
metadata:
name: minio-setup
spec:
restartPolicy: OnFailure
volumes:
- name: config
emptyDir: {}
containers:
- name: mc
image: minio/mc:latest
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- "mc --config-dir=/config config host add velero http://minio:9000 minio minio123 && mc --config-dir=/config mb -p velero/velero"
volumeMounts:
- name: config
mountPath: "/config"
代码语言:javascript复制$ kubectl create ns velero
$ kubectl apply -f minio.yaml
Install Velero 服务器
代码语言:javascript复制$ velero install
--provider aws
--plugins velero/velero-plugin-for-aws:v1.2.1
--bucket velero-backups
--secret-file /root/velero/credentials-velero
--use-volume-snapshots=false
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://192.168.86.129:32001
注意参数:
- 首先安装好 minio
- 设置好 minio 存值桶 velero-backups
- 设置 secret-file 密钥(以下说明)
- minio 访问地址,根据自己环境设置为 LB 或 NodePort 等(本示例已设置为 NodePort 访问)
$ vim /root/velero/credentials-velero
[default]
aws_access_key_id = minio
aws_secret_access_key = minio123
部署测试资源 nginx.yaml
代码语言:javascript复制---
apiVersion: v1
kind: Namespace
metadata:
name: nginx-example
labels:
app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: nginx-example
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:1.17.6
name: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
name: my-nginx
namespace: nginx-example
spec:
ports:
- port: 80
targetPort: 80
selector:
app: nginx
type: LoadBalancer
代码语言:javascript复制$ kubectl apply -f nginx.yaml
检查 velero 部署
代码语言:javascript复制$ kubectl get deployments -l component=velero --namespace=velero
NAME READY UP-TO-DATE AVAILABLE AGE
velero 1/1 1 1 30m
$ kubectl get po -n velero
NAME READY STATUS RESTARTS AGE
velero-6976844696-jwvbb 1/1 Running 0 47s
备份 Nginx 并查看备份情况
代码语言:javascript复制$ velero backup create nginx-backup --selector app=nginx
Backup request "nginx-backup" submitted successfully.
Run `velero backup describe nginx-backup` or `velero backup logs nginx-backup` for more details.
代码语言:javascript复制$ velero backup describe nginx-backup
...
Name: nginx-backup
Namespace: velero
Labels: velero.io/storage-location=default
Annotations: velero.io/source-cluster-k8s-gitversion=v1.24.3
velero.io/source-cluster-k8s-major-version=1
velero.io/source-cluster-k8s-minor-version=24
Phase: Completed
Errors: 0
Warnings: 2
Namespaces:
Included: *
Excluded: <none>
Resources:
Included: *
Excluded: <none>
Cluster-scoped: auto
Label selector: app=nginx
Storage Location: default
...
显示 Completed , 说明备份成功!
查看备份的资源列表
删除 nginx 资源
代码语言:javascript复制$ kubectl delete namespace nginx-example
$ kubectl get all --namespace=nginx-example
No resources found in nginx-example namespace.
恢复资源
代码语言:javascript复制$ velero restore create --from-backup nginx-backup
// 已经看到 velero 将删除的资源 nginx 恢复到原来的 ns 下面
$ kubectl get all --namespace=nginx-example
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-59699f4f78-94db7 2/2 Running 2 (7d7h ago) 11d
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/my-nginx ClusterIP 10.109.85.213 <none> 80/TCP 11d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 1/1 1 1 11d
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-59699f4f78 1 1 1 11d
注意
还原可能需要一些时间才能完成。在此期间,STATUS 列将显示 InProgress.
成功还原后,STATUS 列为 Completed,WARNINGS 和 ERRORS 为 0, nginx-example命名空间中的所有对象都应该与删除它们之前一样
For more information, see the debugging information.