CCE集群备份恢复(停止维护)
插件简介
CCE集群备份恢复插件(e-backup)提供集群备份恢复能力。它将用户应用数据和业务数据备份到OBS桶中,并提供数据的本地备份和远程备份的能力。
使用约束
- 备份/恢复过程中,用户要保证集群处于稳态,不要触发增删改等变更行为,以免出现备份/恢复失败或不完整;
- 若集群发生变更,建议等15分钟后,集群处于稳态,再做备份操作;
- 使用 云盘快照备份 时,仅提供EVS类型的PV卷做快照备份,并遵循快照的约束(如:不支持跨AZ恢复等),计费参考“云盘快照”;
- 使用 restic备份 时,提供对EVS、SFS、SFS Turbo、OBS类型的PV卷做数据备份,并上传到OBS备份仓库中;
- 开源的restic会对备份时间点的数据做自有快照,并上传数据,不影响用户后续数据的读写,但restic不做文件内容的校验和业务一致性校验,其特性遵循restic约束;
- restic占用内存与初次备份的PV卷数据大小有关,若数据大于500G,建议采用云存储提供的迁移方式进行,若使用本插件可以参考操作指南修改restic容器的资源配额;
- 备份过程中有状态应用业务数据一致性,需要用户可通过Hooks来保证业务数据一致性,比如:同步内存数据到文件中等;
- 在恢复过程中,支持通过配置调整来适应迁移前后的环境差异:
- 应用可以从原命名空间恢复到指定的另一个命名空间中,但需要用户确认恢复应用间没有通过固定的service来访问该应用;
- 可以将应用的镜像地址(repo)换成另一个镜像地址,镜像名字和版本号在恢复过程中是保持不变的;
- 可以将应用使用的StorageClass的名字更换成新的StorageClass,注意需要使用同类型替换,比如:块存储 -> 块存储。
- 遵循开源velero和restic插件的约束,比如:在恢复过程中Service会清除clusterIP的IP地址,这样才能更适应源、目标K8s集群的差异。
安装插件
- 登录CCE控制台,单击左侧导航栏的“插件市场”,找到e-backup插件,单击e-backup插件下的“安装”。
- 在安装插件页面,选择要安装的集群,配置参数,然后单击“安装”。
当前支持配置如下参数。
volumeWorkerNum:备份volume的工作并发数量,默认为3。
准备密钥
- 获取访问密钥。
登录CCE控制台,在右上角用户名下选择“我的凭证”,在左侧选择“访问密钥”,单击“新增访问密钥”。
- 创建密钥文件,并通过 base64 格式化成字符串。
# 创建密钥文件 $ vi credential-for-huawei-obs HUAWEI_CLOUD_ACCESS_KEY_ID=your_access_key HUAWEI_CLOUD_SECRET_ACCESS_KEY=your_secret_key # 使用 base64 格式化字符串 $ base64 -w 0 credential-for-huawei-obs XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHWOBS
- 创建Secret。
按如下YAML文件创建Secret。
apiVersion: v1 kind: Secret metadata: labels: secret.everest.io/backup: 'true' #标识该secret用于E-Backup访问备份存储库 name: secret-secure-opaque namespace: velero #必须和E-Backup置于同一namespace,取值必须为velero type: cfe/secure-opaque data: # credential文件经过base64编码后得到的字符串 cloud: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHWOBS
- secret 所在 namespace 必须和 E-Backup 实例所在namespace一致,即 velero。
- secret.data 中存储的是访问对象存储服务的密钥,其中 key 必须为 cloud,而 value 为2中通过 base64 编码得到的字符串。一般通过 base64 编码后显示的字符串会有换行符,请在写入 secret.data 中时手动去除这些换行符。
- secret 需要打上标签“secret.everest.io/backup: true”,标识该 secret 是用于备份存储库的管理。
创建存储库
这里的备份存储库是指 E-Backup 用于获取和检测后端对象存储服务相关信息的 K8s 资源对象。
apiVersion: velero.io/v1 kind: BackupStorageLocation metadata: name: backup-location-001 namespace: velero #必须和E-Backup处于同一namespace spec: config: endpoint: obs.{regionname}.myhuaweicloud.com # OBS的endpoint credential: name: secret-secure-opaque # 此前创建的secret的名字 key: cloud # secret.data中的key值 objectStorage: bucket: tools-cce # OBS中的桶名 prefix: for-backup # 子路径名 provider: huawei # 使用OBS服务
- 除了 prefix 字段为选填外,其他字段必填。provider 为固定值 huawei。
- endpoint 可以到地区和终端节点获取,都需要保证集群内各节点可访问该地址。当endpoint 不带协议头时(http或者https),默认启用 https。
- credential中的 name 和 key 需要配置正确,否则 E-Backup 无法访问后端存储库。
创建完成后等待30s用于备份存储库的检查和同步等工作,随后查看该备份存储库状态是否可用,PHASE 为 Available 表示可用,其他表示不可用。
$ kubectl get backupstoragelocations.velero.io backup-location-001 -n velero NAME PHASE LAST VALIDATED AGE DEFAULT backup-location-001 Available 23s 23m
此处如果PHASE 长时间没有Available,可通过查看E-Backup的日志定位问题。E-Backup安装后会在velero命名空间创建一个名为velero的工作负载,查看velero的日志即可。
立即备份
立即备份操作后会立刻执行备份过程,备份完成后停止,适用于克隆/迁移。
编辑备份模板,如下所示,随后通过 kubectl create 命令创建。
apiVersion: velero.io/v1 kind: Backup metadata: name: backup-01 namespace: velero spec: includedNamespaces: - nginx - mysql labelSelector: matchExpressions: - key: direction operator: In values: - back - front matchLabels: app: nginx backup: velero runMode: Normal appData: volumes: Restic hooks: resources: - name: hook01 includedNamespaces: - nginx labelSelector: {} pre: - exec: command: - /bin/sh - -c - echo hello > hello.txt && echo goodbye > goodbye.txt container: container-0 onError: Fail timeout: 30s post: - exec: command: - /bin/sh - -c - echo hello > hello.txt && echo goodbye > goodbye.txt container: container-0 onError: Fail timeout: 30s storageLocation: backup-location-001 ttl: 720h0m0s
参数说明如下。
- 备份参数
- storageLocation:指定了使用的备份存储库的名称,备份后的内容将会放置到对应的后端对象存储中,为必填字段。
- ttl:指定了备份的内容将会在存储库中存放的时间,超期后会被删除,必须按照指定格式进行配置:h,m,s 分别表示“时,分,秒”。例如24h 表示一天,3h4m5s 表示 三小时四分钟五秒,默认为30天(720h0m0s)。
- 资源过滤相关:以下字段为过滤条件,都配置时取交集,相当于对集群中的所有资源进行筛选。
- includedNamespaces/excludedNamespaces:指定对某些命名空间下的资源备份/不备份,互斥选项,选择一项配置即可,可选择多个namespace,默认表示所有namespace。
- labelSelector:指定对具有特定标签的资源进行备份,参照 K8s 的标准用法,按需选择。
- runMode:选择备份的运行方式,必填,Normal(备份应用和数据)/AppOnly(仅备份应用)/DataOnly(仅备份数据)/DryRun(用于验证,不备份)。
- 业务数据备份相关:当前支持两种方式对业务产生的实际数据进行备份,一种是 everest 快照,只适用于使用 evs 类型的持久卷(pvc)作为数据卷;另一种是 restic 备份,可备份除去 hostpath 类型以外的所有数据卷。两种方式支持混用。
- appData:备份持久卷数据的方式,Restic/Snapshot,Snapshot默认不启用。Snapshot方式是为支持快照能力的存储,且集群中部署了csi快照插件时才能生效。
- hook:hook是用于在备份前或备份后执行某些指令,实现用户对备份的精细化控制,hook 类似于执行 kubectl exec 命令,目前只对 Pod 有效。
- includedNamespaces/excludedNamespaces:指定对某些 namespace 下的 Pod 执行/不执行 hook ,互斥选项,默认表示所有namespace
- labelSelector:指定对具有某些 label 的 Pod 执行 hook,参照 K8s 的标准用法,按需选择
- command:指定 hook 的执行命令
- container :指定执行命令的容器名,当 Pod 有多个容器时用于精细化控制,默认为Pod 的第一个容器。
- onError:指定 hook 执行失败时的行为,可选择 Continue/Fail ,默认为 Fail。
- Continue:表示 hook 执行失败不影响后续动作的继续执行;Fail 表示 hook 执行失败将不会继续后续备份动作。
- timeout:指定 hook 执行的超时时间,超过时间后认为 hook 执行失败,默认为 30s。
hook 是针对 Pod 而言,hook 执行失败可能影响的后续备份动作也是针对执行 hook 的 Pod 而言,对其他对象比如 services 等的备份没有影响。
由于 hook 是针对 Pod 而言,因此 hook 并非全局可用的。当需要执行 hook 的 Pod 没有被选择为备份对象时,hook 不会被执行。可以认为 hook 的"includedNamespaces/excludedNamespaces" 配置是在被筛选为需要备份的对象中进一步进行筛选。
上文中给出了所有的可配置项,在这里一方面基于实际备份场景,一方面为了用于便于操作,给出备份配置建议。
- 备份的保存时间按照"天"(24h)粒度进行控制。
- 当前应用基本会部署到特定namespace中,因此建议使用 includeNamespace 划定备份范围。如果需要更精细的备份对象控制,可以应用 labelSelector,前提是明确所有需要备份的对象具有相应的label。"includeNamespace + labelSelector" 能够满足绝大多数场景的使用。
- 使用 restic 备份业务数据时,如果对 OUT/IN 方式不熟悉,可以不对需要备份卷的 Pod 增加 annotation,通过简单的配置 defaultVolumesToRestic 选项为 true/false 对 Pod 使用的卷整体进行业务数据备份/不备份。
- 在需要对备份进行精细化控制时使用 hook ,尽量避免执行长时间运行的任务。另外,hook 中执行的命令不要直接操作文件系统。
备份执行后,可通过如下命令查看备份状态。status中会列出详细的状态。
$ kubectl -n velero get backups backup-01 -o yaml | grep "phase" phase: Completed $ kubectl -n velero get backups backup-01 -o yaml …… status: ……
备份状态说明
- FailedValidation:备份模板配置错误,可以查看 Backup.Status.ValidationErrors 发现错误配置原因
- InProgress:备份正在进行中
- Completed:备份完成,没有错误
- PartiallyFailed:备份完成,但是备份某些对象的过程中出现错误(比如 hook 执行错误)
- Failed:备份失败,出现影响整体备份的错误
- Deleting:备份正在删除中
首次备份完成后,OBS桶中会出现backups和restic两个文件夹。
备份日志存储在OBS桶中,假设备份名为 backup-001,进入到OBS存储服务的页面,根据在备份存储库中配置的桶名和子路径名找到存储位置,进入 backups/backup-01 目录下,找到 backup-01-logs.gz 文件,随后下载、解压并查看。
周期备份
操作后会基于配置以一定的周期重复性地执行备份过程,比较适用于容灾。
编辑 Schedule 模板,如下所示,随后通过 kubectl create 命令创建。用户可以自行按照需要给 Schedule 模板打上 label,Schedule 上的 label 都会打到通过 schedule 创建的 backup 上。Schedule 创建到集群后,会立即执行一次备份,后续按照设定的定时周期重复执行备份过程。
apiVersion: velero.io/v1 kind: Schedule metadata: name: schedule-backup-001 namespace: velero spec: schedule: 0 */10 * * * template: runMode: Normal hooks: {} includedNamespaces: - nginx - mysql labelSelector: matchExpressions: - key: direction operator: In values: - back - front matchLabels: app: nginx backup: velero storageLocation: backup-location-001 ttl: 720h0m0s
参数说明如下。
- schedule:创建的定时表达式,指定备份的周期执行时间。支持 @every格式 和 Linux标准cron表达式。
- @every NUnit:其中N表示一个正整数,Unit可以为s, m, h,表示每隔N个Unit时间触发一次,例如:@every 2h30m,每隔2小时30分执行一次。
- 标准cron表达式:采用五子表达式,分别是 Minute,Hour,Day-of-Month,Month,Day-of-Week。
- template:备份的模板,与备用应用(立即备份)中spec一致。
删除备份
删除集群中创建的备份对象及其相关对象(比如:Backup/Restore/Schedule等),并且将后端存储库中的备份内容删除,适用于产生大量备份数据时进行的清理工作。
编辑 DeleteBackupRequest 模板,如下所示,随后通过 kubectl create 命令创建。
apiVersion: velero.io/v1
kind: DeleteBackupRequest
metadata:
name: backup-001-delete
namespace: velero
spec:
backupName: backup-001 # 指定要删除的备份名
查看状态。
$ kubectl -n velero get deletebackuprequests backup-001-delete -o yaml | grep " phase" phase: InProgress
- InProgress:删除任务正在进行中。
- Processed:删除任务已经被处理过。
- Processed 状态只意味着 E-Backup 处理过该任务,但是不一定能够完成该任务。可以通过查看 deletebackuprequest.status.errors 字段查看执行删除任务期间出现的错误。如果 E-Backup 正确完整地处理完删除任务,则该 deletebackuprequest 对象本身也会被删除。
- 后端存储库(OBS桶)中的内容不要人为进行手动删除。
立即恢复
将某个立即备份作为数据源,恢复应用到另一个 namespace/集群 中,全场景适用。
编辑 Restore 模板,如下所示,随后通过 kubectl create 命令创建。
apiVersion: velero.io/v1 kind: Restore metadata: name: restore-01 namespace: velero spec: backupName: backup-01 hooks: resources: - name: restore-hook-1 includedNamespaces: - mysql labelSelector: {} 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 - exec: execTimeout: 1m waitTimeout: 5m onError: Fail container: mysql command: - /bin/bash - '-c' - 'while ! mysql_isready; do sleep 1; done' - exec: container: mysql waitTimeout: 6m execTimeout: 1m onError: Continue command: - /bin/bash - '-c' - 'mysql < /backup/backup.sql' includedNamespaces: - nginx - mysql namespaceMapping: nginx: nginx-another mysql: mysql-another labelSelector: {} preserveNodePorts: false storageClassMapping: disk: csi-disk obs: csi-obs imageRepositoryMapping: quay.io/coreos: swr.cn-south-1.myhuaweicloud.com/everest
参数说明如下。
- 选择数据源
- 资源过滤相关:这里的过滤是指对已经备份的内容进行的过滤,参考备用应用(立即备份)中资源过滤相关的配置。
- 特殊处理相关
- namespaceMapping:指定将已备份的内容恢复到另一个 namespace 中,以 map 形式给出,格式为"source: target",不要求新的 namespace 在目的集群存在
- storageClassMapping:改变备份资源PV、PVC等使用的storageClassName,要求StorageClass类型相同。
- imageRepositoryMapping:改变备份资源的images字段,用于仓库的映射关系,不包含镜像名字和标签的改变(防止迁移和升级耦合在一起),比如:quay.io/coreos/etcd:2.5 搬迁到SWR后,使用本地镜像仓库下 swr.cn-south-1.myhuaweicloud.com/everest/etcd:2.5,配置格式为:quay.io/coreos: swr.cn-south-1.myhuaweicloud.com/everest
- preserveNodePorts:如果设置成不保留,则不保留的是 Service 自动生成的 nodePort,用户手动配置的 nodePort 仍然会保留
- hook相关:Restore 模板的 hook 配置和 Backup 模板的不太相同,共有两种类型,一种是 init 类型,用于向 Pod 中添加 initContainer;一种是 exec 类型,用于执行某些指令。init 类型的 hook 请参照 K8s 中 initContainers 的定义方式进行配置,下面介绍有关 hook 整体选择的参数和 exec 类型的参数。
- includedNamespaces/excludedNamespaces:指定对某些 namespace 下的 Pod 执行/不执行 hook ,互斥选项,默认表示所有namespace
- labelSelector:指定对具有某些 label 的 Pod 执行 hook,参照 K8s 的标准用法,按需选择。
- command:指定 hook 的执行命令。
- container:指定执行命令的容器名,当 Pod 有多个容器时用于精细化控制,默认为Pod的第一个容器。
- onError:指定 hook 执行失败时的行为,可选择 Continue/Fail ,默认为 Fail。
- Continue :表示 hook 执行失败不影响后续动作的继续执行;Fail 表示 hook 执行失败将不会继续后续动作。
- execTimeout:指定 hook 执行的超时时间,超过时间后认为 hook 执行失败,默认为 30s。
- waitTimeout:指定 E-Backup 准备执行 hook 时到容器开始执行 hook 的等待超时时间,超时后认为 hook 执行失败,默认为 0s,表示没有超时限制。
- 数据源的选择请指定正确,保证该 Backup 是 Completed 状态
- 资源过滤相关的参数只在确有需要的时候进行配置,否则无需配置
- 业务数据的恢复由 E-Backup 自行根据备份时选择的方式进行针对性的恢复,用户无需担心,也没有相应的配置
- hook 的使用建议参照立即备份中的 hook 使用建议,waitTimeout 在无必要的情况下可以不进行配置
- 恢复时建议配置恢复到新的 namespace 下,按照备份什么就恢复什么的原则,避免自行的配置失误导致恢复后的应用无法启动运行
恢复执行后,可通过如下命令查看恢复状态。status中会列出详细的状态。
$ kubectl -n velero get restores restore-01 -o yaml | grep " phase" phase: Completed $ kubectl -n velero get restores restore-01 -o yaml …… status: ……
恢复状态说明
- FailedValidation:恢复模板配置错误,可以查看 Restore.Status.ValidationErrors 发现错误配置原因。
- InProgress:恢复正在进行中。
- Completed:恢复完成,没有错误。
- PartiallyFailed:恢复完成,但是恢复某些对象的过程中出现错误(比如 hook 执行错误)。
- Failed:恢复失败,出现影响整体恢复的错误。
查看恢复日志以及过程中的 warnings 和 errors 信息。
假设恢复名为 restore-01 ,进入到OBS控制台,根据在备份存储库中配置的桶名和子路径名找到存储位置,进入 restores/restore-01 目录下,有如下两个文件。
- restore-01-logs.gz:日志文件,随后下载、解压并查看日志。
- restore-01-results.gz:恢复结果文件,包含 warnings 和 errors 信息。
版本记录
插件版本 |
支持的集群版本 |
更新特性 |
---|---|---|
1.2.0 |
v1.15 v1.17 v1.19 v1.21 |
|