企业灾难可能是技术、自然或人为层面的。自然灾害包括洪水、龙卷风、飓风、滑坡、地震和海啸。人为和技术灾难涉及的面较广,包括危险物质泄漏、电力或基础设施故障、化学和生物武器威胁、网络攻击、恐怖主义行为、爆炸和内乱。这些都有可能造成企业IT系统的关闭,以及阻碍企业的整体运营。
对于企业来说,停机时间和技术中断就像一个恐怖故事,所以,您需要一个灾难恢复 (DR) 计划。
阅读本文,您将了解现代云平台上,CloudBees CI实施此类灾难恢复计划的效果。
立即联系CloudBees授权合作伙伴——龙智,获得更多关于CloudBees的咨询、试用、服务等信息。
生产环境中部署的关键业务功能,必须有灾备计划,以便在系统意外崩溃时,可以将业务迁移到本地区的其它机房甚至其它地区。
这就是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