[关闭]
@gaoxiaoyunwei2017 2018-06-07T15:01:30.000000Z 字数 6077 阅读 625

大型分布式团队的集中化持续交付

luna
作者:洪远雷


如何集中化管理CI Agent?

首先看一下现在的团队结构,可以看到绿色的部分表示现在我所在的Team, Asia属于Group下,Group下有很多其它的Team,我们的Team又分为很多其它的Team,以Regionalweb Team为例,它主要分布在香港、新加坡和其它的区域。可以看到团队的结构相对比较复杂,对于我来说,我现在手上所管理的AWS的账户是20多个。

image.png-97.5kBimage.png-168.1kB

我们都知道CICT是持续交付中很重要的工作,CICT又依赖于集成服务器,还有另外一个说法是自动化服务器。我们都知道一个应用部署到各个环境里去,在我们把应用部署到各个环境去之前需要做的是部署CI Agent。重点是我们要把应用部署到这么多的count里去,我们就需要部署Agent,它像是我们的助手,可以帮助我们部署应用。我们有这么多的count,自然要去部署更多的东西,岂不是很崩溃?

image.png-338kB

如何集中化管理这么多,我想到了一个办法,这个办法就是影分身之术,不知道大家之前有没有看过火影忍者,它可以分身。我们通过影分身来做,再多的count也可以很容易的解决掉。

image.png-633.5kB

接下来的内容就是讲怎么去学习影分身之术。学习影分身之术第一是要学如何结印。跟大家开一个玩笑,我们都是普通的人类,即便我们学会了结印也没有办法去进行影分身,看似这个方案失败了。
image.png-346.8kB

但不要气馁,我又想到了另一个方法叫基础设施即代码。我再简单的介绍一下,简单的理解就是我们以代码的方式来生成基础设施。什么是基础设施?对应到云上业务,比如说AWS, EC2、数据库服务、ELB等都是基础设施。我们可以通过代码的方式来生成基础设施,这有什么好处?第一个好处是通过对Agent即基础设施代码,加上配置参数,可以定制化的快速并且非常正确的创建不同环境上的CI Agent。

image.png-174.1kB
具体怎么做?首先看如何集中化创建CI Agent,我们采用的是ANSIBLE加CloudFormation,在这里我们实现了它的一部分,可以对其配置不同的Team不同的环境,配置不同的参数,将这些参数传到CloudFormation,CloudFormation是AWS用来实现基础设施即代码的方式,我们将不同的参数再加上模版即AWS的模版,就可以生成特定环境的CI Agent集群。当我们已经创建好Agent,通常情况下会有另外的需求,即需要分析Agent,比如说Agent可能会有一些权限,在后续的使用过程中需要去分析权限,我又不想一个一个去修改,那怎么做?通过对CI Agent的基础设施,添加Deploy来实现自动更新,在这一步我们会使用已经有的Agent来创建新的Agent,当新的Agent创建好之后,我们会用新的Agent 来干掉老的。比如说有一个机器人,它可以接受模版,它就可以通过这个模版生成收音机、单车等,但这个机器人在过了一段时间之后,它需要自我升级,这时谁帮它做?它就可以接受新的Agent基础设施代码,机器人通过基础设施代码创建一个新的机器人,创建好了新的机器人,这个机器人就会把老的机器人干掉,这样就实现自我更新。

到现在其实已经可以集中化的创建Agent,并且能够自动化的更新Agent,程序员只需要修改基础设施代码,后面的事都不需要。
image.png-63.3kB
image.png-57kB

两种CI Agent部署策略的优劣比较

现在看一下CI Agent的部署策略,这是最初CI Agent的部署策略。

image.png-71.6kB

我们可以看到,这是对于一个Team来说,通常情况下有三个环节。

到这里看似一切都很完美,但实际上是这样的吗?CI Agent的部署策略有什么问题,我们将所有的Agent都部署到DEV,DEV具有权限去操作,它有什么问题?
image.png-73.5kB

其实它具有很多问题,首先是单点故障,再是在升级Agent的时候,其它环境都是不可预估的,另一个是assume role. 在DEV环境,我们的Staging和production的pipeline都不是很好,这是一个问题。第二个是当我们升级Agent的时候,可能会有中断,production和Staging都依赖于这个。我们可以看到,DEV是具有权限去访问任何production和Staging,比方说我是一个装修公司的工头,我带了一群小弟,我具有装修的资格认证,这个认证是有序列号的,Thought Works觉得这里的装修不太好,让我们去做一些升级,老大就带着这些小弟去,前台会去核对资格证的证书和登记是否一样,如果一样就会给我一个临时的工牌,我就有权限来进行工作,当我把工作完成之后就会离开这个公司,前台也会把我的工牌收走,这是一个临时的权限,但这样还是具有一个问题,即如果我的工队里有些小伙伴居心叵测,他进入了ThoughtWorks就可以做一些手脚,他可以去破坏production或者是Staging,这其实是非常危险的。

