K8S集群备份-Velero

Velero官网如下:Velero。下面是Velero的官方文档介绍: Velero(原名 Heptio Ark)为您提供了备份和恢复 Kubernetes 集群资源和持久卷的工具。您可以在云提供商处或在本地运行 Velero。Velero 可让您: 备份您的集群并在丢失时恢复。 将集群资源迁移到其

Velero官网如下:Velero。下面是Velero的官方文档介绍:

Velero(原名 Heptio Ark)为您提供了备份和恢复 Kubernetes 集群资源和持久卷的工具。您可以在云提供商处或在本地运行 Velero。Velero 可让您:

  • 备份您的集群并在丢失时恢复。
  • 将集群资源迁移到其他集群。
  • 将生产集群复制到开发和测试集群。

Velero可以支持:

  • 在您的集群上运行的服务器
  • 本地运行的命令行客户端。

我们下面基于Minio作为K8S集群的备份的数据,并基于Minio作为恢复K8S集群的数据来源。

1.安装Minio对象存储服务

Minio是一个开源的对象存储服务(OSS),类似于阿里云OSS服务,兼容AWS的S3(Simple Storage Service)协议,Velero支持使用AWS的S3协议进行备份,我们可以采用Minio作为内部的OSS存储服务对K8S执行备份。

首先我们需要装一个Minio的对象存储服务,并且需要在K8S集群之外安装,需要另外找一台虚拟机安装,不能在K8S集群内安装,不能产生循环依赖,不然K8S集群挂掉了,Minio可能也挂掉了,就没有办法进行恢复,也可以使用阿里云/腾讯云的对象存储服务,我们下面基于Docker和Docker-Compose分别进行安装的方式进行介绍。

MINIO的API服务,在9000端口进行对外暴露;MINIO的控制台服务默认会随机指定端口号启动,我们指定一个端口号9001,以便我们可以方便对外访问。

1.1 基于docker命令安装Minio

基于如下的docker命令可以启动Minio服务:

docker run -d   --name minio   -p 9000:9000   -p 9001:9001  -e MINIO_ROOT_USER=admin   -e MINIO_ROOT_PASSWORD=123456   -v /etc/localtime:/etc/localtime:ro   -v /etc/timezone:/etc/timezone:ro   -v /sharedata/data/data/minio:/data   quay.io/minio/minio:latest   server /data --console-address ":9001"

我们详细介绍一下各个参数的的作用

  • 通过--name minio参数指定了启动的Docker容器名称为minio
  • 通过-p 9000:9000 -p 9001:9001指定,将容器内9000端口映射到宿主机的9000端口,容器内9001端口映射到宿主机的9001端口。(前面写宿主机端口号,后面写容器的端口号,比如容器9000映射到宿主机的19000,应该配置-p 19000:9000)
  • 通过-e MINIO_ROOT_USER=admin-e MINIO_ROOT_PASSWORD=123456指定了Minio的管理员账号和密码。
  • 通过-v /etc/localtime:/etc/localtime:ro -v /etc/timezone:/etc/timezone:ro挂载宿主机的当地时间到容器。
  • 通过-v /sharedata/data/data/minio:/data,将本地的/sharedata/data/data/minio目录挂载到容器的/data目录下。
  • 通过server /data --console-address ":9001"指定启动Minio的命令,并指定控制台Web页面的地址在9001端口启动。
  • 如果想要指定SSL(TLS)证书(生产环境强烈建议配置SSL证书,为了保证数据传输的安全),那么进行如下配置:
    • (1)配置-v /path/to/${domain}_bundle.crt:/root/.minio/certs/public.crt:ro挂载证书文件到容器。
    • (2)配置-v /path/to/{domain}.key:/root/.minio/certs/private.key:ro指定证书文件挂载到容器。

接着,我们就可以通过http://127.0.0.1:9001端口进行启动Minio的控制台页面,使用管理员账号和密码进行登录,登录后进入如下页面。

