乐趣区

关于kubernetes:详解kubernetes备份恢复利器-Velero-深入了解Carina系列第三期

Carina 是由博云主导并发动的云原生本地存储我的项目(GitHub 地址为:https://github.com/carina-io/…),目前曾经进入 CNCF 全景图。

Carina 能够为云原生环境中的有状态利用提供 高性能 免运维 本地存储解决方案,具备存储卷生命周期治理、LVM/RAW 盘供给、智能调度、RAID 治理、主动分层等能力,旨在为云原生有状态服务提供极低提早、免运维、懂数据库的数据存储系统。Carina 作为博云容器云平台的组件之一,曾经在多个金融机构的生产环境中稳固运行多年。

传统的数据备份计划次要有两种,一种是利用存储数据的服务端实现基于快照的备份,另一种是在每台指标服务器上部署专有备份 agent 并指定备份数据目录,定期把数据复制到内部存储上。这两种形式的备份机制绝对固化,在云原生时代无奈适应容器化后的弹性、池化等部署场景。

以云原生存储插件 Carina 为例,数据库等数据敏感场景中每个数据库集群包含多个计算实例,实例可能在集群内任意漂移并实现主动故障复原。传统数据备份形式在数据库集群疾速扩缩容、跨节点漂移等场景下无奈主动追随计算实例迁徙从而导致数据备份生效,因而一款贴合 k8s 容器场景的备份工具就非常重要。

Kubernetes 备份复原利器:velero

Velero 是一款云原生时代的劫难复原和迁徙工具,采纳 Go 语言编写,并在 github 上进行了开源,开源地址为:https://github.com/vmware-tan…。Velero 源于西班牙语,意思为帆船,十分合乎 Kubernetes 社区的命名格调。

利用 velero 用户能够平安的备份、复原和迁徙 Kubernetes 集群资源和长久卷。它的基本原理就是将集群的数据,例如集群资源和长久化数据卷备份到对象存储中,在复原的时候将数据从对象存储中拉取下来。除了灾备之外它还能做资源移转,反对把容器利用从一个集群迁徙到另一个集群,这也是 velero 一个十分胜利的应用场景。

Velero 次要包含两个外围组件,别离为服务端和客户端。服务端运行在具体的 Kubernetes 集群中,客户端是运行在本地的命令行工具,只有配置好 kubectl 及 kubeconfig 即可应用,非常简单。

Velero 基于其实现的 kubernetes 资源备份能力,能够轻松实现 Kubernetes 集群的数据备份和复原、复制 kubernetes 集群资源到其余 kubernetes 集群或者疾速复制生产环境到测试环境等性能。

在资源备份方面,velero 反对将数据备份到泛滥的云存储中,例如 AWS S3 或 S3 兼容的存储系统、Azure Blob、Google Cloud 存储、Aliyun OSS 等。与备份整个 kubernetes 的数据存储引擎 etcd 相比,velero 的管制更加细化,能够对 Kubernetes 集群内对象级别进行备份,还能够通过对 Type、Namespace、Label 等对象进行分类备份或者复原。

Velero 工作流程

以外围的数据备份为例,当执行 velero backup create my-backup 时:

  • Velero 客户端首先调用 Kubernetes API 服务器以创立 Backup 对象;
  • BackupController 将收到告诉有新的 Backup 对象被创立并执行验证;
  • BackupController 开始备份过程,它通过查问 API 服务器以获取资源来收集数据以进行备份;
  • BackupController 将调用对象存储服务,例如,AWS S3 - 上传备份文件。默认状况下,velero backup create反对任何长久卷的磁盘快照,能够通过指定其余标记来调整快照,运行 velero backup create --help 能够查看可用的标记,也能够应用 --snapshot-volumes=false 选项禁用快照。

对于备份存储地位和卷快照,Velero 有两个自定义资源 BackupStorageLocation 和 VolumeSnapshotLocation,用于配置 Velero 备份及其关联的长久卷快照的存储地位。

  • BackupStorageLocation 次要反对的后端存储是 S3 兼容的存储,存储所有 Velero 数据的存储区中的前缀以及一组其余特定于提供程序的字段。比方:Minio 和阿里云 OSS 等 ;
  • VolumeSnapshotLocation(pv 数据), 次要用来给 PV 做快照,须要云提供商提供插件, 齐全由提供程序提供的特定的字段(例如 AWS 区域,Azure 资源组,Portworx 快照类型等)定义。以对数据一致性最为敏感的数据库和中间件为例,开源存储插件 Carina 也行将提供数据库感知的 velero 卷快照性能,能够实现中间件数据的疾速备份及复原。

Velero 装置和应用

装置 velero 客户端

$ wget https://mirror.ghproxy.com/https://github.com/vmware-tanzu/velero/releases/download/v1.6.3/velero-v1.6.3-darwin-amd64.tar.gz 
$ tar -zxvf velero-v1.6.3-darwin-amd64.tar.gz && cd velero-v1.6.3-darwin-amd64 
$ mv velero /usr/local/bin && chmod +x /usr/local/bin/velero 
$ velero version

装置 minio 作为数据备份后端

Minio 装置 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 
        - containerPort: 9001 
        volumeMounts: 
        - name: storage 
          mountPath: "/storage" 
        - name: config 
          mountPath: "/config" 
--- 
apiVersion: v1 
kind: Service 
metadata: 
  namespace: velero 
  name: minio 
  labels: 
    component: minio 
spec: 
  type: NodePort 
  ports: 
    - name: api 
      port: 9000 
      targetPort: 9000 
    - name: console 
      port: 9001 
      targetPort: 9001 
  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" 

装置 Mini,并查看资源创立状况。

$ kubectl apply -f ./00-minio-deployment.yaml 
$ kubectl get pods -n velero 
NAME                     READY   STATUS              RESTARTS   AGE
minio-58dc5cf789-z2777   0/1     ContainerCreating   0          14s
minio-setup-dz4jb        0/1     ContainerCreating   0          6s
$ kubectl get svc  -n velero 
NAME    TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)                         AGE
minio   NodePort   10.96.13.35   <none>        9000:30693/TCP,9001:32351/TCP   17s

