本次使用velero1.7.1.对接备份存储为minio

介绍

velero 是一款云原生时代的灾难恢复和迁移工具,采用 Go 语言编写,并在 github 上进行了开源,利用 velero 用户可以安全的备份、恢复和迁移 Kubernetes 集群资源和持久卷。

开源地址:https://github.com/vmware-tanzu/velero 官方文档:https://velero.io/docs

  • Velero 是一个云原生的灾难恢复和迁移工具, 采用 Go 语言编写,可以安全的备份、恢复和迁移Kubernetes集群资源和持久卷。
  • 使用velero可以对集群进行备份和恢复,降低集群DR造成的影响。其基本原理就是将集群的数据备份到对象存储中,在恢复的时候将数据从对象存储中拉取下来。
  • 除了灾备之外velero还能做资源移转,支持把容器应用从一个集群迁移到另一个集群。

在kubernetes的备份体系当中,etcd通常被作为主要的备份手段。与 Etcd 备份相比,直接备份 `Etcd` 是将集群的全部资源备份起来。而 `Velero` 可以对 `Kubernetes` 集群内对象级别进行备份。除了对 `Kubernetes` 集群进行整体备份外,`Velero` 还可以通过对 `Type`、`Namespace`、`Label` 等对象进行分类备份或者恢复。

组件

Velero 组件一共分两部分,分别是服务端和客户端。

  • 服务端:运行在你 Kubernetes 的集群中
  • 客户端:是一些运行在本地的命令行的工具,需要已配置好 kubectl 及集群 kubeconfig 的机器上

流程

  1. velero客户端调用kubernetes API Server创建backup任务
  2. Backup控制器基于watch机制通过Api Server获取到备份任务
  3. Backup控制器开始执行备份动作,会通过请求Api Server获取到需要备份的数据
  4. Backup 控制器将获取到的数据备份到指定的对象存储server端

云计算-使用velero备份还原k8s集群_对象存储

存储后端

Velero支持两种关于后端存储的CRD,分别是BackupStorageLocation和VolumeSnapshotLocation。

  • BackupStorageLocation

主要用来定义 Kubernetes 集群资源的数据存放位置,也就是集群对象数据,不是 PVC 的数据。主要支持的后端存储是 S3 兼容的存储,比如:Mino 和阿里云 OSS 等。

  • VolumeSnapshotLocation

主要用来给 PV 做快照,需要云提供商提供插件。阿里云已经提供了插件,这个需要使用 CSI 等存储机制。

配置minio

Velero支持很多种存储插件,可查看:https://velero.io/docs/v1.10/supported-providers/获取插件信息,我们这里使用minio作为S3兼容的对象存储提供程序。您也可以在任意地方部署Minio对象存储,只需要保证K8S集群可以访问到即可。

---
apiVersion: v1
kind: Service
metadata:
  name: minio
  namespace: velero
  labels:
    app: minio
spec:
  selector:
    app: minio
  ports:
  - name: api
    port: 9000
    protocol: TCP
  - name: console
    port: 9001
    protocol: TCP
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: minio
  namespace: velero
  labels:
    app: minio
spec:
  replicas: 1
  serviceName: minio
  selector:
    matchLabels:
      app: minio
  template:
    metadata:
      labels:
        app: minio
    spec:
      containers:
      - name: minio
        image: docker.io/bitnami/minio:2023.3.22
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9000
          name: api
          protocol: TCP
        - containerPort: 9001
          name: console
          protocol: TCP
        env:
        - name: MINIO_ROOT_USER
          value: "minio"
        - name: MINIO_ROOT_PASSWORD
          value: "minio123"
        - name: MINIO_DEFAULT_BUCKETS
          value: "velero"
        volumeMounts:
        - name: data
          mountPath: /data
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: [ "ReadWriteOnce" ]
        resources:
          requests:
            storage: 50Gi

配置完成后,如下所示

#创建minio
kubectl apply -f minio.yaml

云计算-使用velero备份还原k8s集群_nginx_02

安装velero

安装

wget https://github.com/vmware-tanzu/velero/releases/download/v1.7.1/velero-v1.7.1-linux-amd64.tar.gz
tar -xf velero-v1.7.1-linux-amd64.tar.gz
cp velero-v1.7.1-linux-amd64/velero /usr/bin/

#验证
velero version
==============
Client:
        Version: v1.7.1
        Git commit: 4729274d07eae7e788233d5c995d7f45f40c9c61
Server:
        Version: v1.7.0
==============

创建密钥

$ cat > credentials-velero <<EOF
[default]
aws_access_key_id = minio
aws_secret_access_key = minio123
EOF

安装velero到k8s集群

velero install    \
  --provider aws   \
  --bucket velero   \
  --prefix k8s-bak \
  --image velero/velero:v1.7.0  \
  --plugins velero/velero-plugin-for-aws:v1.3.0  \
  --namespace velero  \
  --secret-file ./credentials-velero  \
  --use-volume-snapshots=false \
  --use-restic \
  --backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://192.168.233.3:30873
  
  # 可使用如下命令查看运行日志
kubectl logs deployment/velero -n velero
 
# 查看velero创建的api对象
kubectl api-versions | grep velero
velero.io/v1
 
# 查看备份位置
velero backup-location get

=========
NAME      PROVIDER   BUCKET/PREFIX    PHASE       LAST VALIDATED                  ACCESS MODE   DEFAULT
default   aws        velero/k8s-bak   Available   2024-06-13 17:05:12 +0800 CST   ReadWrite     true
=========

配置选项说明

  • --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:指定对象存储地址信息;

卸载