c72243124b7d92b62e48717bcce7b12b.png

1.2 基于docker-compose安装Minio

下面使用docker-compose进行安装Minio的安装,相关的配置信息和上面的docker命令一致。

version: '3.7'

services:
  minio:
    image: quay.io/minio/minio:latest
    container_name: minio
    ports:
      - "9000:9000"    # MinIO API 端口
      - "9001:9001"    # MinIO 控制台端口
    environment:
      - MINIO_ROOT_USER=admin        # 管理员用户名
      - MINIO_ROOT_PASSWORD=123456  # 管理员密码
      - MINIO_REGION=minio
      #- MINIO_BROWSER_REDIRECT_URL=https://wanna1314y.top:19000/console
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
      - /sharedata/data/data/minio:/data                 # 数据存储目录映射
    command: server /data --console-address ":9001"

如果需要指定SSL证书,可以参考如下的配置:

version: '3.7'

services:
  minio:
    image: quay.io/minio/minio:latest
    container_name: minio
    ports:
      - "9000:9000"    # MinIO API 端口
      - "9001:9001"    # MinIO 控制台端口
    environment:
      - MINIO_ROOT_USER=admin        # 管理员用户名
      - MINIO_ROOT_PASSWORD=123456  # 管理员密码
      - MINIO_REGION=minio
    volumes:
      - /path/to/{domain}_bundle.crt:/root/.minio/certs/public.crt:ro  # 证书地址
      - /path/to/{domain}.key:/root/.minio/certs/private.key:ro   # 私钥地址
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
      - /sharedata/data/data/minio:/data                 # 数据存储目录映射
    command: server /data --console-address ":9001"

接着,我们就可以通过http://127.0.0.1:9001端口进行启动Minio的控制台页面,使用管理员账号和密码进行登录,登录后进入如下页面。

c72243124b7d92b62e48717bcce7b12b.png

1.3 基于awscli命令测试Minio通过客户端连接

在安装好Minio之后,我们需要测试一下Minio能否通过API的方式进行外部访问,以便后续我们在进行K8S集群的备份时,能够顺利进行。

我们基于如下命令安装AWS的客户端工具:

# macos
sudo brew install awscli

# ubuntu
sudo apt install awscli

通过如下命令,配置aws的accessKeyId和accessKey,以及region。

aws configure

配置好accessKeyId和accessKey之后,可以使用如下的命令进行测试,可以列举出来Minio对象存储服务下的所有的Bucket桶位,如果成功列举出来则说明整个对象存储部署成功,可以用于进行K8S集群的备份和恢复。

aws s3 ls --endpoint-url http://{ip}:9000

2. 下载并安装Velero

首先,我们需要去Velero的github仓库下载对应的Velero安装包,Github的Release包的地址如下。

https://github.com/vmware-tanzu/velero/releases

找到合适的版本的Velero包,直接下载压缩包并上传到服务器,或者是使用wget等工具进行下载(需要科学上网,Github仓库国内无法直接访问)。

wget https://github.com/vmware-tanzu/velero/releases/download/v1.15.0/velero-v1.15.0-linux-amd64.tar.gz

使用如下的命令解压Velero:

tar -xvzf velero-*.tar.gz

解压之后可以使用下面的命令将该二进制文件去copy到bin目录下,方便我们可以直接访问到。我们下面的操作当中,都直接基于相对路径进行操作,不进行二进制文件的拷贝。

cp ./velero/velero /usr/local/bin/

需要说明的是,下面的操作都需要在K8S的Master节点上执行。我们使用如下的命令安转发Velero服务到当前的K8S集群:

./velero/velero install --kubeconfig /root/.kube/config --use-node-agent --default-volumes-to-fs-backup --provider aws --plugins velero/velero-plugin-for-aws:latest --bucket k8s-backup --secret-file velero-oss-auth/velero-oss-auth.txt  --use-volume-snapshots=false --namespace velero --backup-location-config region=minio,s3ForcePathStyle='true',s3Url=http://10.233.1.80:9000

