| Velero version | Expected Kubernetes version compatibility | Tested on Kubernetes version |
|---|---|---|
| 1.14 | 1.18-latest | 1.27.9, 1.28.9, and 1.29.4 |
| 1.13 | 1.18-latest | 1.26.5, 1.27.3, 1.27.8, and 1.28.3 |
| 1.12 | 1.18-latest | 1.25.7, 1.26.5, 1.26.7, and 1.27.3 |
| 1.11 | 1.18-latest | 1.23.10, 1.24.9, 1.25.5, and 1.26.1 |
| 1.10 | 1.18-latest | 1.22.5, 1.23.8, 1.24.6 and 1.25.1 |
1)k8s的备份-恢复
集群规划
| 主机名 | 主机IP | 集群版本 |
|---|---|---|
| k8s-master01 | 192.168.139.241 | v1.29.4 |
| k8s-node01 | 192.168.139.244 | v1.29.4 |
| str-minio | 192.168.139.247 |
Velero 组件一共分两部分,分别是服务端和客户端。
-
服务端:运行在你 Kubernetes 的集群中
-
客户端:是一些运行在本地的命令行的工具,需要已配置好 kubectl 及集群 kubeconfig 的机器上
velero备份流程
-
velero客户端调用kubernetes API Server创建backup任务
-
Backup控制器基于watch机制通过Api Server获取到备份任务
-
Backup控制器开始执行备份动作,会通过请求Api Server获取到需要备份的数据
-
Backup 控制器将获取到的数据备份到指定的对象存储server端
Velero后端存储
Velero支持两种关于后端存储的CRD,分别是BackupStorageLocation和VolumeSnapshotLocation。
BackupStorageLocation
主要用来定义 Kubernetes 集群资源的数据存放位置,也就是集群对象数据,不是 PVC 的数据。主要支持的后端存储是 S3 兼容的存储,比如:Mino 和阿里云 OSS 等。
VolumeSnapshotLocation
主要用来给 PV 做快照,需要云提供商提供插件。阿里云已经提供了插件,这个需要使用 CSI 等存储机制。你也可以使用专门的备份工具 Restic,把 PV 数据备份到阿里云 OSS 中去(安装时需要自定义选项)。
Restic 是一款 GO 语言开发的数据加密备份工具,顾名思义,可以将本地数据加密后传输到指定的仓库。支持的仓库有 Local、SFTP、Aws S3、Minio、OpenStack Swift、Backblaze B2、Azure BS、Google Cloud storage、Rest Server
安装velero
安装velero客户端
在 Github Release 页面下载指定的 velero 二进制客户端安装包,比如这里我们下载我们k8s集群对应的版本为 [v1.13.2](https://github.com/vmware-tanzu/velero/releases/tag/v1.13.2)
~# curl -LO https://github.com/vmware-tanzu/velero/releases/download/v1.13.2/velero-v1.13.2-linux-amd64.tar.gz
~# tar xf velero-v1.13.2-linux-amd64.tar.gz
~# mv velero-v1.13.2-linux-amd64/velero /usr/local/bin/
`# 启用命令补全`
~# source <(velero completion bash)
~# velero completion bash > /etc/bash_completion.d/velero
~# velero version
Client:
Version: v1.13.2
Git commit: 4d961fb6fec384ed7f3c1b7c65c818106107f5a6
<error getting server version: no matches for kind "ServerStatusRequest" in version "velero.io/v1">
安装minio存储
k8s中部署minio
~# vim minio-deployment.yaml
---
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
- --console-address=:9001
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: NodePort
ports:
- name: api
port: 9000
targetPort: 9000
nodePort: 32000
- name: console
port: 9001
targetPort: 9001
nodePort: 32001
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"
root@k8s-master01:~/test# cat 1.yaml
---
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
- --console-address=:9001
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: NodePort
ports:
- name: api
port: 9000
targetPort: 9000
nodePort: 32000
- name: console
port: 9001
targetPort: 9001
nodePort: 32001
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"
~# kubectl apply -f minio-deployment.yaml
`# 开放NodePort端口`
~# kubectl patch svc minio -n velero -p '{"spec": {"type": "NodePort"}}'
~# kubectl patch svc minio -n velero --type='json' -p='[{"op": "replace", "path": "/spec/ports/0/nodePort", "value":9000},{"op": "replace", "path": "/spec/ports/1/nodePort", "value":9001}]'
~# kubectl get svc -n velero
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
minio NodePort 10.105.219.192 <none> 9000:32000/TCP,9001:32001/TCP 100m
docker部署minio
~# mkdir /data/minio/{data,config}
~# docker pull minio/minio:latest
~# docker run -p 9000:9000 -p 9090:9090 \
--net=host \
--name minio \
-d --restart=always \
-e "MINIO_ACCESS_KEY=minio" \
-e "MINIO_SECRET_KEY=minio123" \
-v /data/minio/data:/data \
-v /data/minio/config:/root/.minio \
minio/minio server \
/data --console-address ":9090" -address ":9000"
物理机部署minio
Velero支持很多种存储插件,可查看:Velero Docs - Providers获取插件信息,我们这里使用minio作为S3兼容的对象存储提供程序。您也可以在任意地方部署Minio对象存储,只需要保证K8S集群可以访问到即可
根据具体的业务场景选择不同的存储方式
`在待安装 minio 的服务器上下载二进制包`
~# curl -LO https://dl.minio.io/server/minio/release/linux-amd64/minio
~# chmod +x minio
~# mv minio /usr/local/bin/
~# minio --version
minio version RELEASE.2024-05-10T01-41-38Z (commit-id=b5984027386ec1e55c504d27f42ef40a189cdb55)
Runtime: go1.22.3 linux/amd64
License: GNU AGPLv3 - https://www.gnu.org/licenses/agpl-3.0.html
Copyright: 2015-2024 MinIO, Inc.
`创建用于运行 minio 服务的用户和组`
~# groupadd --system minio
~# useradd -s /sbin/nologin --system -g minio minio
~# mkdir /data
~# chown -R minio:minio /data/
`为 minio 创建 systemd 服务单元文件`
~# cat /etc/systemd/system/minio.service
[Unit]
Description=Minio
Documentation=https://docs.minio.io
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio
[Service]
WorkingDirectory=/data
User=minio
Group=minio
EnvironmentFile=-/etc/default/minio
ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/default/minio\"; exit 1; fi"
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
# Let systemd restart this service always
Restart=always
# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=65536
# Disable timeout logic and wait until process is stopped
TimeoutStopSec=infinity
SendSIGKILL=no
[Install]
WantedBy=multi-user.target
`创建 minio 环境文件`
~# cat /etc/default/minio
# Volume to be used for Minio server.
MINIO_VOLUMES="/data"
# Use if you want to run Minio on a custom port.
MINIO_OPTS="--address :9000 --console-address :9090 "
# Access Key of the server.
MINIO_ACCESS_KEY=minio
# Secret key of the server.
MINIO_SECRET_KEY=minio123
其中
MINIO_ACCESS_KEY为长度至少为3个字符的访问密钥,MINIO_SECRET_KEY
~# sudo systemctl daemon-reload
~# sudo systemctl start minio
~# lsof -i :9000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
minio 1946 minio 10u IPv4 42472 0t0 TCP localhost:9000 (LISTEN)
minio 1946 minio 11u IPv6 42473 0t0 TCP *:9000 (LISTEN)
minio 1946 minio 12u IPv6 42474 0t0 TCP ip6-localhost:9000 (LISTEN)
http://192.168.139.247:9090/login
注意一定要在minio的dashboard界面,创建一个名为 velerodata 的 Buckets
安装 velero 服务端
我们可以使用 velero 客户端来安装服务端,也可以使用 Helm Chart 来进行安装,比如这里我们用客户端来安装,velero 命令默认读取 kubectl 配置的集群上下文,所以前提是 velero 客户端所在的节点有可访问集群的 kubeconfig 配置。
创建密钥
~# tee > credentials-velero <<EOF
[default]
aws_access_key_id = minio
aws_secret_access_key = minio123
EOF
安装velero到k8s集群
-
物理机和docker部署的minio
`安装velero到k8s`
~# velero --kubeconfig /root/.kube/config \
install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.9.1 \
--bucket velerodata \
--secret-file ./credentials-velero \
--use-volume-snapshots=false \
--namespace velero \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://192.168.139.247:9000/
#--------------------------------------------------------------------------------------------------------------
# 执行install命令后会创建一系列清单,包括CustomResourceDefinition、Namespace、Deployment等。*
# velero install .... --dry-run -o yaml > velero_deploy.yaml 如果为私仓,可以通过--dry-run 导出 YAML 文件调整在应用。
#--------------------------------------------------------------------------------------------------------------
~# kubectl get pod -n velero
NAME READY STATUS RESTARTS AGE
node-agent-597rt 1/1 Running 0 7m49s
velero-6c4f88c7c6-qncd8 1/1 Running 0 48s
~# kubectl api-versions | grep velero
velero.io/v1
velero.io/v2alpha1
`# 查看备份位置`
~# velero backup-location get
NAME PROVIDER BUCKET/PREFIX PHASE LAST VALIDATED ACCESS MODE DEFAULT
default aws velero Available 2024-05-26 14:17:42 +0800 CST ReadWrite true
-
如果是将minio部署在k8s中则执行下面这条命令
~# velero install \
--provider aws \
--image velero/velero:v1.13.2 \
--plugins velero/velero-plugin-for-aws:v1.9.1\
--bucket velero \
--secret-file ./credentials-velero \
--use-node-agent \
--use-volume-snapshots=false \
--namespace velero \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://minio:9000
--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:指定对象存储地址信息;
备份k8s里的数据
备份命令:
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: 指定快照的位置,也就是哪一个公有云驱动
备份测试应用
~# kubectl create deployment demoapp --image=ikubernetes/demoapp:v1.0 --replicas=3 -n default
~# velero backup create demo-backup --include-namespaces default
Backup request "demo-backup" submitted successfully.
Run `velero backup describe demo-backup` or `velero backup logs demo-backup` for more details.
` 查看备份列表`
# velero backup get
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
demo-backup Completed 0 0 2024-05-26 14:20:51 +0800 CST 29d default <none>
定时备份指南
# 使用cron表达式备份
$ velero schedule create nginx-daily --schedule="0 1 * * *" --include-namespaces default
# 使用一些非标准的速记 cron 表达式
$ velero schedule create nginx-daily --schedule="@daily" --include-namespaces default
# 手动触发定时任务
$ velero backup create --from-schedule default
# 每日1点进行备份
$ velero create schedule --schedule="0 1 * * *"
# 每日1点进行备份,备份保留48小时
$ velero create schedule --schedule="0 1 * * *" --ttl 48h
# 每6小时进行一次备份
$ velero create schedule --schedule="@every 6h"
# 每日对 web namespace 进行一次备份
$ velero create schedule --schedule="@every 24h" --include-namespaces web
更多cron示例请参考:cron package’s documentation
恢复
模拟灾难
~# kubectl delete deploy --all
deployment.apps "demoapp" deleted
~# kubectl get pod
NAME READY STATUS RESTARTS AGE
demoapp-7c58cd6bb-8xrb5 1/1 Terminating 0 47m
demoapp-7c58cd6bb-ml5wb 1/1 Terminating 0 47m
demoapp-7c58cd6bb-pn525 1/1 Terminating 0 47m
恢复资源
~# velero backup get
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
demo-backup Completed 0 0 2024-05-26 14:20:51 +0800 CST 29d default <none>
~# velero restore create --from-backup demo-backup
Restore request "demo-backup-20240526142634" submitted successfully.
检查恢复的资源
# velero restore get
NAME BACKUP STATUS STARTED COMPLETED ERRORS WARNINGS CREATED SELECTOR
demo-backup-20240526142634 demo-backup Completed 2024-05-26 14:26:34 +0800 CST 2024-05-26 14:26:35 +0800 CST 0 1 2024-05-26 14:26:34 +0800 CST <none>
`# 查看详细信息`
# velero restore create --from-backup demo-backup
`# 检查资源状态`
# kubectl get pod
NAME READY STATUS RESTARTS AGE
demoapp-7c58cd6bb-8xrb5 1/1 Running 0 26s
demoapp-7c58cd6bb-ml5wb 1/1 Running 0 26s
demoapp-7c58cd6bb-pn525 1/1 Running 0 26s
卸载velero命令
`卸载方式一`
# velero uninstall --namespace velero
`卸载方式二`
# kubectl delete namespace/velero clusterrolebinding/velero
# kubectl delete crds -l component=velero
2)项目迁移实战
基于上面环境
集群规划
| 集群 | 主机名 | 主机IP | 集群版本 |
|---|---|---|---|
| 集群A | |||
| k8s-master01 | 192.168.139.241 | v1.29.4 | |
| k8s-node01 | 192.168.139.244 | v1.29.4 | |
| 集群B | |||
| k8s-master02 | 192.168.139.245 | v1.29.4 | |
| k8s-node01 | 192.168.139.246 | v1.29.4 | |
| minio存储 | str-minio | 192.168.139.247 |
集群B安装 velero
安装velero客户端
在 Github Release 页面下载指定的 velero 二进制客户端安装包,比如这里我们下载我们k8s集群对应的版本为 [v1.13.2](https://github.com/vmware-tanzu/velero/releases/tag/v1.13.2)
~# curl -LO https://github.com/vmware-tanzu/velero/releases/download/v1.13.2/velero-v1.13.2-linux-amd64.tar.gz
~# tar xf velero-v1.13.2-linux-amd64.tar.gz
~# mv velero-v1.13.2-linux-amd64/velero /usr/local/bin/
`# 启用命令补全`
~# source <(velero completion bash)
~# velero completion bash > /etc/bash_completion.d/velero
~# velero version
Client:
Version: v1.13.2
Git commit: 4d961fb6fec384ed7f3c1b7c65c818106107f5a6
<error getting server version: no matches for kind "ServerStatusRequest" in version "velero.io/v1">
安装 velero 服务端
我们可以使用 velero 客户端来安装服务端,也可以使用 Helm Chart 来进行安装,比如这里我们用客户端来安装,velero 命令默认读取 kubectl 配置的集群上下文,所以前提是 velero 客户端所在的节点有可访问集群的 kubeconfig 配置。
安装velero到k8s集群
创建密钥
~# tee > credentials-velero <<EOF
[default]
aws_access_key_id = minio
aws_secret_access_key = minio123
EOF
安装velero到k8s
`安装velero到k8s`
~# velero --kubeconfig /root/.kube/config \
install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.9.1 \
--bucket velerodata \
--secret-file ./credentials-velero \
--use-volume-snapshots=false \
--namespace velero \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://192.168.139.247:9000/
~# kubectl get pod -n velero
NAME READY STATUS RESTARTS AGE
node-agent-597rt 1/1 Running 0 7m49s
velero-6c4f88c7c6-qncd8 1/1 Running 0 48s
~# kubectl api-versions | grep velero
velero.io/v1
velero.io/v2alpha1
`# 查看备份位置`
~# velero backup-location get
NAME PROVIDER BUCKET/PREFIX PHASE LAST VALIDATED ACCESS MODE DEFAULT
default aws velero Available 2024-05-26 14:17:42 +0800 CST ReadWrite true
#卸载命令
# velero uninstall --namespace velero
# 执行install命令后会创建一系列清单,包括CustomResourceDefinition、Namespace、Deployment等。 # velero install .... --dry-run -o yaml > velero_deploy.yaml 如果为私仓,可以通过--dry-run 导出 YAML 文件调整在应用。
`如果是将minio安装在k8s中这执行下面这条命令`
velero install \
--provider aws \
--image velero/velero:v1.13.2 \
--plugins velero/velero-plugin-for-aws:v1.9.1 \
--bucket velero \
--secret-file ./credentials-velero \
--use-node-agent \
--use-volume-snapshots=false \
--namespace velero \
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://192.168.139.241:32000
注意:其中
S3的地址指向集群B(192.168.19.140)的minio对象存储。
集群A创建对应的资源
~# kubectl create ns demo
~# kubectl create deployment demoapp --image=ikubernetes/demoapp:v1.0 --replicas=3 -n demo
~# kubectl get pod -n demo
NAME READY STATUS RESTARTS AGE
demoapp-7c58cd6bb-6rnfz 1/1 Running 0 8s
demoapp-7c58cd6bb-flmjb 1/1 Running 0 8s
demoapp-7c58cd6bb-lmvnx 1/1 Running 0 8s
备份集群A资源
~# velero backup create demo-test-backup \
--default-volumes-to-fs-backup \
--include-namespaces demo
` 查看备份列表`
# velero backup get
--default-volumes-to-fs-backup:默认将所有PV卷进行备份,详情查看官方文档。
--include-namespaces:指定要备份的命名空间
恢复到集群B
`# 到集群B中查看备份资源`
# velero backup get
NAME STATUS ERRORS WARNINGS CREATED EXPIRES STORAGE LOCATION SELECTOR
demo-backup Completed 0 0 2024-05-26 14:20:51 +0800 CST 29d default <none>
demo-test-backup Completed 0 0 2024-05-26 16:07:19 +0800 CST 29d default <none>
`# 执行恢复命令`
~# velero restore create --from-backup demo-test-backup
root@k8s-master02:~# kubectl get pod -n demo
NAME READY STATUS RESTARTS AGE
demoapp-7c58cd6bb-6rnfz 1/1 Running 0 7s
demoapp-7c58cd6bb-flmjb 1/1 Running 0 7s
demoapp-7c58cd6bb-lmvnx 1/1 Running 0 7s











文章评论