什么是 Velero?
Heptio Velero
( 以前的名字为 ARK) 是一款用于 Kubernetes
集群资源和持久存储卷(PV)的备份、迁移以及灾难恢复等的开源工具。
Velero 特性
Velero
目前包含以下特性:
Kubernetes
集群数据备份和恢复Kubernetes
集群的资源到其它 Kubernetes
集群Velero 组件
Velero
组件一共分两部分,分别是服务端和客户端。服务端运行在你 Kubernetes
的集群中,客户端是一些运行在本地的命令行的工具。
Velero 支持的备份存储
项目地址:https://github.com/heptio/velero
与 Etcd 备份的区别
与 Etcd 备份相比,直接备份 Etcd
是将集群的全部资源备份起来。而 Velero
就是可以对 Kubernetes
集群内对象级别进行备份。除了对 Kubernetes
集群进行整体备份外,Velero
还可以通过对 Type
、Namespace
、Label
等对象进行分类备份或者恢复。
注意: 备份过程中创建的对象是不会被备份的。
Velero
客户端发送备份指令。Kubernetes
集群内就会创建一个 Backup
对象。BackupController
监测 Backup
对象并开始备份过程。BackupController
会向 API Server
查询相关数据。BackupController
将查询到的数据备份到远端的对象存储。Velero
在 Kubernetes
集群中创建了很多 CRD
以及相关的控制器,进行备份恢复等操作实质上是对相关 CRD
的操作。
# Velero 在 Kubernetes 集群中创建的 CRD $ kubectl -n velero get crds -l component=velero NAME CREATED AT backups.velero.io 2019-08-28T03:19:56Z backupstoragelocations.velero.io 2019-08-28T03:19:56Z deletebackuprequests.velero.io 2019-08-28T03:19:56Z downloadrequests.velero.io 2019-08-28T03:19:56Z podvolumebackups.velero.io 2019-08-28T03:19:56Z podvolumerestores.velero.io 2019-08-28T03:19:56Z resticrepositories.velero.io 2019-08-28T03:19:56Z restores.velero.io 2019-08-28T03:19:56Z schedules.velero.io 2019-08-28T03:19:56Z serverstatusrequests.velero.io 2019-08-28T03:19:56Z volumesnapshotlocations.velero.io 2019-08-28T03:19:56Z
如何保证数据一致性
对象存储的数据是唯一的数据源,也就是说 Kubernetes
集群内的控制器会检查远程的 OSS
存储,发现有备份就会在集群内创建相关 CRD
。如果发现远端存储没有当前集群内的 CRD
所关联的存储数据,那么就会删除当前集群内的 CRD
。
Velero 支持的后端存储
Velero
支持两种关于后端存储的 CRD
,分别是 BackupStorageLocation
和 VolumeSnapshotLocation
。
BackupStorageLocation
主要用来定义 Kubernetes
集群资源的数据存放位置,也就是集群对象数据,不是 PVC
的数据。主要支持的后端存储是 S3
兼容的存储,比如:Mino
和阿里云 OSS
等。
apiVersion: velero.io/v1 kind: BackupStorageLocation metadata: name: default namespace: velero spec: # 只有 aws gcp azure provider: aws # 存储主要配置 objectStorage: # bucket 的名称 bucket: myBucket # bucket内的 prefix: backup # 不同的 provider 不同的配置 config: #bucket地区 region: us-west-2 # s3认证信息 profile: "default" # 使用 Minio 的时候加上,默认为 false # AWS 的 S3 可以支持两种 Url Bucket URL # 1 Path style URL:http://s3endpoint/BUCKET # 2 Virtual-hosted style URL:http://oss-cn-beijing.s3endpoint 将 Bucker Name 放到了 Host Header中 # 3 阿里云仅仅支持 Virtual hosted 如果下面写上 true, 阿里云 OSS 会报错 403 s3ForcePathStyle: "false" # s3的地址,格式为 http://minio:9000 s3Url: http://minio:9000
apiVersion: velero.io/v1 kind: BackupStorageLocation metadata: labels: component: velero name: default namespace: velero spec: config: region: oss-cn-beijing s3Url: http://oss-cn-beijing.aliyuncs.com s3ForcePathStyle: "false" objectStorage: bucket: build-jenkins prefix: "" provider: aws
VolumeSnapshotLocation 主要用来给 PV 做快照,需要云提供商提供插件。阿里云已经提供了插件,这个需要使用 CSI 等存储机制。你也可以使用专门的备份工具 Restic
,把 PV 数据备份到阿里云 OSS 中去(安装时需要自定义选项)。
# 安装时需要自定义选项 --use-restic # 这里我们存储 PV 使用的是 OSS 也就是 BackupStorageLocation,因此不用创建 VolumeSnapshotLocation 对象 --use-volume-snapshots=false
Restic 是一款 GO 语言开发的数据加密备份工具,顾名思义,可以将本地数据加密后传输到指定的仓库。支持的仓库有 Local、SFTP、Aws S3、Minio、OpenStack Swift、Backblaze B2、Azure BS、Google Cloud storage、Rest Server。 项目地址:https://github.com/restic/restic
本文中,我们将使用 Restic
来对 PV
进行备份,不过现阶段通过 Restic
备份会有一些限制。
Velero
提供了一个命令行用来初始化服务端和进行常用的备份和恢复操作。该命令行和 Kubernetes
集群交互(和 Kubectl 的方式类似),也是通过寻找 kubeconfig
的相关配置来访问集群。kubeconfig
主要是通过 KUBECONFIG
环境变量和 ~/.kube/config
文件以及选项 –-kubeconfig
来指定。
本次安装将会使用阿里云的 OSS 和 Restic
来作为后端存储。
Restic
需要 Docker
进程开通 Mount
传播,需要在 Docker
启动的 Systemd
文件内加入 MountFlags=shared
MountFlags:Docker 服务的 Mount Namespace 配置,会影响进程上下文中挂载点的信息。即服务是否会继承主机上已有挂载点,以及如果服务运行执行了挂载或卸载设备的操作,是否会真实地在主机上产生效果。可选值为 shared
、slaved
或 private
。
Mount Namespace
,继承主机挂载点,且服务挂载或卸载设备会真实地反映到主机上。Mount Namespace
,它会继承主机挂载点,但服务对挂载点的操作只有在自己的 Namespace
内生效,不会反映到主机上。Mount Namespace
,它在启动时没有任何挂载点,服务对挂载点的操作也不会反映到主机上。更多 Systemd
服务管理可参考:https://blog.mallux.me/2017/02/13/systemd/
下载最新版 Velero
,并解压。这里以 Linux 平台为例:
$ wget https://github.com/heptio/velero/releases/download/v1.1.0/velero-v1.1.0-linux-amd64.tar.gz $ tar xzvf velero-v1.1.0-linux-amd64.tar.gz $ cp velero-v1.1.0-linux-amd64\velero \usr\local\bin
更多平台可以在官方 Releases 页面下载:https://github.com/heptio/velero/releases/ 。
安装完成成后,可以加载下 Shell
自动完成功能,方便使用。
$ velero completion bash
2.1 准备 credentials-velero 文件
credentials-velero 文件内容为阿里云 OSS 的认证信息,会用于在集群中创建密钥。
$ vim credentials-velero # default 和 BackupStorageLocation 对象中 profile 字段的值要对应 [default] aws_access_key_id = xxx aws_secret_access_key = xxx
2.2 启动 Velero 服务端
$ velero install \ --image gcr.azk8s.cn/heptio-images/velero:v1.1.0 \ --provider aws \ --bucket xxx \ --prefix xxx \ --namespace velero \ --secret-file ./credentials-velero \ --velero-pod-cpu-request 200m \ --velero-pod-mem-request 200Mi \ --velero-pod-cpu-limit 200m \ --velero-pod-mem-limit 200Mi \ --use-volume-snapshots=false \ --use-restic \ --restic-pod-cpu-request 200m \ --restic-pod-mem-request 200Mi \ --restic-pod-cpu-limit 200m \ --restic-pod-mem-limit 200Mi \ --backup-location-config region=oss-cn-beijing,s3ForcePathStyle="false",s3Url=http://oss-cn-beijing.aliyuncs.com
使用 Restic
给带有 PVC
的 Pod
进行备份,必须先给 Pod
加上注解。
先看一看基本语法:
$ kubectl -n YOUR_POD_NAMESPACE annotate pod/YOUR_POD_NAME backup.velero.io/backup-volumes=YOUR_VOLUME_NAME_1,YOUR_VOLUME_NAME_2,...
在来看一个实例,这里使用一个 Elasticsearch
的 Pod
为例:
$ kubectl -n elasticsearch annotate pod elasticsearch-master-0 backup.velero.io/backup-volumes=elasticsearch-master $ kubectl get pod -n elasticsearch elasticsearch-master-0 -o jsonpath='{.metadata.annotations}' map[backup.velero.io/backup-volumes:elasticsearch-master]
$ velero create backup NAME [flags] # 剔除 namespace --exclude-namespaces stringArray namespaces to exclude from the backup # 剔除资源类型 --exclude-resources stringArray resources to exclude from the backup, formatted as resource.group, such as storageclasses.storage.k8s.io # 包含集群资源类型 --include-cluster-resources optionalBool[=true] include cluster-scoped resources in the backup # 包含 namespace --include-namespaces stringArray namespaces to include in the backup (use '*' for all namespaces) (default *) # 包含 namespace 资源类型 --include-resources stringArray resources to include in the backup, formatted as resource.group, such as storageclasses.storage.k8s.io (use '*' for all resources) # 给这个备份加上标签 --labels mapStringString labels to apply to the backup -o, --output string Output display format. For create commands, display the object but do not send it to the server. Valid formats are 'table', 'json', and 'yaml'. 'table' is not valid for the install command. # 对指定标签的资源进行备份 -l, --selector labelSelector only back up resources matching this label selector (default) # 对 PV 创建快照 --snapshot-volumes optionalBool[=true] take snapshots of PersistentVolumes as part of the backup # 指定备份的位置 --storage-location string location in which to store the backup # 备份数据多久删掉 --ttl duration how long before the backup can be garbage collected (default 720h0m0s) # 指定快照的位置,也就是哪一个公有云驱动 --volume-snapshot-locations strings list of locations (at most one per provider) where volume snapshots should be stored
这里同样以上面提到的 elasticsearch
为例。
$ velero create backup es --include-namespaces=elasticsearch
注:Restic 会使用 Path Style,而阿里云禁止 Path style 需要使用 Virtual-Hosted,所以暂时备份没有办法备份 PV 到 OSS。
备份创建成功后会创建一个名为 backups.velero.io
的 CRD 对象。
$ velero restore create [RESTORE_NAME] [--from-backup BACKUP_NAME | --from-schedule SCHEDULE_NAME] [flags] --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 -h, --help help for create --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) --label-columns stringArray a comma-separated list of labels to be displayed as columns --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,... -o, --output string Output display format. For create commands, display the object but do not send it to the server. Valid formats are 'table', 'json', and 'yaml'. 'table' is not valid for the install command. --restore-volumes optionalBool[=true] whether to restore volumes from snapshots -l, --selector labelSelector only restore resources matching this label selector (default) --show-labels show labels in the last column -w, --wait
$ velero restore create back --from-backup es
恢复成功后,同样也会创建一个 restores.velero.io
CRD 对象。
首先,在集群 1 中创建备份(默认 TTL 是 30 天,你可以使用 --ttl 来修改):
$ velero backup create
然后,为集群 2 配置与集群 1 相同的备份位置 BackupStorageLocations 和快照路径 VolumeSnapshotLocations。 并确保 BackupStorageLocations 是只读的(使用 --access-mode=ReadOnly)。接下来,稍微等一会(默认的同步时间为 1 分钟),等待 Backup 对象创建成功。
# The default sync interval is 1 minute, so make sure to wait before checking. # You can configure this interval with the --backup-sync-period flag to the Velero server. $ velero backup describe
最后,执行数据恢复:
$ velero restore create --from-backup$ velero restore get $ velero restore describe
本文在 「集群备份工具 Velero 使用 」一文基础上修改而成。