# 如果无法访问dockehub, 那么可以基于类似如下的命令, 自定义镜像仓库地址
./velero/velero --kubeconfig /root/.kube/config install --use-node-agent --default-volumes-to-fs-backup --provider aws --image harbor.wanna1314y.top/velero/velero:v1.15.0 --plugins harbor.wanna1314y.top/velero/velero-plugin-for-aws:latest --bucket k8s-backup --secret-file velero-oss-auth/velero-oss-auth.txt  --use-volume-snapshots=false --namespace velero --backup-location-config region=minio,s3ForcePathStyle='true',s3Url=http://10.233.1.80:9000

我们解释一下各个参数的含义:

  • --kubeconfig /root/.kube/config指定证书和密钥的文件路径。
  • --image velero/velero:v1.15.0指定velero-server的镜像地址,Velero将会用于部署一个K8S的Deployment。如果无法访问dockerhub,请修改成为私有仓库的地址。
  • --provider aws表示基于亚马逊的AWS的S3协议提供数据的备份。
  • --plugins velero/velero-plugin-for-aws:latest指定Velero数据备份的插件,我们基于AWS S3协议的Minio进行部署,可以使用这个插件。如果无法访问dockerhub,请修改成为私有仓库的地址。
  • --bucket k8s-backup用于指定存放备份的对象存储的桶,我们这里指定为k8s-backup表明我们希望将数据备份在k8s-backup这个桶当中。
  • --secret-file velero-oss-auth/velero-oss-auth.txt用于指定AWS S3连接对象存储服务的accessKeyId和accessKey认证用户名和密码。必填!!!
  • --namespace velero用于指定Velero相关的Pod以及其他的资源会部署在velero这个Namespace下。默认就行,不用修改。
  • --backup-location-config region=minio,s3ForcePathStyle='true',s3Url=http://10.233.1.80:9000用于指定对象存储的路径,这里的s3Url是我们需要配置的对象存储服务器的地址。

对于velero-oss-auth/velero-oss-auth.txt,它的格式如下:

[default]
aws_access_key_id = ...
aws_secret_access_key = ...

如果想要进行定制化,需要K8S的yaml文件配置,可以后面加上--dry-run -o yaml参数,比如:

./velero/velero install --kubeconfig /root/.kube/config --use-node-agent --default-volumes-to-fs-backup --provider aws --plugins velero/velero-plugin-for-aws:latest --bucket k8s-backup --secret-file velero-oss-auth/velero-oss-auth.txt  --use-volume-snapshots=false --namespace velero --backup-location-config region=minio,s3ForcePathStyle='true',s3Url=http://10.233.1.80:9000 --dry-run -o yaml

使用如下的命令,我们可以查看Velero在我们当前的K8S集群上安装了哪些资源对象。

kubectl get all -n velero

3. 利用Velero创建备份

3.1 创建备份

依次执行如下两条命令,第一条命令用于生成一个时间戳的DATE环境变量,第二条命令用于创建Velero备份。

DATE=`date +%Y%m%d%H%M%S`


./velero/velero backup create k8s-backup-${DATE}  --include-namespaces=default  --kubeconfig=/root/.kube/config  --namespace=velero

我们来介绍一下各个参数的含义:

  • ./velero/velero backup create是Velero创建备份时是用到的命令。
  • k8s-backup-${DATE}是需要创建备份的名称(采用年月日时分秒格式生成)。
  • --include-namespaces=default指定要进行备份的namespace,比如--include-namespaces=default,支持配*并且默认值就是*
  • 通过--kubeconfig=/root/.kube/config指定K8S集群的证书密钥文件路径。
  • 通过--namespace=velero指定Velero的部署的Namespace,上一部分我们使用velero作为namespace,那么我们这里也需要指定为该namespace

我们下面先来创建一个测试的Deployment并挂载持久卷,给后面测试备份和恢复时使用。

