GitHub 全面运行在Kubernetes之上
【编者的话】网络上鲜有文章介绍如何将Kubernetes部署在物理云环境中。本文作者Newland来自于GitHub的SRE团队,他从实际项目实施角度,介绍了如何将Kubernetes部署在GitHub的物理服务器上,并最终实现将GitHub全部运在Kubernetes上。
自GitHub在2008年上线以来,其网站就运行在Ruby on Rails之上。然而,8年过去了, GitHub作为全世界最重要的版本控制仓库,整个组织架构的负载已经日趋紧张。GitHub在很多方面都有了很大的发展,不仅在用户数量和对github.com和api.github.com的访问请求等各方面都有巨大的增长。公司的员工数量在递增,同时对站点可靠性工程师(Site Reliability Engineering,SRE )团队服务的需求也在递增。
SRE团队越来越多地从项目中撤出,旨在直接改善GitHub.com网站的用户体检,以支持各种各样的内部需求。随着GitHub 服务数量的增多,团队的数量也在不断增加,随之站点可靠性团队花费在服务的维护、部署和其他无关任务上的时间也越多。
受限于SRE团队的可用性,GitHub的其他工程师也受到限制,甚至变得更慢。“新的服务可能需要几天、几周甚至几个月才能完成部署,这取决于它们的复杂性和我们团队的可用性。”GitHub的首席站点可靠性工程师 Jesse Newland 说。“我们迫切地需要给其他的工程师提供一个自助的平台,他们可以用来自己实验创建和部署新的服务,并按需扩容。”
因此,在2016年8月的前一年,启动了Newland团队和平台开发实验团队的一个合作项目,将整个平台作为服务解决方案进行评估。Kubernetes是由Google开发并由云原生计算基金会( Cloud Native Computing Foundation )维护的开源容器编排引擎,它迅速地成为行业的领先竞争者。
“ Kubernetes 项目是我见过的维护和监管最好的开源项目之一,和它相关的社区也都非常精彩,该项目的每个领域展现着出色的工程师。”Newland说。“我相信该技术能够帮助团队以更加稳健地方式来远行项目,不仅限于GitHub团队,也包括任何使用它的团队。”
开始使用容器
这不是GitHub首次涉足容器。“我们已经在很多方面使用了他们,比如CI、测试和一些隔离的项目上。不过,他们没有提供大量的生产工作负载。”他解释道。因此,我们已经拥有了一些经验,但是并不深入。我们确实对Dockerfile格式的优点和缺点都很熟悉,这也是有所帮助的。
在项目的最初阶段,团队就决定要致力于迁移公司的一个最核心的负载:github.com和GitHub API。“ 这是一个深思熟虑的决定,它受很多因素的影响。” Newland说。这其中包括对自助服务容量扩容工具的需求,随时间的推移增加指定工作负载的可迁移性的需求,以及对新的平台能持续运行多年的需求。
“根据我们选择要迁移负载的关键性能,我们需要在把它服务于实际生产负载前,获得高水平的运维信心。”Newland说。
Kubernetes风格的黑客周(Hack Week)
为了支持即将到来的黑客周,一个小型的实验项目已经构建,并创建了Kubernetes集群和部署工具,此举也获得一些该平台的实践经验。这是一个合适的场景,让不同的团队同时尝试集群和部署,这也是一个小规模版本GitHub对平台的全面组织的需求。
Newland说,黑客周正如其名,是一个非常适合的测评场地。这是一个低风险的实验环境,来验证Github在Kubernetes的运行状况,并且成为我们第一次调研的良好的质量标准,因为黑客周就是围绕软件的最多可用性来进行的。“然而,更重要的是公司的开发人员喜欢拥有一个可重复的环境,去测试他们的修改对所有依赖的子系统的运行情况。
简而言之,Github的第一次深入尝试Kubernetes取得了真正成功。“我们对该项目的经验以及来自黑客周的工程们的反馈都是非常积极正面的,并支持扩大该实验。”Newland总结到。“有了这些正面的体验,我们开始计划更大的推广。”
(此外,Newland说,黑客周已经成为了一种模式,用来运行和检验其他的GitHub的应用,这些应用可以从独立的运行环境中获得好处,并可按需创建而不必运行在固定数量的准生产服务器上。“以我的经验来看,非生产或者准生产环境随着时间推移而逐渐会变得陈旧,因为在你真正需要它们的那一刻之前,它们并没有被真正地维护和受关注,这样会引起各种各样的问题。”Newland说。“所以,我们非常兴奋地应用该模式到所有的GitHub及它的应用上,正如我们需要一套预备生产测试环境一样。”)
构建之路
该团队没有为整个Kubernetes的迁移工作设立一个固定时间表,而采用了一种以成就为导向的方式 。目标是根据现有产品的性能以及错误率为导向迁移,而不会设定一个固定的截止期限来完成。
“我们大致知道我们要达到的目标,会通过选定一个接近的目标和设定一个大概的日期,让团队感到紧迫性。”Newland说。这是一个阶段性的推进方案,他解释道:“我们对这个新的平台进行小流量的测试,并在我们尝试更大的步骤前,来检验它是否能够满足我们的预期目标。”
下一个关键的成就是:建立一个“评审实验室”(review lab)。
“我们知道,我们需要设计、原型和验证使用Kubernetes原生的Pods、Deployments和Services来替代由前端服务器提供的服务。”Newland说。“一些验证可以通过在一个容器中运行现有的测试套件来进行,而不是运行在一个配置为模拟前端服务器上。
但是,我们还需要获得更大的信心在把容器作为一组更大的Kubernetes资源的一部分来运行。”
我们决定建立“评审实验室”--- 这是一个通过Kubernetes来部署和管理的环境,它支持对Kubernetes及其服务组合进行探索性测试,类似与现有GitHub的“分支实验室”环境。
团队们花费了2016余下的时间来创建评审实验室,并在此程中交付了多个子项目。其中包含把K8s集群运行在AWS 虚拟私有云平台( AWS Virtual Private Cloud ),它使用Hashicorp的 Terraform 和 kops 的组合管理;使用Dockerfile文件来部署github.com和api.github.com,使用YAML来描述超过50个的Kubernetes资源;使用一些Bash集成测试脚本来实验短暂的Kubernetes集群服务。Newland把它描述为“在项目开始时,通过大量地高负载地使用来获得对Kubenetes的信心。”
最终的结果是一个聊天式的用户界面,可以根据拉取请求来创建隔离部署GitHub的总量。“我们非常高兴的是,这种环境使工程师能够以自助服务的方式来实验和解决问题,”Newland说。他解释说,评审实验室环境在内部发布后,给大量的工程师提供了一种新的部署方式。从环境感兴趣的工程师们的反馈,以及在持续使用过程中工程师并未察觉环境变化并为此提出反馈,这些都帮助可靠性团队对Kubernetes建立了信心。
在物理服务器上部署Kubernetes
评审实验室成功推出后,Newland和他的团队从2016年底假期结束后,准备重点关注在GitHub的物理环境工作Kubernetes集群上,并开始迁移网络流量。
“我觉得特别有趣的一点是,我们实际上是在金属实体物理机器上运行着Kubernetes集群。Kubernetes生态系统非常专注于运行在云服务提供商上,大多数文档都是基于这一点的,”Newland说。 “有关Kubernetes如何工作在我们的物理数据中心的设计上,我们遇到了一些挑战。我们也看一些零散的文章和先驱者,但大多数博客文章和讨论都是基于 Kubernetes集群运行在他们的房子来阐述。所以,几个团队成员实际上开始在家里实施Kubernetes,并把它作为实验和学习的机会。”
“实际上,我的几个家庭自动化现在由Kubernetes来提供支持,”Newland补充说。
不容置疑,这需要做一些非常有趣的调整。为了满足GitHub的旗舰服务 的性能和可靠性要求,其中的一部分服务还要依赖于对其他数据服务的低延迟访问, GitHub的Kubernetes基础设施将需要支持公司的物理数据中心和接驳点(POPs)中的“物理云”。
“参照 Kelsey Hightower 的一篇不少于十几个读者的文章“ Kubernetes The Hard Way ”, 我们将少量手动配置的服务器组合到了一个临时的Kubernetes群集中。这些集群通过了我们的一组集成测试,该测试集之前也同样用来测试我们的AWS集群,”Newland说。
在迁移工作站旅途上的几个小的驿站:
- 使用 Calico软件定义的网络提供商 的即时可用功能,在IP-in-IP模式下快速发布群集,随后允许使用GitHub的网络基础设施进行对等探测。
- 构建一个小工具,为GitHub的内部Puppet和加密系统生成每个集群所需的证书授权和配置。
- 使用两种实例角色(Kubernetes节点和 Kubernetes API服务 )的配置,允许用户提供已经部署的集群的名称,以便在部署时加入该集群。
- 构建一个小型的基于Go的服务来使用容器日志,将元数据以key / value格式附加到每一行,并将它们发送到主机本地Syslog终端。
- 加强GitHub的内部负载均衡服务,以支持 Kubernetes NodePort 服务。
“所有这些努力的工作组合,通过了在单个集群的验收测试。”Newland说。鉴于此,团队们有理由相信,在相同的一组投入(指的是评审实验所使用的Kubernetes资源),同一组数据(通过VPN连接的评审实验室的网络服务)和使用相同的工具能够得到类似的结果。
“在不到一个星期的时间里,其中大部分时间用于内部沟通和对迁移有重大影响的事物的排序上,我们将整个工作负载从运行在AWS上的Kubernetes集群迁移到我们的一个数据之中心。”他总结道。
最后的倒计时
通过在GitHub的物理云上创建了一个成功和稳定的组合Kubernetes集群的模式,现在是时机开始减轻GitHub前端服务器的部分负载 。
“在GitHub,通常的做法是工程们通过创建一个称为Flipper的功能来验证他们正在构建的新功能,一旦可行就可以接它。”Newland说。 在增强部署系统后,将新的Kubernetes资源部署到现有前端服务器并行的Github生产环境的域名空间中,并增强了Github负载均衡服务,可基于受影响的Flipper功能模块的 cookie ,将员工的网络请求路由到另外的后台服务器,该团队允许GitHub的员工选择路由到一个实验性的Kubernetes后端。
“来自于内部用户的负载,帮助我们发现问题、修复错误,并让我们开始建立信心,”Newland说。 “我们还将少量网络流量路由到此集群,以确认我们对该负载下的性能和可靠性的假设。从最初的100个请求每秒开始,并扩大到对整个github.com和api.github.com的10%的访问量的请求。 ”
问题也卷土而出,其中也包括将集群与GitHub的现有负载平衡基础设施集成在一起的问题。 “运行高可用集群的文档掩盖了对负载均衡器的必要特性 – 这也不是缺陷,因为这也不是经常使用的事情。”他说。 “我们在此开辟先河,并在此过程中更具体地理解问题所在。当我们这样做的时候,我们也愿意和社区分享一些我们的经验。”
在即将把100%流量路由到Kubernetes时,团队选择在每个站点的多个群集上运行GitHub的前端系统,并自动地将请求从不健康的群集转移到其他健康群集。 “所以我们不用把所有的蛋放在一个Kubernetes集群中,而是运行了几个集群 - 这样一来,如果出现了错误的话,那么我们只会丢失一部分当时正在处理服务请求的服务器,”Newland解释说 。 “我们改进了我们的设计,并让它在那些测试过程中存在问题的领域提供更加合理的服务。”
最终,从内部到外部的Kubernetes的过渡是在一个月内进行的,同时保持在一定的性能和错误率之内。 “我在这里,因为我喜欢解决问题,”Newland说。 “不过,我同样感兴趣于不再创造出绝无必要的问题。”
个人视角
“作为一名站点的可靠性工程师,我的愿望是能够创建工具,使得软件开发人员比我更有创意 - 构建创新的和革新的解决方案,然后帮助其他人在GitHub上使用它们,”Newland总结说。 “这个项目让我感到鼓舞 - 我们设置的审查实验室环境,让我们的工程师能够尝试新事物并进行实验,而在此之前他们需要等待SRE团队。现在,他们不再受限于SRE员工的数量了。我们看到工程师们实验用不同的方法来替代大块的软件栈 ,并且审查实验室和Kubernetes组合使他们不仅可以自己实践,而且还做了一些SRE团队意想不到的事情...”