CloudBees CI 使用 Velero 进行灾备 (DR) 概念验证
企业灾难可能是技术、自然或人为层面的。自然灾害包括洪水、龙卷风、飓风、滑坡、地震和海啸。人为和技术灾难涉及的面较广,包括危险物质泄漏、电力或基础设施故障、化学和生物武器威胁、网络攻击、恐怖主义行为、爆炸和内乱。这些都有可能造成企业 IT 系统的关闭,以及阻碍企业的整体运营。
对于企业来说,停机时间和技术中断就像一个恐怖故事,所以,您需要一个灾难恢复 (DR) 计划。
阅读本文,您将了解现代云平台上,CloudBees CI 实施此类灾难恢复计划的效果。
生产环境中部署的关键业务功能,必须有灾备计划,以便在系统意外崩溃时,可以将业务迁移到本地区的其它机房甚至其它地区。
这就是 CloudBees 决定进行概念验证的原因,能够了解在现代云平台上,为 CloudBees CI 实施此类灾难恢复计划的效果如何。
CloudBees 专注于以下几种场景: CloudBees CI 在 Elastic Kubernetes Service (EKS)中运行,对于 $JENKINS_HOME 卷使用 Elastic Block Store (EBS),并由 Route 53 管理域。它演示了使用常用的 OSS Velero 项目作为备份系统,对元数据使用简单存储服务(S3),并使用 EBS 快照来存储主要数据。
为什么 CloudBees 要选择这一场景?因为采用 Kubernetes 能使我们关注应用程序本身,而不是基础设施。当在 Kubernetes 上使用类似 Velero 的工具时,不仅会备份和恢复数据卷,而且还会备份和恢复所有元数据。这意味着我们可以通过一些简单、可移植的命令来运行主要的操作。
除了 Velero,我还能使用其他工具吗?是的,当然可以。这篇文章中展示的概念可以用其他开源或商业的备份工具来实现,不管是在 Kubernetes 上还是其他地方,只要它们能够跨区域同步数据。例如,Google Cloud (GCP) 正在为 Google Kubernetes Engine (GKE)提供一个原生的集成备份系统。
能剧透一下结果吗?能,但继续阅读,您能收获更多有趣的信息和背景。CloudBees 进行了测试,测试规模约 100 个在用的托管控制器,能够达成 RPO(Recovery Point Objective)和 RTO(Recovery Time Objective)目标。更具体地说,CloudBees 可以在每 15 分钟安排一次备份的基础上实现较低的 RPO,而 RTO 则在同一范围内。
CloudBees CI 的灾难恢复要求
一般来说,CloudBees CI 的跨区灾难恢复有以下几个要求:
文件系统数据,例如 $JENKINS_HOME 卷,必须在灾难发生之前复制到备用区。因为灾难发生后,恢复数据为时已晚。
元数据,例如进程列表、网络配置或不在 $JENKINS_HOME 中的任何内容,也必须提前复制。应该假定主要区域是完全不可访问的。
管理员必须有一种简单的、大部分是自动化的方式来触发切换(failover)。(当在主区域检测到问题时,不需要自动触发切换。)
一旦恢复到备用区域,CloudBees CI 必须在没有任何严重错误(例如:文件写入不一致等)的情况下启动。
故障转移过程必须包括将 CloudBees CI 的 DNS 条目切换到新的物理位置,以便任何浏览器书签、webhook 或类似组件都可像恢复之前那样继续工作。
恢复时间目标(RTO)由管理员确定,但通常是一个小时或是更少的时间。这意味着故障转移过程需要在几分钟内完成,CloudBees CI 应该很快启动并运行,随即准备执行构建。
恢复点目标(RPO)可能较长,大约为一天,但也可能与 RTO 相当。因此,只有少数最新的构建或配置更改可能会丢失。
管理员应该清楚地知道恢复的系统实际上是从备份中恢复的,并有机会检查可能因故障转移而中断的任何构建。
备注:
由于 Jenkins 架构,UI 将会有一段时间无法访问,任何传入的 webhook 也会丢失。但是,监听 hook 的系统,如 Multibranch 项目,应该配置为偶尔轮询作为备用。
预计可能已经因为故障转移而中断的构建,不会自动恢复或重新启动,也不去尝试保存工作区的内容或节点的实时进程状态。
CloudBees CI 中的灾难恢复支持
CloudBees CI 与 DR 兼容,包括跨区域。从技术角度来看,它涉及到以下主要组成部分:
Jenkins 核心和插件通常将配置和运行时的状态,都保存在文件系统层次结构中。因此,简单地将 $JENKINS_HOME 卷复制到新位置就足以进行备份。在可行的情况下,元数据文件都是自动编写的,并且尽一切努力容忍丢失、截断或损坏的文件,但出于安全原因,也有一些例外。
流水线插件的设计目的是允许构建版本在控制器重启时运行。同样的机制也适用于备份和恢复或灾难恢复场景中的输入等步骤,这些步骤不需节点参与就会暂停。当构建在节点块内的节点上运行,并且由于区域中断或更常见的问题而销毁或丢失节点时,当前构建不可能在新的节点上重试这一阶段。然而,这种情况至少可以记录在构建日志和元数据中,并可以从头开始重新启动构建。
CloudBees CI 包含专有的功能,可检测恢复场景,向管理员显示专门的通知,并列举可能或肯定受到影响的构建版本。
2022 年 4 月发布的 CloudBees CI 2.332.2.6 版本中有一些功能改进。我们会继续吸取客户的意见,并作出适当的改进。
Kubernetes 上的 CloudBees CI 还受益于 Kubernetes 控制平面的强大容器管理。除了作为 StatefulSet 运行的运营中心(operations center)和托管控制器(managed controllers)之外,控制器还使用 Jenkins Kubernetes 插件在一次性节点上安排构建,无需显式管理基础设施。假设备份区域的集群有足够的容量,那么一旦托管控制器再次启动,恢复后的安装就可以运行新的构建。备份不需要包含 Pod,因为操作中心或管理控制器 Pod 会自动重新创建。代理 Pod 无法从备份中恢复。
出于 DR 目的,CloudBees CI 还支持托管控制器休眠。如果在最后一次备份时,托管控制器中只有一部分实际上在运行,那么恢复之后也同样如此。交付给恢复集群的 SCM webhook 可以像往常一样“唤醒”休眠的托管控制器并触发构建。
CloudBees CI 还提供了配置即代码(CasC)功能。完全转换为 CasC 的安装可能不需要传统备份来实现灾难恢复;恢复操作可简单地包括在新集群中运行 CasC 引导脚本。但是,如果您需要保留临时数据(例如构建历史记录),那么出于 DR 目的,可能仍需要从备份执行文件系统级恢复。
在 AWS 上使用 Velero
Velero 包括一个适用于 AWS 的标准插件,专门基于 S3 元数据存储和 EBS 快照。不过此插件目前暂不提供跨区域支持。
作为这个概念验证的示例,我们为这个 Velero 插件开发了自定义补丁,它实现了跨区 EBS 快照复制。为保持较低的 RPO,我们还为 Velero 核开发了自定义补丁,以并行化卷快照操作。可以将备份恢复到主区域或 failover 区域,并在恢复时自动选择适当的快照。
重要提示:这些补丁应该被认为是实验性的且无法支持。他们目前的形式不被上游 Velero 项目接受。对 Velero 的普遍跨地区支持正在讨论中,因为它可能是基于新的基础架构。
此外,我们还为 CloudBees CI 开发了简单的 Velero 插件,该插件并非针对 AWS。它在每个 StatefulSet 中将当前恢复的标识符记录为环境变量,这样使用 Restart Aborted Builds 插件的托管控制器就会收到关于从备份中恢复的警报。
演示
代码
有配套的存储库和发布版,可演示本篇文章的内容,并对其进行更详细的扩展。
存储库: https://github.com/cloudbees-oss/cbci-eks-dr-demo
发布: cbci-velero-eks
注意:这里介绍的架构和代码旨在进行概念验证,并没有制定关于如何在生产环境中部署 CloudBees CI 的标准。
架构
下图展示了为运行演示而部署的所有 AWS 组件。
△ 图 1:演示架构图 概述
流程
构建阶段
△ 图 2:演示架构图 侧重构建阶段
构建灾难恢复演示的自动化脚本完成所有步骤后,将在原始(东)和故障转移(西)区域创建以下元素:
在 EKS 上运行的 Kubernetes 集群
△ 图 3:主要(东)区域和故障转移(西)区域的 Kubernetes context 元素 通过 K9s 工具查看
部署在 Nginx 入口控制器和 Velero 图表 k8s 资源部署,以及 k8s Metrics 服务器组件
△ 图 4:运行演示设置后,故障转移区可用的 Kubernetes 副本集 通过 K9s 工具查看
除了跨区域的通用元素之外,原始区域将用于现代化云平台的 CloudBees CI 部署,包括一个运营中心和一组通过 Helm 和 CasC 配置的托管控制器。
△ 图 5:在 MC_COUNT 设置为 5 的情况下运行演示设置后
可立即从主区域获得 Kubernetes Statefulset,通过 K9s 工具查看
在提到的区域外,在全局级别上,创建了以下元素:
在 AWS Route 53 内的一条 A 记录,指向主区域的入口控制器的 AWS ELB alias。
△ 图 6:运行演示设置后,来自 Route 53 的 AWS A 记录指向主 AWS ELB alias
通过 AWS 控制台查看
全局 S3 bucket ((连接到西部区),存储 Velero 备份,Velero 调度程序是在部署 CloudBees CI 图之后立即创建的。
△ 图 7:运行演示设置后,全局 AWS S3 Bucket 可用 通过 AWS 控制台查看
最后,为主区域(Primary Region)除 pods 和事件外的所有 K8s 对象创建 Velero 备份计划。它将安排以下事件:
Velero 命名空间备份
CloudBees CI 命名空间备份
存储在 s3 Bucket 中每个 PV 的 EBS 快照
将 EBS 快照复制到故障转移区域
注意:如不希望使用计划备份,也可以使用 backup.sh 脚本启动备份
CI 工作负载模拟
此时,可以根据您的 DR 测试要求扩展集群节点组,更新 cbci-eks-dr-demo/infra/cluster.yaml 上定义的初始 desiredCapacity。
一旦节点成功扩展,就可通过运行 reload-cbci 脚本来模拟 CI 工作负载,它将触发每个托管控制器中托管的 3 个流水线。值得注意的是,在运行加载命令之前,应该调整 MC_COUNTto 的新值,以适应节点组的新大小)。
△ 图 8:Jenkins pipeline 任务通过其中一个 controller 运行
从 CloudBees CI 控制器仪表盘查看
△ 图 9:来自节点的 Kubernetes Pods,上述 Jenkins pipeline 任务,通过 K9s 工具查看
灾难恢复故障转移
△ 图 10:演示架构图,侧重故障转移阶段
在转移到故障转移部分前,务必确保 Velero 备份正常:检查是否是“已完成”的非过期备份,且没有错误或警告。
△ 图 11:可用 velero 备份的描述性列表侧重故障转移阶段,从终端查看
然后,可执行 CloudBees CI 平台到故障转移区域的恢复,从最新的健康备份中传输包含应用配置和构建信息的所有 K8s 资源。Velero 此前启动了名称空间恢复。
务必注意,主区域中的运行流水线会在恢复操作之后立即在故障转移区域中恢复。
另请查阅 CloudBees 检查点功能对于这类场景的全部优势。
△ 图 12:故障转移区域中的运行流水线 ,从 CloudBees CI 控制器仪表盘查看
为了验证恢复是否成功,请转到恢复后的托管控制器的托管 Jenkins 仪表板,从 Restart Aborted Builds 插件的管理监视器可以看到这样的消息:This controller is new restore from backup。
△ 图 13:来自 Restore Build Plugin 的消息
通过 CloudBees CI Controller > Manage Jenkins 查看
此外,Velero 恢复操作可通过其 CLI 描述,以检查其状态。
△ 图 14:完整描述由 Velero 备份执行的恢复 从终端查看
DNS 开关
CloudBees 应用将可从故障转移区域访问,因为有一个 DNS 开关从东部的 ELB alias 到西部。
△ 图 15:演示架构图,重点关注 DNS 交换阶段
可从 Route 53 Hosted Zone 进行验证。
△ 图 16:运行 DNS 开关后,来自 Route 53 的 AWS A 记录指向故障切换 AWS ELB alias
从 AWS 控制台查看
测试和结果
整体而言,Velero 补丁已经测试到大约 100 个主动管理控制器的规模。休眠管理控制器对备份时间的影响很小,因为 EBS 卷快照以及跨区域快照复制都是增量的。在合理的负载条件下,备份只需几分钟就能完成,因此,基于每 15 分钟调度一次的备份,可实现较低的 RPO。由于 Kubernetes 元数据的重建是相当快的,因此在同一区域的 RTO 也是可能实现的。从 EBS 快照创建的卷是延迟加载的,因此操作中心和托管控制器的启动时间比通常要慢,但仍然可以接受。
实际结果取决于许多因素,备份性能主要取决于修改的 512 KiB 块的数量。可以修改大量或大型文件的托管控制器(例如通过运行许多并发构建、使用大型日志文件,或将构建工件存储在 $JENKINS_HOME(基于 s3 的工件存储适宜于这个任务)施加了最大的负载,因此需要时间。从 EBS 快照创建的卷是延迟加载的,因此操作中心和托管控制器的启动时间比通常要慢,但仍然可以接受。
考量
如果你想尝试一下实验性的 Velero 插件补丁,请注意有一些限制:
它只支持单个可用分区(AZ)中的卷,即使可将 EKS 配置为使用 EBS 跨区的几个 AZ 运行有状态的工作负载。但是,无状态的 pods(如节点)可以运行在另一个 AZ 的节点池中。
它只支持一个故障转移区域,不实现元数据复制。元数据只发送到故障转移区域中的 S3,因此如果故障转移区域发生故障,从主区域中的备份进行恢复将无法工作。
还要注意,AWS 弹性文件系统(EFS)有一个非常不同的快照和复制架构,不在这个插件管理范围内(打补丁或其他方式)。
与灾难恢复相关的 AWS 计费成本可能会有所不同,因此请确保监控每个“服务”的每日、每周或每月的成本使用图表。预计与计算(EC2)成本相比,EBS 快照的跨区域复制不会显著增加每月费用。保持 EBS 快照,即使在一个区域内也会产生显著的成本,但仍然可能比计算成本低得多。但这对于日常备份是必要的。
从头开始创建 EKS 集群非常耗时,大约需要 27 分钟,这就无法优化 RTO。此外,这很容易出错。因此,明智的做法是在故障转移区域保留一个空集群—只有一个控制平面和 Velero 服务处于活动状态,费用为每天 5 美元。扩展节点池的速度要快得多,且看起来非常可靠,因此在恢复过程中按需进行扩展是合理的。这节省了成本,只会增加几分钟的 RTO。使用 Amazon EC2 Spot 实例也可以大大节省计算成本。
致谢
感谢 Steve Boardwell 所做的评论和演示测试,用以验证其交叉兼容性。
本文由 Jesse Glick(持续集成首席软件工程师)和 Carlos Rodriguez Lopez (CloudBees DevOps 顾问)撰写。Jesse 多年来一直在开发 Jenkins 的核心和插件。他与 Kohsuke 共同开发了流水线系统的核心基础设施。Carlos 是一位推崇 DevOps 文化的自动化顾问。他在 Java Web 和数据管理与分析以及在云中运行 CI/CD 流水线方面有丰富的造诣。
文章来源:https://www.cloudbees.com/blog/cloudbees-ci-disaster-recovery-dr-proof-of-concept-using-velero
如需了解更多关于 CI/CD 等流水线等信息,或想免费试用 Cloudbees,请立即联系Cloudbees授权合作伙伴——龙智:
电话:400-775-5506
邮箱:marketing@shdsd.com
评论