apiVersion: v1
kind: Namespace
metadata:
  name: backup-test
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
  namespace: backup-test
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: nfs-storage

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-deployment
  namespace: backup-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test-app
  template:
    metadata:
      labels:
        app: test-app
    spec:
      containers:
        - name: test-container
          image: nginx:latest
          ports:
            - containerPort: 80
          volumeMounts:
            - name: test-volume
              mountPath: /usr/share/nginx/html  # 将持久卷挂载到 Nginx 的默认目录
      volumes:
        - name: test-volume
          persistentVolumeClaim:
            claimName: test-pvc  # 挂载之前创建的 PVC

---
apiVersion: v1
kind: Service
metadata:
  name: test-service
  namespace: backup-test
spec:
  selector:
    app: test-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP

我们使用如下的命令进入容器:

kubectl exec -it {pod-name} -n backup-test -- sh

# eg
kubectl exec -it test-deployment-5bf75f486c-bjd2k -n backup-test -- sh

接着我们切换到/usr/share/nginx/html,使用echo 12345 > test.txt命令当中新增一个文件,文件的内容就是简单的12345。

我们使用如下的命令去备份K8S集群中的一个namespace的资源。

DATE=`date +%Y%m%d%H%M%S`

./velero/velero backup create k8s-backup-${DATE}  --include-namespaces=backup-test  --kubeconfig=/root/.kube/config  --namespace=velero

接着命令行会告诉你创建出来的备份的名字:

Backup request "k8s-backup-20241216042112" submitted successfully.
Run `velero backup describe k8s-backup-20241216042112` or `velero backup logs k8s-backup-20241216042112` for more details.

接着等一会儿,就可以在Minio的Bucket当中找到这份备份的数据,我们可以在Minio的控制台当中查看到这部分的数据。

2184ce50575e607c078d62d06fd9178e.png

edd8911cfc1854ea6a0bdfeac6a5808c.png

到这里就说明我们K8S集群下的相关资源已经备份完成,已经备份到我们的Minio对象存储服务器,我们可以基于这个备份进行后续的恢复工作。

下面我们将刚刚测试Namespace下的资源全删掉,并借助Velero进行K8S资源的恢复。

# 删除namespace下的相关资源
kubectl delete -f test.yaml

# 进入NFS服务器, 删除该文件(因为NFS不会删除持久卷当中的内容)
rm -rf backup-test/test-pvc/test.txt 

可以基于如下的命令kubectl get backups -A去获取当前K8S集群的Velero的备份列表。

root@master01:~# kubectl get backups -A
NAMESPACE       NAME                        AGE
velero   k8s-backup-20241216041945   13h
velero   k8s-backup-20241216042112   13h
velero   k8s-backup-20241216043509   13h

对于大量的数据备份的情况,备份会比较缓慢。可以通过如下的命令,去查看这个备份的描述信息,我们可以从中查看到备份的进度情况。

kubectl describe backups ${backup-name} -n velero

输出下面的结果,其中Phase: InProgress说明还在备份过程中,通过Items Backed UpTotal Items告诉我们一共有1618个备份项,其中已经备份完成1058个备份项。

API Version:  velero.io/v1
Kind:         Backup
Metadata:
  Creation Timestamp:  2024-12-18T14:15:40Z
  Generation:          17
  Resource Version:    3310034
  UID:                 fa157293-f93a-44cc-9232-36062eecb141
Spec:
  Csi Snapshot Timeout:          10m0s
  Default Volumes To Fs Backup:  true
  Hooks:
  Included Namespaces:
    *
  Item Operation Timeout:  4h0m0s
  Metadata:
  Snapshot Move Data:  false
  Storage Location:    default
  Ttl:                 720h0m0s
Status:
  Expiration:      2025-01-17T14:15:40Z
  Format Version:  1.1.0
  Phase:           InProgress
  Progress:
    Items Backed Up:  1058
    Total Items:      1618
  Start Timestamp:    2024-12-18T14:15:40Z
  Version:            1
Events:               <none>