image.png-90.1kB

带着这几个问题,我们将Agent部署的策略进行升级。现在的Agent部署策略是下面这样:

image.png-71.6kB

可以看到这是DEV具有DEV的Agent,Staging具有Staging的Agent,Production也有production的Agent,对环境也分区域,比如说北京区、东京区或者是新加坡区。我们都部署了相应的Agent,这样带来的好处有哪些?首先是操作DEV的时候,操作Staging就是Staging,操作Production就是Production,不会跨区域访问。其次它也不会有单点故障,因为它是隔离的。当然,它也不会有问题。能理解吗?我升级的时候是用的我自己的东西做升级,我要升级的时候是我自己内部的,不会用其它团队的Agent来升级我,是用我自己团队的。

image.png-159.2kB

如何优化CI Agent资源利用?

现在看一下都完成了哪些,首先是Assume role的问题解决了,然后是单点故障还有升级时影响的其它pipeline运行,这时我们就可以喝茶了吗?我们不能自己腐蚀自己。现在想想Agent的部署策略还有什么问题,大家看一下,这是刚才演进了一版的CI Agent的部署策略,它有什么问题?可以说它是没问题的,没有什么是100%的。

image.png-73.8kB

它是占用了更多的资源,意味着要花更多的钱,怎么去解决这样的问题?

image.png-83kB

image.png-98.9kB

上面也说了,Agent是属于一个大的龙头,在大的龙头下有一些公用的Agent池,这些Agent不具备访问环境的权限,它只具有编号的权限,我们可以让Test在这些共享的Agent去运行,就可以减少我自己的Agent上所要运行的任务,达到我们想要去用私有云,这可能在小的团队里用的不多,但在大的共享云里这个非常重要,因为它的任务量非常高,有了这种方法我们就可以使用共享池,其它的Team也可以在上面运行。

如何平衡资源的花费和提供更好的服务?

到现在可以看完成了哪些具有挑战性的任务。首先是我们使用了一个新的Agent策略,再一个是优化了资源的利用,到现在我们可以去喝茶了吗?
image.png-157.1kB

还是不行。我们要想怎么能提供更好的服务给DEV,怎么去做?
image.png-80.5kB

对于我们来说,在Agent不断增多的时候,我们需要在那去无限等待,这是很无效的,当Agent资源不够时,任务就得排队,CI可能一直在转,我们也不希望当没有任务时CI Agent还在运行,我想达到的目标是当我的任务增多时CI的集群能够自动来响应,当请求降低时也会自动的去把多余的Agent关掉,怎样达到这样的频度。我想到一个方法是提升它的可伸缩性,怎么提升它的可伸缩性?大家看一下这个图:

image.png-91.8kB

这是DEV环境里的CI Agent,什么情况下可以该把Agent增多,什么情况下该把Agent减少,我们是通过一个Lambda, 它会从Agent里去获取很多维度的信息,比如我现在正在运行的任务数和现在待运行的任务数,我们可以把这些信息定期的获取之后放到AWS里,再通过AWS的辅助,它是监控者,它监控着Cloudwatch, 当它发现已经超过的时候就可以去创建一个Lifecycle hook, 当我的任务解决量都能被消耗的时候就会停下。什么时候去删除,我们也是用这个来监控,当待执行任务的数量已经有两个小时都是零,两个小时都没有执行时这时就可以选择把多余的Agent关掉,这样就能实现可伸缩性。

有了可伸缩性我们可以看一下另外一个东西,即怎么监控和警告。

image.png-90.2kB

有了这么多的Agent和Team,我怎么知道Agent运行的状况,有些Agent可能在里面一直阻塞着,也不接受任务,但却一直说自己在busy, 你怎么去判断一个Agent有问题,其实取决于自己,你自己判断什么时候应该去发一个简要说Agent是有问题,集群里没有Agent提供服务时我们会发出一个警告,可以去触发它发送警告,警告也分级别,有高优先级的也有低优先级的,高优先级的可能是打电话,低优先级的可能是发邮件或者是短信来告诉你,这取决于你怎么去判定故障是高优先级还是低优先级。

现在我们又解决了一些具有挑战性的任务,完成了CI Agent的可伸缩性以及Agent的监控和预警系统。到这个时候我们可以喝茶了吗?
image.png-152.5kB

使用BulidKite所带来的优势和劣势

