[TOC]
一、安装 minio 服务
# 安装 minio
$ docker run --name minio -p 9000:9000 -p 9999:9999 -d --restart=always -e "MINIO_ROOT_USER=admin" -e "MINIO_ROOT_PASSWORD=12345678" -v /data/minio/data:/data minio/minio:RELEASE.2022-04-12T06-55-35Z server /data --console-address '0.0.0.0:9999'
==注意:minio安装以后,需要在浏览器中打开,并创建一个名为 velero 的桶==
二、初始化 velero
https://github.com/vmware-tanzu/velero/releases/tag/v1.13.2 安装 velero client,解压放置 /usr/local/bin
$ cat /data/velero/velero-auth.txt
[default]
aws_access_key_id = admin
aws_secret_access_key = 12345678
$ velero --kubeconfig /root/.kube/config install --use-node-agent --default-volumes-to-fs-backup --provider aws --plugins velero/velero-plugin-for-aws:latest --bucket velero --secret-file /data/velero/velero-auth.txt --use-volume-snapshots=false --namespace velero-system --backup-location-config region=minio,s3ForcePathStyle=‘true’,s3Url=http://192.168.66.14:9000不支持 hostPath 卷,需要讲 s3Url 替换为 minio的地址$ kubectl get BackupStorageLocation -n velero-system -o yaml
三、备份还原数据
1、实验演示
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
storageClassName: nfs-client
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: wangyanglinux/myapp:v1.0
volumeMounts:
- name: my-persistent-storage
mountPath: /usr/local/nginx/html
volumes:
- name: my-persistent-storage
persistentVolumeClaim:
claimName: my-pvc$ DATE=`date +%Y%m%d%H%M%S`
$ velero backup create default-backup-${DATE} --include-namespaces default --kubeconfig=/root/.kube/config --namespace velero-system
# --ttl 24h0m0s 如果未指定,将应用 30 天的默认 TTL 值
containers: - args: - server - --features= - --default-volumes-to-fs-backup=true - --uploader-type=kopia
默认情况下,Velero 执行非破坏性恢复,这意味着它不会删除目标集群上的任何数据。如果备份中的资源已存在于目标集群中,Velero 将跳过该资源
$ velero restore create --from-backup default-bakcup-20240422111959 --wait --kubeconfig=/root/.kube/config --namespace velero-system
2、常用命令
a、为与标签选择器匹配的任何对象创建备份app=nginx
$ velero backup create nginx-backup --selector app=nginx
b、备份除与标签匹配的对象之外的backup=ignore所有对象
$ velero backup create nginx-backup --selector 'backup notin (ignore)'
c、定时备份数据
$ velero schedule create schedule-backup --schedule="* * * * *" --include-namespaces=default --default-volumes-to-fs-backup
$ velero schedule create nginx-daily --schedule="@daily" --selector app=nginx
四、卸载 Velero
$ kubectl delete namespace/velero clusterrolebinding/velero
$ kubectl delete crds -l component=velero
五、补充
1、常用命令
# 备份存储库是否存在并且准备好
$ velero repo get
Velero 备份/恢复中是否存在任何错误$ velero backup describe BACKUP_NAME
$ velero backup logs BACKUP_NAME
$ velero restore describe RESTORE_NAME
$ velero restore logs RESTORE_NAMEPod 卷备份/恢复的状态如何$ kubectl -n velero get podvolumebackups -l velero.io/backup-name=BACKUP_NAME -o yaml
$ kubectl -n velero get podvolumerestores -l velero.io/restore-name=RESTORE_NAME -o yaml
2、排除固定的卷至 FSB
apiVersion: v1
kind: Pod
metadata:
name: app1
namespace: sample
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-webserver
volumeMounts:
- name: pvc1-vm
mountPath: /volume-1
- name: pvc2-vm
mountPath: /volume-2
volumes:
- name: pvc1-vm
persistentVolumeClaim:
claimName: pvc1
- name: pvc2-vm
claimName: pvc2
$ kubectl -n sample annotate pod/app1 backup.velero.io/backup-volumes-excludes=pvc1-vm
$ velero backup create BACKUP_NAME --default-volumes-to-fs-backup OTHER_OPTIONS
3、安全的还原
$ kubectl patch backupstoragelocation default --namespace velero-system --type merge --patch '{"spec":{"accessMode":"ReadOnly"}}'
$ kubectl patch backupstoragelocation default --namespace velero-system --type merge --patch ‘{"spec":{"accessMode":"ReadWrite"}}’
4、资源过滤
a、–include-namespaces
# 备份命名空间及其对象
$ velero backup create <backup-name> --include-namespaces <namespace>
恢复两个命名空间及其对象$ velero restore create <backup-name> --include-namespaces <namespace1>,<namespace2>
b、–include-resources
# 备份集群中的所有 deployment
$ velero backup create <backup-name> --include-resources deployments
恢复集群中的所有 deployment 和 configmap$ velero restore create <backup-name> --include-resources deployments,configmaps备份指定命名空间中的 deployment$ velero backup create <backup-name> --include-resources deployments --include-namespaces <namespace>
c、–include-cluster-resources
# 备份整个集群,包括集群范围的资源
$ velero backup create <backup-name>
仅恢复集群中的命名空间资源$ velero restore create <backup-name> --include-cluster-resources=false备份命名空间并包含集群范围的资源$ velero backup create <backup-name> --include-namespaces <namespace> --include-cluster-resources=true
d、–selector,该选项不能与 --selector 一起使用
# 包含与标签选择器匹配的资源
$ velero backup create <backup-name> --selector <key>=<value>
包含与选择器不匹配的资源$ velero backup create <backup-name> --selector "<key> notin (<value>)"
e、–or-selector
# 包含与任一标签选择器匹配的资源,foo=bar 或者 baz=qux
$ velero backup create backup1 --or-selector "foo=bar or baz=qux"
包括标记为 environment=production 或 env=prod 或 env=production 的资源 environment=prod$ velero restore create restore-prod --from-backup=prod-backup --or-selector "env in (prod,production) or environment in (prod, production)"
f、–include-cluster-scoped-resources
# 备份集群中的所有 StorageClasses 和 ClusterRoles
$ velero backup create <backup-name> --include-cluster-scoped-resources="storageclasses,clusterroles"
备份集群中所有集群范围的资源$ velero backup create <backup-name> --include-cluster-scoped-resources="*"
g、–include-namespace-scoped-resources,格式为 resources.group
# 备份集群中的所有 Deployment 和 ConfigMap
$ velero backup create <backup-name> --include-namespace-scoped-resources="deployments.apps,configmaps"
备份集群中所有命名空间资源$ velero backup create <backup-name> --include-namespace-scoped-resources="*"
h、–exclude-namespaces
# 从集群备份中排除 kube-system
$ velero backup create <backup-name> --exclude-namespaces kube-system
在恢复期间排除两个命名空间$ velero restore create <backup-name> --exclude-namespaces <namespace1>,<namespace2>
i、–exclude-resources
# 从备份中排除 secrets
$ velero backup create <backup-name> --exclude-resources secrets
排除 secret 和 rolebindings$ velero backup create <backup-name> --exclude-resources secrets,rolebindings
j、velero.io/exclude-from-backup=true
具有该标签的资源velero.io/exclude-from-backup=true不会包含在备份中,即使它包含匹配的选择器标签也是如此
k、–exclude-cluster-scoped-resources
# 从备份中排除 StorageClasses 和 ClusterRoles
$ velero backup create <backup-name> --exclude-cluster-scoped-resources="storageclasses,clusterroles"
从备份中排除所有集群范围的资源$ velero backup create <backup-name> --exclude-cluster-scoped-resources="*"
l、–exclude-namespace-scoped-resources,格式为 resources.group
# 从备份中排除所有 Deployment 和 ConfigMap
$ velero backup create <backup-name> --exclude-namespace-scoped-resources="deployments.apps,configmaps"
从备份中排除所有命名空间资源$ velero backup create <backup-name> --exclude-namespace-scoped-resources="*"
i、Velero 提供资源策略来过滤资源以进行备份或恢复。目前仅支持通过资源策略跳过备份卷
① 创建资源策略配置映射
用户需要从定义资源策略的 YAML 文件在 Velero 安装命名空间中创建一个配置映射。创建命令如下所示:
$ kubectl create cm <configmap-name> --from-file <yaml-file> -n velero
② 创建对已定义资源策略的备份引用
$ velero backup create --resource-policies-configmap <configmap-name>
③ YAML 模板
# currently only supports v1 version
version: v1
volumePolicies:
# each policy consists of a list of conditions and an action
# we could have lots of policies, but if the resource matched the first policy, the latters will be ignored
# each key in the object is one condition, and one policy will apply to resources that meet ALL conditions
# NOTE: capacity or storageClass is suited for [Persistent Volumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes), and pod [Volume](https://kubernetes.io/docs/concepts/storage/volumes) not support it.
- conditions:
# capacity condition matches the volumes whose capacity falls into the range
capacity: "10,100Gi"
# pv matches specific csi driver
csi:
driver: aws.ebs.csi.driver
# pv matches one of the storage class list
storageClass:
- gp2
- standard
action:
type: skip
- conditions:
capacity: "0,100Gi"
# nfs volume source with specific server and path (nfs could be empty or only config server or path)
nfs:
server: 192.168.200.90
path: /mnt/data
action:
type: skip
- conditions:
nfs:
server: 192.168.200.90
action:
type: skip
- conditions:
# nfs could be empty which matches any nfs volume source
nfs: {}
action:
type: skip
- conditions:
# csi could be empty which matches any csi volume source
csi: {}
action:
type: skip
- conditions:
volumeTypes:
- emptyDir
- downwardAPI
- configmap
- cinder
action:
type: skip
5、备份参考
a、从备份中排除特定项目
$ kubectl label -n <ITEM_NAMESPACE> <RESOURCE>/<NAME> velero.io/exclude-from-backup=true
b、并行文件上传
$ velero backup create <BACKUP_NAME> --include-namespaces <NAMESPACE> --parallel-files-upload <NUM> --wait
c、指定特定种类资源的备份顺序
$ velero backup create backupName --include-cluster-resources=true --ordered-resources 'pods=ns1/pod1,ns1/pod2;persistentvolumes=pv4,pv8' --include-namespaces=ns1
$ velero backup create backupName --ordered-resources ‘statefulsets=ns1/sts1,ns1/sts0’ --include-namespaces=ns1
6、恢复钩子
Velero 支持恢复挂钩,这是可以在恢复过程期间或之后执行的自定义操作。恢复钩子有两种:
InitContainer Restore Hooks:这些会将 init 容器添加到恢复的 Pod 中,以便在恢复的 Pod 的应用程序容器启动之前执行任何必要的设置。
Exec Restore Hooks:这些可用于在恢复的 Kubernetes Pod 的容器中执行自定义命令或脚本。
a、InitContainer 钩子
在 pod 恢复之前,使用InitContainer钩子将 init 容器添加到 pod 中。您可以使用这些 init 容器来运行 Pod 从备份状态恢复运行所需的任何设置。恢复钩子添加的 InitContainer 将是podSpec恢复后的 pod 中的第一个 init 容器。如果 Pod 具有使用文件系统备份备份的卷,则恢复钩子 InitContainer 将添加在 InitContainer 之后restore-wait。
① 在注释中指定恢复钩子
init.hook.restore.velero.io/container-image要添加的init容器的容器镜像。选修的。
init.hook.restore.velero.io/container-name正在添加的初始化容器的名称。选修的。
init.hook.restore.velero.io/command这是
ENTRYPOINT要添加的初始化容器。此命令不在 shell 内执行,ENTRYPOINT如果未提供,则使用容器映像。如果需要 shell 来运行命令,请/bin/sh在命令开头包含容器支持的 shell 命令,例如 。如果需要多个参数,请将命令指定为 JSON 数组,例如["/usr/bin/uname", "-a"]
② 在恢复规范中指定钩子
apiVersion: velero.io/v1
kind: Restore
metadata:
name: r2
namespace: velero
spec:
backupName: b2
excludedResources:
...
includedNamespaces:
- '*'
hooks:
resources:
- name: restore-hook-1
includedNamespaces:
- app
postHooks:
- init:
initContainers:
- name: restore-hook-init1
image: alpine:latest
volumeMounts:
- mountPath: /restores/pvc1-vm
name: pvc1-vm
command:
- /bin/ash
- -c
- echo -n "FOOBARBAZ" >> /restores/pvc1-vm/foobarbaz
- name: restore-hook-init2
image: alpine:latest
volumeMounts:
- mountPath: /restores/pvc2-vm
name: pvc2-vm
command:
- /bin/ash
- -c
- echo -n "DEADFEED" >> /restores/pvc2-vm/deadfeed
b、ExecRestore 钩子
① 在注释中指定钩子
post.hook.restore.velero.io/container
# 将执行挂钩的容器名称。默认为第一个容器。选修的。
post.hook.restore.velero.io/command
# 将在容器中执行的命令。默认情况下,该命令不在 shell 内执行。如果需要 shell 来运行命令,请/bin/sh在命令开头包含容器支持的 shell 命令,例如 。如果需要多个参数,请将命令指定为 JSON 数组,例如["/usr/bin/uname", "-a"].请参阅 Exec Restore Hooks As Pod 注释示例。选修的。
post.hook.restore.velero.io/on-error
# 如何处理执行失败。有效值为Fail和Continue。默认为Continue.使用模式时Continue,仅记录执行失败。使用Fail模式,任何 pod 中的任何容器中都不会再执行任何恢复钩子,并且恢复的状态将为PartiallyFailed。选修的。
post.hook.restore.velero.io/exec-timeout
# 执行开始后等待多长时间。默认值为 30 秒。选修的。
post.hook.restore.velero.io/wait-timeout
# 等待容器准备好需要多长时间。这应该足够长,以便容器启动以及同一容器中的任何前面的钩子完成。当容器恢复时,等待超时开始,并且可能需要时间来拉取映像和挂载卷。如果未设置,恢复将无限期等待。选修的。
post.hook.restore.velero.io/wait-for-ready
# 布尔值的字符串表示形式,确保在底层容器完全Ready时启动命令 。请谨慎使用,因为如果 pod 中只有一个恢复钩子包含WaitForReady“true”标志,则该 pod 的所有其他钩子执行,无论其来源(Backup或RestoreCRD)如何,也将等待Ready状态。除“true”之外的任何值都将被视为“false”。默认为 false。选修的。
② 在恢复规范中指定钩子
apiVersion: velero.io/v1
kind: Restore
metadata:
name: r2
namespace: velero
spec:
backupName: b2
excludedResources:
...
includedNamespaces:
- '*'
hooks:
resources:
- name: restore-hook-1
includedNamespaces:
- app
postHooks:
- exec:
execTimeout: 1m
waitTimeout: 5m
onError: Fail
container: postgres
command:
- /bin/bash
- '-c'
- 'while ! pg_isready; do sleep 1; done'
- exec:
container: postgres
waitTimeout: 6m
execTimeout: 1m
command:
- /bin/bash
- '-c'
- 'psql < /backup/backup.sql'
- exec:
container: sidecar
command:
- /bin/bash
- '-c'
- 'date > /start'
7、设置节点代理的并发
# node-agent-configs.json
{
"loadConcurrency": {
"globalConfig": 2,
"perNodeConfig": [
{
"nodeSelector": {
"matchLabels": {
"kubernetes.io/hostname": "node1"
}
},
"number": 3
},
{
"nodeSelector": {
"matchLabels": {
"beta.kubernetes.io/instance-type": "Standard_B4ms"
}
},
"number": 5
}
]
}
}
$ kubectl create cm node-agent-configs -n velero --from-file=<json file name>
8、删除对一个名字空间的所有备份
# 先删除所有的关于名称空间的backup
velero backup delete -n velero-system monitor-sa-backup-20250610162335
# 列出所有repo
velero repo get -n velero-system
NAME STATUS LAST MAINTENANCE
blog-default-kopia-dt656 Ready 2025-06-11 09:29:27 +0800 CST
docsify-default-kopia-65nmw Ready 2025-06-11 09:14:27 +0800 CST
halo2-default-kopia-r85x9 Ready 2025-06-11 09:39:27 +0800 CST
monitor-sa-default-kopia-b2nbk Ready 2025-06-11 09:24:28 +0800 CST
# 删除backuprepositories
kubectl delete backuprepositories.velero.io -n velero-system monitor-sa-default-kopia-b2nbk
# 这样清空以后,下一次在对名称空间备份时,会先初始化创建一个对应名称空间,新的backuprepositories9、常用backup、restore操作
# 获取backup备份
[root@k8s-master01 /root]# velero backup get -n velero-system |grep jump
jump-backup-20250801020002 Completed 0 0 2025-08-01 02:00:26 +0800 CST 3d default <none>
jump-backup-20250731020004 Completed 0 0 2025-07-31 02:00:28 +0800 CST 2d default <none>
jump-backup-20250730020003 Completed 0 0 2025-07-30 02:00:30 +0800 CST 1d default <none>
jump-backup-20250729020002 Completed 0 0 2025-07-29 02:01:05 +0800 CST 1h default <none>
# 恢复备份
[root@k8s-master01 /root]# velero restore create -n velero-system --from-backup jump-backup-20250801020002
# 删除备份
[root@k8s-master01 /root]# velero backup delete -n velero-system jump-backup-20250729020002
# 查看恢复任务
[root@k8s-master01 /root]# velero restore get -n velero-system
NAME BACKUP STATUS STARTED COMPLETED ERRORS WARNINGS CREATED SELECTOR
jump-backup-20250729020002-20250803000659 jump-backup-20250729020002 Completed 2025-08-03 00:06:59 +0800 CST 2025-08-03 00:08:13 +0800 CST 0 21 2025-08-03 00:06:59 +0800 CST <none>
#################
# 使用kubectl实现
# 获取backup备份
[root@k8s-master01 /root]# kubectl get backup -n velero-system |grep jump
jump-backup-20250729020002 4d22h
jump-backup-20250730020003 3d22h
# 查看恢复任务
[root@k8s-master01 /root]# kubectl get restores.velero.io -n velero-system
NAME AGE
jump-backup-20250729020002-20250803000659 15m
jump-backup-20250801020002-20250802235827 24m
# 删除backup备份
[root@k8s-master01 /root]# kubectl get backup -n velero-system jump-backup-20250729020002
评论区