3.2 查看当前集群已经存在的备份信息

kubectl get backup -n velero

3.3 借助Linux脚本实现每个namespace产生一个备份

我们新建一个Shell脚本k8s-backup.sh去实现将每个namespace产生一份备份数据:

#!/bin/bash

DATE=`date +%Y%m%d%H%M%S`

EXCLUDED_NAMESPACES=("kube-system" "velero" "elk" "harbor" "kubesphere-monitoring-system" "monitoring" "pxc")
NAMESPACES=$(kubectl get namespaces -o jsonpath='{.items[*].metadata.name}')

echo $NAMESPACES

for namespace in $NAMESPACES; do
  # 检查命名空间是否在排除列表中
  if [[ " ${EXCLUDED_NAMESPACES[@]} " =~ " ${namespace} " ]]; then
    echo "Skipping excluded namespace: $namespace"
    continue
  fi

  # 创建备份
  velero backup create k8s-backup-$namespace-${DATE}  --include-namespaces=$namespace  --kubeconfig=/root/.kube/config  --namespace=velero

  echo "Backup for namespace $namespace created."
done

执行K8S备份脚本:

chmod a+x k8s-backup.sh
./k8s-backup.sh

4. 借助Velero恢复K8S

4.1 在本集群恢复

可以基于下面的命令,基于Velero进行恢复之前已经安装好的K8S集群,需要将{backup-name}替换成为真实的备份名称,比如k8s-backup-20241216042112

./velero/velero restore create --from-backup {backup-name} --wait --kubeconfig=/root/.kube/config --namespace velero

我们执行如下命令,尝试恢复K8S集群当中我们刚刚删除的资源信息。

./velero/velero restore create --from-backup k8s-backup-20241216042112 --wait --kubeconfig=/root/.kube/config --namespace velero

恢复过程中,出现了下面的问题,原因在于velero/velero-restore-helper:v1.15.0这个镜像在DockerHub我们无法下载。

Failed to pull image "velero/velero-restore-helper:v1.15.0": rpc error: code = DeadlineExceeded desc = failed to pull and unpack image "docker.io/velero/velero-restore-helper:v1.15.0": failed to resolve reference "docker.io/velero/velero-restore-helper:v1.15.0": failed to do request: Head "https://registry-1.docker.io/v2/velero/velero-restore-helper/manifests/v1.15.0": dial tcp 108.160.165.11:443: i/o timeout

既然在DockerHub我们没有办法下载,我们尝试将这个镜像,从其他机器上传过来,并基于containerd/docker进行加载到本地。

# 能访问外网的机器
docker pull velero/velero-restore-helper:v1.15.0
docker save -o velero-restore-helper.tar velero/velero-restore-helper:v1.15.0

# K8S机器
ctr images import velero-restore-helper.tar
ctr images ls | grep velero

重新执行恢复命令:

./velero/velero restore create --from-backup k8s-backup-20241216042112 --wait --kubeconfig=/root/.kube/config --namespace velero

还是拉取不到,本来在本地已经有这个镜像不应该继续拉取镜像,但是实际上还是会去进行镜像拉取,这里就很奇怪,上网查找,基本没有怎么配置这个镜像相关的资料。

后面发现,原因在于,Containerd在进行容器镜像进行加载时,需要指定namespace为k8s.io。

ctr --namespace k8s.io images import velero-restore-helper.tar
ctr --namespace k8s.io images ls | grep velero

我们尝试参照官方文档Velero Customize Restore Helper Container,新增如下的这样一个ConfigMap进行image的自定义。(还不行的话,可以尝试新增一个备份,再试试)

apiVersion: v1
kind: ConfigMap
metadata:
  # any name can be used; Velero uses the labels (below)
  # to identify it rather than the name
  name: fs-restore-action-config
  # must be in the velero namespace
  namespace: velero
  # the below labels should be used verbatim in your
  # ConfigMap.
  labels:
    # this value-less label identifies the ConfigMap as
    # config for a plugin (i.e. the built-in restore
    # item action plugin)
    velero.io/plugin-config: ""
    # this label identifies the name and kind of plugin
    # that this ConfigMap is for.
    velero.io/pod-volume-restore: RestoreItemAction
