侧边栏壁纸
博主头像
青菜-halo2 博主等级

行动起来,活在当下

  • 累计撰写 74 篇文章
  • 累计创建 6 个标签
  • 累计收到 7 条评论

目 录CONTENT

文章目录

k8s备份-velero

Administrator
2025-02-08 / 0 评论 / 0 点赞 / 40 阅读 / 0 字

[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 支持恢复挂钩,这是可以在恢复过程期间或之后执行的自定义操作。恢复钩子有两种:

  1. InitContainer Restore Hooks:这些会将 init 容器添加到恢复的 Pod 中,以便在恢复的 Pod 的应用程序容器启动之前执行任何必要的设置。

  2. 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

# 这样清空以后,下一次在对名称空间备份时,会先初始化创建一个对应名称空间,新的backuprepositories

9、常用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 

0

评论区