待服务都曾经启动结束,能够登录 minio 查看 velero/velero 的 bucket 是否创立胜利。

装置 velero 服务端,应用 s3 作为存储

  • 创立 minio 凭证

    $ cat > credentials-velero <<EOF
    [default]
    aws_access_key_id = minio
    aws_secret_access_key = minio123
    EOF
    # 装置 velero
    $ cp velero /usr/bin/
    # 启用疾速补全
    $ velero completion bash
  • 应用官网提供的 restic 组件备份 pv

    $ velero install    \
     --image velero/velero:v1.6.3  \
       --plugins velero/velero-plugin-for-aws:v1.0.0  \
       --provider aws   \
       --bucket velero   \
       --namespace velero  \
       --secret-file ./credentials-velero   \
       --velero-pod-cpu-request 200m   \
       --velero-pod-mem-request 200Mi   \
       --velero-pod-cpu-limit 1000m  \
       --velero-pod-mem-limit 1000Mi   \
       --use-volume-snapshots=false   \
       --use-restic   \
       --restic-pod-cpu-request 200m   \
       --restic-pod-mem-request 200Mi   \
       --restic-pod-cpu-limit 1000m  \
       --restic-pod-mem-limit 1000Mi  \
       --backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://minio.velero.svc:9000

其中,几个重要的参数及其阐明如下:

--provider:申明应用的 Velero 插件类型。--plugins:应用 S3 API 兼容插件“velero-plugin-for-aws”。--bucket:在腾讯云 COS 创立的存储桶名。--secret-file:拜访 COS 的拜访凭证文件,见下面创立的“credentials-velero”凭证文件。--use-restic:应用开源收费备份工具 restic 备份和还原长久卷数据。--default-volumes-to-restic:应用 restic 来备份所有 Pod 卷,前提是须要开启 --use-restic 参数。--backup-location-config:备份存储桶拜访相干配置。--region:兼容 S3 API 的 COS 存储桶地区,例如创立地区是广州的话,region 参数值为“ap-guangzhou”。--s3ForcePathStyle:应用 S3 文件门路格局。--s3Url:COS 兼容的 S3 API 拜访地址
--use-volume-snapshots=false 来敞开存储卷数据快照备份。

装置命令执行实现后,期待 Velero 和 restic 工作负载就绪后,查看配置的存储地位是否可用。

$ velero backup-location get 

apiVersion: velero.io/v1    
kind: BackupStorageLocation    
metadata:    
  name: default    
  namespace: velero    
spec:    
# 只有 aws gcp azure    
  provider: aws    
  objectStorage:    
    bucket: myBucket    
    prefix: backup    
  config:    
    region: us-west-2        
    profile: "default"    
    s3ForcePathStyle: "false"    
    s3Url: http://minio:9000

至此 velero 就曾经全副部署实现。

velero 性能介绍

创立备份

velero 反对备份所有对象,也能够按类型,名称空间和 / 或标签过滤对象