data:
  # The value for "image" can either include a tag or not;
  # if the tag is *not* included, the tag from the main Velero
  # image will automatically be used.
  image: harbor.wanna1314y.top/velero/velero-restore-helper:v1.15.0

官方文档当中有介绍,ConfigMap的名称无所谓,将会根据label标签进行匹配,主要依赖于下面的这项配置:

velero.io/pod-volume-restore: RestoreItemAction

当配置好ConfigMap之后,我们尝试重新进行恢复时,发现我们恢复的Namespace下的Pod正常启动了,并且已经Ready。

root@master01:~/k8s/k8s-backup# kubectl get all -n backup-test
NAME                                   READY   STATUS    RESTARTS   AGE
pod/test-deployment-5bf75f486c-t4njt   1/1     Running   0          2m55s

NAME                   TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/test-service   ClusterIP   10.233.6.111   <none>        80/TCP    2m55s

NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/test-deployment   1/1     1            1           2m55s

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/test-deployment-5bf75f486c   1         1         1       2m55s

我们使用如下的命令查看/usr/share/nginx/html/test.txt文件当中的内容,发现我们删除的持久卷当中的内容,也被Velero进行备份回来了!

root@master01:~/k8s/k8s-backup# kubectl exec -it test-deployment-5bf75f486c-bjd2k  -n backup-test -- cat /usr/share/nginx/html/test.txt
Defaulted container "test-container" out of: test-container, restore-wait (init)
12345

默认情况下:Velero 执行非破坏性恢复,这意味着它不会删除目标集群上的任何数据。如果备份中的资源已存在于目标集群中,Velero 将跳过该资源的恢复。

可以基于如下的命令kubectl get restores -A,查看本机的恢复历史列表。

root@master01:~# kubectl get restores -A
NAMESPACE       NAME                                       AGE
velero   k8s-backup-20241216043509-20241216044003   13h

可以基于如下的命令kubectl describe restores {restore-name} -n velero指定restore的名称去查看恢复的详情:

root@master01:~# kubectl describe restores k8s-backup-20241216043509-20241216044003 -n velero
Name:         k8s-backup-20241216043509-20241216044003
Namespace:    velero
Labels:       <none>
Annotations:  <none>
API Version:  velero.io/v1
Kind:         Restore
Metadata:
  Creation Timestamp:  2024-12-15T20:40:03Z
  Finalizers:
    restores.velero.io/external-resources-finalizer
  Generation:        6
  Resource Version:  2677777
  UID:               14427c30-53a5-4c15-9d63-d8d4b8ad4570
Spec:
  Backup Name:  k8s-backup-20241216043509
  Excluded Resources:
    nodes
    events
    events.events.k8s.io
    backups.velero.io
    restores.velero.io
    resticrepositories.velero.io
    csinodes.storage.k8s.io
    volumeattachments.storage.k8s.io
    backuprepositories.velero.io
  Hooks:
  Included Namespaces:
    *
  Item Operation Timeout:  4h0m0s
  Uploader Config:
Status:
  Completion Timestamp:  2024-12-16T00:40:05Z
  Errors:                1
  Hook Status:
  Phase:  PartiallyFailed
  Progress:
    Items Restored:  11
    Total Items:     11
  Start Timestamp:   2024-12-15T20:40:03Z
  Warnings:          1
Events:              <none>

4.2 在其他K8S集群恢复(集群资源的迁移)

我们使用如下的命令安转发Velero服务到当前的K8S集群:

./velero/velero install --kubeconfig /root/.kube/config --use-node-agent --default-volumes-to-fs-backup --provider aws --plugins velero/velero-plugin-for-aws:latest --bucket k8s-backup --secret-file velero-oss-auth/velero-oss-auth.txt  --use-volume-snapshots=false --namespace velero --backup-location-config region=minio,s3ForcePathStyle='true',s3Url=http://10.233.1.80:9000