上面讲的东西都是所有持续提升服务器所具有的通性问题,不管你是什么样的持续提升服务器,它都具有这样的东西,是属于架构性的问题,我们也有一些个性的问题。客户的需求,我们将Jenkins迁移到了build KITE, 大家都知道Jenkins是持续提升服务器,其实Build kite也是,什么是Build kite,大家听过吗?

image.png-128.8kB

我在这里给大家讲一下,大家以后有用到Build kite的时候有一些坑就可以提前注意。
什么是Build kite?它其实就是架构,但它不同的地方是Build的master,Jenkins是完全自主掌控,但Build kite里master是交互性的,它帮我们做一些处理。
image.png-105.7kB

它可以带来哪些好处?首先是只需要提供运行时的环境,不需要去关心上面运行的用户管理,日志怎么管理,在Jenkins里每一个集群都有自己的用户管理日志,如果一个人管很多就要查看很多,很麻烦,但是对于Build Kite来说它提供统一的就不需要管理,还有Pipeline配置、Build信息管理,我们通常会定期去备份Jenkins上的东西和信息,因为我们要做灾配,可能不知道由于什么原因就被干掉了,我们需要找回之前的信息,但对于Build Kite来说就不需要,因为信息都保存在上面。
image.png-35.9kB

使用Build Kite也会带来很多问题,这些问题可能是Jenkins上所不具备的,第一个是安全,第二个是单点故障。

image.png-100.3kB

image.png-118.3kB

对于安全问题,可以看上面的图,这是一个关联的东西,我们需维护Agent的 Token, 如果这些key被泄露了就完了,Build Kite上所有的信息都可以被别人获取。

在同Group下的Team可以使用Group下所有的CI Agent,在一个Group里有很多的Team,Team都会建立自己的CI Agent,我们不希望自己的CI Agent被其他Team的人使用,在默认情况下,另一个Team的小伙伴既然能使用我们的Agent,这就会带来一些安全隐患,如果她是一个心地善良的小女孩就没什么问题,但如果她心怀不轨就可以利用Agent去执行一些任务,通过Agent删除Agent所在count下的资源。

image.png-137.7kB

对于单点故障,它是小概率发生的,但它还是会发生,就在上周五它就发生了,因为数据库出现了一些问题,导致它用不了,这个事持续了一个小时,这是我们选择Build Kite与生俱来的问题,没有办法避免,如果要使用Build Kite就得承担这些风险。它给你提供便利的同时也带来了风险,就看你如何权衡选择。

image.png-78.4kB

我们有这么多的问题,怎么去解决?首先对于敏感信息,即Agent Token,肯定不能让它泄露,因为非常危险。我们使用两种策略,一个是不同环境下使用不同的Agent Token,DEV环境下有DEV的,Staging环境下有Staging的。另一个是不同环境使用不同的KMS, KMS具有权限,在DEV环境下生成的KMS,你要使用它就需要具备DEV环境下的KMS资格。
image.png-73.9kB

进行加密之后,这个人即使看到了这个但也不知道这个是什么东西,因为它被加密了,再进一步说,如果这个人就是DEV的,他具有DEV的权限,他就可以解密DEV的Agent—Token,但即便是这样,他也只能解密DEV的 Agent—Token,而不能解密Staging和Production环境里的Agent—Token,越往下权限越严格。

另一个问题是白名单,这个图画的有点复杂,在我们的Agent上,会加白名单,这个白名单是Git Organisation, 通过这种方式,即便另一个Team的人具有实用Agent的权限,但当Agent去看的时候,发现他的能力不是白名单的,那他也会失败。这样就解决了安全隐患。

image.png-95.1kB

到现在我们再看一下又解决了哪些挑战性的任务,第一个是对敏感信息进行了加密,二是我们设置了白名单,提升了我们的安全性,单点故障没有办法解决,是因为这是Build Kite与生俱来的,我们只能信任它能做到为我们提供99.9%以上的服务。如果你自己去维护Agent的master也有同样的问题,这取决于我们自己的能力,如果我们认为我们的能够比较足,认为可以把服务的可用性提升到99.99%,我认为我们可以自己去控制。

image.png-170.7kB

到此为止,我已经把我所有想分享的内容分享完了。我们做一个简短的回顾。
首先是讲了如何集中化管理CI Agent,接着讲了两种CI Agent部署策略的优劣比较,之后是如何优化CI Agent的资源利用,下面是如何平衡资源的花费和提供更好的服务,最后是分享了使用Build Kite时优劣势,仅供大家参考,大家要使用Build Kite的时候就可以大概知道它的局限性和优势是什么。

image.png-121.4kB

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注