$ velero create backup $NAME [flags]
$ velero backup create pvc-backup-1  --snapshot-volumes --include-namespaces nginx-example --default-volumes-to-restic --volume-snapshot-locations default

其中:

–include-namespaces: 备份该命名空间下的所有资源,不包含集群资源

–include-resources: 要备份的资源类型

–include-cluster-resources: 是否备份集群资源
此选项能够具备三个可能的值:

true:包含所有集群范畴的资源;false:不包含集群范畴内的资源;nil(“主动”或不提供)

–selector: 通过标签抉择匹配的资源备份

–exclude-namespaces: 备份时该命名空间下的资源不进行备份

–exclude-resources: 备份时该类型的资源不进行备份

–velero.io/exclude-from-backup=true: 当标签选择器匹配到该资源时,若该资源带有此标签,也不进行备份

同时,也能够通过应用 –ordered-resources 参数,按特定程序备份特定品种的资源,须要指定资源名称和该资源的对象名称列表,资源对象名称以逗号分隔,其名称格局为“命名空间 / 资源名称”,对于集群范畴资源,只需应用资源名称。映射中的键值对以分号分隔,资源类型是复数模式。

$ 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=n

定时备份:

$ velero schedule create <SCHEDULE NAME> --schedule "0 7 * * *"

$ velero create schedule NAME --schedule="@every 6h"

$ velero create schedule NAME --schedule="@every 24h" --include-namespaces web

$ velero create schedule NAME --schedule="@every 168h" --ttl 2160h0m0s

备份高级用法举例

  • 在单个 Velero 备份中创立不止一种长久卷的快照

    $ velero snapshot-location create ebs-us-east-1 \
      --provider aws \
      --config region=us-east-1
    
    $ velero snapshot-location create portworx-cloud \
      --provider portworx \
      --config type=cloud
    
    $ velero backup create full-cluster-backup \
      --volume-snapshot-locations ebs-us-east-1,portworx-cloud    
  • 在不同的地区将备份存储到不同的对象存储桶中

    $ velero backup-location create default \
      --provider aws \
      --bucket velero-backups \
      --config region=us-east-1
    
    $ velero backup-location create s3-alt-region \
      --provider aws \
      --bucket velero-backups-alt \
      --config region=us-west-1
    
    $ velero backup create full-cluster-alternate-location-backup \
      --storage-location s3-alt-region
  • 对于私有云提供的存储卷,将一部分快照存储在本地,一部分存储在私有云

    $ velero snapshot-location create portworx-local \
      --provider portworx \
      --config type=local
    
    $ velero snapshot-location create portworx-cloud \
      --provider portworx \
      --config type=cloud
    
    $ velero backup create cloud-snapshot-backup \
      --volume-snapshot-locations portworx-cloud    
  • 应用存储地位

    $ velero backup-location create default \
      --provider aws \
      --bucket velero-backups \
      --config region=us-west-1
    
    $ velero snapshot-location create ebs-us-west-1 \
      --provider aws \
      --config region=us-west-1
    
    $ velero backup create full-cluster-backup

查看备份工作。

当备份工作状态是“Completed”,且谬误数为 0,阐明备份工作实现且没产生任何谬误,能够通过以下命令查问:

 $ velero backup get 

通过先长期将备份存储地位更新为只读模式,能够避免在还原过程中在备份存储地位中创立或删除备份对象。

$ kubectl patch backupstoragelocation default --namespace velero \
    --type merge \
    --patch '{"spec":{"accessMode":"ReadOnly"}}'
    
velero backup-location get
NAME      PROVIDER   BUCKET/PREFIX   PHASE     LAST VALIDATED   ACCESS MODE   DEFAULT
default   aws        velero          Unknown   Unknown          ReadWrite     true

复原备份数据

$ velero restore create --from-backup <backup-name>
$ velero  restore create --from-backup pvc-backup-1 --restore-volumes

查看复原工作。

$ velero restore get 

还原实现后,不要遗记把备份存储地位复原为读写模式,以便下次备份工作应用:

$ kubectl patch backupstoragelocation default --namespace velero \
   --type merge \
   --patch '{"spec":{"accessMode":"ReadWrite"}}'

备份 hooks 介绍