#如果您想从集群中完全卸载Velero,则以下命令将删除由velero install创建的所有资源:
kubectl delete namespace/velero clusterrolebinding/velero
kubectl delete crds -l component=velero

备份

备份命令: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: 指定快照的位置,也就是哪一个公有云驱动

备份

elero backup create ops-bak --include-namespaces ops --default-volumes-to-restic 
==========
Backup request "default" submitted successfully.
Run `velero backup describe default` or `velero backup logs default` for more details.
=============

  • --include-namespaces:指定命名空间
  • --selector:标签选择器,如app=nginx

查看备份信息

$ velero backup get
 
# 查看备份详细信息
$ velero backup describe 
 
# 查看备份日志
$ velero backup logs nginx-backup

云计算-使用velero备份还原k8s集群_对象存储_03

进入minio查看备份内容

云计算-使用velero备份还原k8s集群_nginx_04

定时备份

更多cron示例请参考:cron package’s documentation

# 使用cron表达式备份
$ velero schedule create nginx-daily --schedule="0 1 * * *" --include-namespaces nginx-example
 
# 使用一些非标准的速记 cron 表达式
$ velero schedule create nginx-daily --schedule="@daily" --include-namespaces nginx-example
 
# 手动触发定时任务
$ velero backup create --from-schedule nginx-daily

注意事项

  • 在velero备份的时候,备份过程中创建的对象是不会被备份的。
  • velero restore 恢复不会覆盖已有的资源,只恢复当前集群中不存在的资源。已有的资源不会回滚到之前的版本,如需要回滚,需在restore之前提前删除现有的资源。
  • 可以将velero作为一个cronjob来运行,定期备份数据。

恢复

模拟故障

#删除ops空间和里面的资源
kubectl delete ns ops

云计算-使用velero备份还原k8s集群_nginx_05

恢复

使用velero命令行工具执行恢复操作,相关命令参数说明如下:

--exclude-namespaces stringArray                  Namespaces to exclude from the restore.
--exclude-resources stringArray                   Resources to exclude from the restore, formatted as resource.group, such as storageclasses.storage.k8s.io.
--from-backup string                              Backup to restore from
--from-schedule string                            Schedule to restore from
--include-cluster-resources optionalBool[=true]   Include cluster-scoped resources in the restore.
--include-namespaces stringArray                  Namespaces to include in the restore (use '*' for all namespaces) (default *)
--include-resources stringArray                   Resources to include in the restore, formatted as resource.group, such as storageclasses.storage.k8s.io (use '*' for all resources).  
--labels mapStringString                          Labels to apply to the restore.
--namespace-mappings mapStringString              Namespace mappings from name in the backup to desired restored name in the form src1:dst1,src2:dst2,...
--preserve-nodeports optionalBool[=true]          Whether to preserve nodeports of Services when restoring.
# 是否连同持久存储数据一起恢复
--restore-volumes optionalBool[=true]             Whether to restore volumes from snapshots.
-l, --selector labelSelector                          Only restore resources matching this label selector. (default <none>)

进行恢复

[root@node1 velero]# velero backup get
NAME      STATUS      ERRORS   WARNINGS   CREATED                         EXPIRES   STORAGE LOCATION   SELECTOR
ops-bak   Completed   0        0          2024-06-13 16:38:50 +0800 CST   29d       default            <none>
[root@node1 velero]# velero restore create --from-backup ops-bak
Restore request "ops-bak-20240613172336" submitted successfully.
Run `velero restore describe ops-bak-20240613172336` or `velero restore logs ops-bak-20240613172336` for more details.
[root@node1 velero]#

云计算-使用velero备份还原k8s集群_数据_06

检查恢复的资源

[root@node1 velero]#  velero restore get
NAME                     BACKUP    STATUS      STARTED                         COMPLETED                       ERRORS   WARNINGS   CREATED                         SELECTOR
ops-bak-20240613172336   ops-bak   Completed   2024-06-13 17:23:36 +0800 CST   2024-06-13 17:23:37 +0800 CST   0        0          2024-06-13 17:23:36 +0800 CST   <none>

#查看详细信息
[root@node1 velero]#velero restore describe ops-bak-20240613172336
===========
Name:         ops-bak-20240613172336
Namespace:    velero
Labels:       <none>
Annotations:  <none>

Phase:                       Completed
Total items to be restored:  17
Items restored:              17

Started:    2024-06-13 17:23:36 +0800 CST
Completed:  2024-06-13 17:23:37 +0800 CST

Backup:  ops-bak

Namespaces:
  Included:  all namespaces found in the backup
  Excluded:  <none>

Resources:
  Included:        *
  Excluded:        nodes, events, events.events.k8s.io, backups.velero.io, restores.velero.io, resticrepositories.velero.io
  Cluster-scoped:  auto

Namespace mappings:  <none>

Label selector:  <none>

Restore PVs:  auto

Preserve Service NodePorts:  auto
==============

#检查恢复的资源
[root@node1 velero]# kubectl get all -n ops
================
NAME                         READY   STATUS    RESTARTS   AGE
pod/mysql-9b877f47-hcjp4     1/1     Running   0          13m
pod/myweb-76c98cd497-576tn   1/1     Running   0          13m
pod/myweb-76c98cd497-h4zvw   1/1     Running   0          13m

NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/mysql   ClusterIP   10.233.45.112   <none>        3306/TCP         13m
service/myweb   NodePort    10.233.21.217   <none>        8080:30001/TCP   13m

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mysql   1/1     1            1           13m
deployment.apps/myweb   2/2     2            2           13m

NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/mysql-9b877f47     1         1         1       13m
replicaset.apps/myweb-76c98cd497   2         2         2       13m
========