# 如果无法访问dockehub, 那么可以基于类似如下的命令, 自定义镜像仓库地址
./velero/velero --kubeconfig /root/.kube/config install --use-node-agent --default-volumes-to-fs-backup --provider aws --image harbor.wanna1314y.top/velero/velero:v1.15.0 --plugins harbor.wanna1314y.top/velero/velero-plugin-for-aws:latest --bucket k8s-backup --secret-file velero-oss-auth/velero-oss-auth.txt  --use-volume-snapshots=false --namespace velero --backup-location-config region=minio,s3ForcePathStyle='true',s3Url=http://10.233.1.80:9000

接着,我们可以使用kubectl get backup -n velero命令,查看Minio当中的其他集群在之前已经产生备份的数据。在其他K8S集群产生的备份,在当前集群安装之后也可以自动构建出来。

$ kubectl get backup -n velero
NAME                                                         AGE
k8s-prod-backup-default-20250112200008                       61m
k8s-prod-backup-halo-prod-20250112200008                     61m

接着需要去创建如下的ConfigMap用于恢复时是用到的工具镜像(如果velero-restore-helper镜像无法被正常下载的话):

apiVersion: v1
kind: ConfigMap
metadata:
  # any name can be used; Velero uses the labels (below)
  # to identify it rather than the name
  name: fs-restore-action-config
  # must be in the velero namespace
  namespace: velero
  # the below labels should be used verbatim in your
  # ConfigMap.
  labels:
    # this value-less label identifies the ConfigMap as
    # config for a plugin (i.e. the built-in restore
    # item action plugin)
    velero.io/plugin-config: ""
    # this label identifies the name and kind of plugin
    # that this ConfigMap is for.
    velero.io/pod-volume-restore: RestoreItemAction
data:
  # The value for "image" can either include a tag or not;
  # if the tag is *not* included, the tag from the main Velero
  # image will automatically be used.
  image: harbor.wanna1314y.top/velero/velero-restore-helper:v1.15.0

如果恢复的namespace涉及到存储类,那么需要先创建StorageClass再进行恢复,不然恢复过程中会出现问题,例如使用NFS的存储类:

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: k8s-nfs-storage
provisioner: nfs-provisioner
parameters:
  archiveOnDelete: 'false'
  pathPattern: '${.PVC.namespace}/${.PVC.name}'
reclaimPolicy: Delete
volumeBindingMode: Immediate

根据可用的Velero备份,使用velero restore create命令,创建一个K8S集群的恢复:

sudo ./velero restore create --from-backup k8s-prod-backup-halo-prod-20250112200008  --wait --kubeconfig=/root/.kube/config --namespace velero

接着,我们查看这个namespace下Pod信息,发现已经有pod正在处于初始化当中。

wanna@node1:~/velero-v1.15.0-linux-amd64$ kubectl get pod -n halo-prod
NAME                             READY   STATUS            RESTARTS   AGE
halo-prod-dep-8476f6b6cb-pc2rc   0/1     PodInitializing   0          5m37s

过一会儿,如果没什么问题的话,Pod就会处于Running状态,说明恢复完成。

wanna@node1:/sharedata/nfs/halo-prod/halo-prod-pvc/.halo2/plugins$ kubectl get pod -n halo-prod
NAME                             READY   STATUS    RESTARTS   AGE
halo-prod-dep-68d8cbdf7f-dpfn9   1/1     Running   0          37m

5. 卸载Velero

依次执行如下的命令,即可删除已经K8S集群当中安装好的Velero相关的资源。

# 官方推荐使用, 会删除所有通过velero install安装的资源对象
velero uninstall

# 删除namespace和rbac
kubectl delete namespace/velero clusterrolebinding/velero

# 删除velero的自定义crd
kubectl delete crds -l component=velero
Comment