Velero 反对在备份工作执行之前和执行后在容器中执行一些事后设定好的命令,这种形式对数据一致性等十分无效。velero 反对两种办法指定钩子,一种是 pod 自身的正文申明,另一种是在定义 Backup 工作时的 Spec 中申明。

  • Pre hooks

    pre.hook.backup.velero.io/container: 将要执行命令的容器,默认为 pod 中的第一个容器, 可选的。pre.hook.backup.velero.io/command: 要执行的命令, 如果须要多个参数,请将该命令指定为 JSON 数组。例如:["/usr/bin/uname", "-a"]
    
    pre.hook.backup.velero.io/on-error: 如果命令返回非零退出代码如何解决。默认为“Fail”,有效值为“Fail”和“Continue”,可选的。pre.hook.backup.velero.io/timeout: 期待命令执行的工夫,如果命令超过超时,则认为该挂钩失败的。默认为 30 秒,可选的。
  • Post hooks

    post.hook.backup.velero.io/container: 将要执行命令的容器,默认为 pod 中的第一个容器, 可选的。post.hook.backup.velero.io/command: 要执行的命令, 如果须要多个参数,请将该命令指定为 JSON 数组。例如:["/usr/bin/uname", "-a"]
    
    post.hook.backup.velero.io/on-error: 如果命令返回非零退出代码如何解决。默认为“Fail”,有效值为“Fail”和“Continue”,可选的。post.hook.backup.velero.io/timeout: 期待命令执行的工夫,如果命令超过超时,则认为该挂钩失败的。默认为 30 秒,可选的

    还原 hooks 介绍

    Velero 反对还原 hooks,能够在还原工作执行前或还原过程之后执行的自定义操作。有以下两种定义模式:

  • InitContainer Restore Hooks:这些将在待还原的 Pod 的应用程序容器启动之前将 init 容器增加到还原的 pod 中,以执行任何必要的设置。
init.hook.restore.velero.io/container-image: 要增加的 init 容器的容器镜像

init.hook.restore.velero.io/container-name: 要增加的 init 容器的名称

init.hook.restore.velero.io/command: 将要在初始化容器中执行的工作或命令

如进行备份之前,请应用以下命令将正文增加到 Pod:

kubectl annotate pod -n <POD_NAMESPACE> <POD_NAME> \
    init.hook.restore.velero.io/container-name=restore-hook \
    init.hook.restore.velero.io/container-image=alpine:latest \
    init.hook.restore.velero.io/command='["/bin/ash","-c","date"]'
  • Exec Restore Hooks:可用于在已还原的 Kubernetes pod 的容器中执行自定义命令或脚本。

    post.hook.restore.velero.io/container:; 执行 hook 的容器名称, 默认为第一个容器, 可选
    
    post.hook.restore.velero.io/command: 将在容器中执行的命令, 必填
    
    post.hook.restore.velero.io/on-error: 如何解决执行失败, 有效值为 Fail 和 Continue, 默认为 Continue, 应用 Continue 模式,仅记录执行失败; 应用 Fail 模式时,将不会在自行其余的 hook,还原的状态将为 PartiallyFailed, 可选
    
    post.hook.restore.velero.io/exec-timeout: 开始执行后要期待多长时间, 默认为 30 秒, 可选
    
    post.hook.restore.velero.io/wait-timeout: 期待容器准备就绪的工夫, 该工夫应足够长,以使容器可能启动,并

    如进行备份之前,请应用以下命令将正文增加到 Pod

    kubectl annotate pod -n <POD_NAMESPACE> <POD_NAME> \
      post.hook.restore.velero.io/container=postgres \
      post.hook.restore.velero.io/command='["/bin/bash","-c","psql < /backup/backup.sql"]' \
      post.hook.restore.velero.io/wait-timeout=5m \
      post.hook.restore.velero.io/exec-timeout=45s \
      post.hook.restore.velero.io/on-error=Continue

Velero 局部关键问题解析

Velero 能够将资源还原到与其备份起源不同的命名空间中吗?

是的,能够应用 –namespace-mappings 参数来指定:

velero restore create RESTORE_NAME \
  --from-backup BACKUP_NAME \
  --namespace-mappings old-ns-1:new-ns-1,old-ns-2:new-ns-2

执行还原操作后,已有的 NodePort 类型的 service 如何解决?

Velero 有一个参数,可让用户决定保留原来的 nodePorts。

velero restore create子命令具备 –preserve-nodeports 标记爱护服务 nodePorts。此标记用于从备份中保留原始的 nodePorts,可用作 –preserve-nodeports 或 –preserve-nodeports=true
如果给定此标记,则 Velero 在还原 Service 时不会删除 nodePorts,而是尝试应用备份时写入的 nodePorts。

velero 怎么实现不影响业务前提下得一致性备份策略,并将备份数据上传到对象存储中?

如果是基于 velero 实现数据库的一致性,须要用 velero 的 hook,在备份前对数据库进行 quiesce 操作,备份完 unquiesce。对于备份自身,能够应用 restic 来 copy 数据(但不必快照),或者应用快照的形式。

退出移动版