詹金斯和库伯内斯:完美的一对

2020-05-18 14:35:06

由于世界正在适应新的和不可预见的环境,许多传统的做事方式已经不再是这样了。这带来的一个重要影响是,世界几乎完全虚拟了。无论是Zoom欢乐时光和家庭聚会,还是虚拟会议,过去面对面的东西都已经数字化了。在几个月前世界似乎发生翻天覆地的变化之前,我本打算在一个会议上谈到我们过去几年在Rookout运行詹金斯对库伯内斯的经历。然而,唉,这并不是命中注定的。所以,我想我可以把我到目前为止学到的任何东西都传授给你们所有人,在这里(以数字方式!;)。世界正在走向虚拟,那么还有什么更好的方式来联系学习到的经验,对吗?

我们选择Jenkins的原因是,我们需要对构建过程和Jenkins Pipeline支持的代码可重用性进行高度控制(自从我们做出选择以来,CircleCI和GitHub Actions在满足我们的一些需求方面取得了很大进展)。你可以在这篇博客文章中找到这一特定旅程的全部细节,但让我们把重点放在这一条上。

在Kubernetes之上运行Jenkins省去了大部分维护工作,尤其是管理Jenkins代理。Jenkins Kubernetes插件非常成熟,使用它按需启动代理可以将代理本身的维护成本降低到几乎为零。

虽然我们非常享受这种设置的日常好处,例如快速的构建时间、高度可定制的CI/CD过程,而且几乎不需要维护,但让它启动并运行远非一件微不足道的任务。

一路走来,我们遇到了詹金斯和库伯内斯的种种局限,我们在“引擎盖下”寻找,发现了鲜为人知的知识金块。通过在这里与您分享它们,我希望您自己的部署体验将更加顺畅。

将Jenkins部署在Kubernetes Cluster上的最简单方法(我们对Jenkins使用专用集群,但这不是必需的)是构建您自己的Helm图(如果您不熟悉Helm,请查看),依赖于现有的Helm图作为依赖项,并添加您可能需要的任何其他资源。

很明显,您要添加的第一个图表依赖项是Jenkins本身,我们从稳定的舵库中选择了这个舵图。要定义的最重要的配置选项包括:

确保将Persistent Volume Claim作为ExistingClaim传递给Jenkins持久性配置。

根据您正在运行的作业量计算出Jenkins Master需要的内存量,并在隐藏的master.javaOpts参数中设置JVM参数-XMX、-XMS和-XX:MaxPermSize(我们分别使用8192m、8192m和2048m)。

在Kubernetes上运行Jenkins最具挑战性的部分是设置构建容器映像的环境。要执行此操作,请执行以下三个简单步骤:

将运行构建容器docker:dind的官方Docker镜像的部署和服务添加到您的Helm图表中。

将持久卷挂载到/var/lib/docker,以确保您的层被持久缓存,以获得卓越的构建性能。

通过添加DOKER_HOST环境变量指向相关的POD服务(即tcp://dind-service:2375),配置pod模板以使用远程docker引擎。

您旅程的下一步是使您的团队能够访问Jenkins,同时避免将其暴露给世界。Jenkins有大量的插件和配置选项,要使所有内容保持最新和安全几乎是不可能的。

我们选择让入口控制器来处理这一问题,HAProxy在将任何传入请求传递给Jenkins之前执行OAuth2身份验证。按照本指南配置HAProxy OAuth2插件以使用OAuth2代理容器。如果您将Jenkins配置为使用相同的OAuth2身份提供程序(例如,使用此插件进行Google身份验证),您的团队将只有一次登录。或者,您也可以随时获得商业的现成解决方案,如ODO。

一旦您完成了所有设置,您将需要确保定期备份您的Jenkins Master。实现这一点的最简单方法是使用这个整洁的小脚本。

正如我前面提到的,我们发现这种方法的最大好处之一是能够轻松地动态扩展您的资源。我们在集群上使用两个单独的节点池,一个用于长时间运行的Pod,例如Jenkins Master、Inress、Docker-in-Docker,另一个节点池用于Jenkins代理及其正在运行的工作负载。

对于我们的主机本身,我们为Jenkins选择了单主机部署。它在具有16个CPU和64 GB RAM的单个节点上运行。这意味着主升级和其他意外事件可能会导致较短的停机时间。如果您需要多主机部署,您可以自行完成:)。

第二个节点池正在运行Jenkins代理及其工作负载,并且启用了自动伸缩。要允许Kubernetes智能地管理该节点池的资源,您必须确保正确定义Kubernetes资源请求和限制。

将工作负载本身的资源设置为Jenkins Kubernetes插件中Pod模板的一部分。

请记住,第二个节点池实际上是节省成本的大好机会,并且是Spot实例的完美候选者,无论是直接使用还是通过利用Spot。作为一个额外的好处,当在GKE上运行时,我们发现节点的性能随着时间的推移而下降,这可能是由于密集的Pod调度所致。当使用每24小时(或更短时间)自动更换一次的Google可抢占虚拟机时,我们注意到集群可靠性和性能有了显著提高。

在我与我们的客户和Rookout的研发团队的工作中,我发现部署往往是减缓日常运营和工程速度的瓶颈。我希望通过与您分享我们在Kubernetes上运行Jenkins所学到的一些经验,您现在将能够改进您自己的CI/CD流程。

话虽如此,仍然需要注意的是,采用Rookout这样的工具将使您能够做更多的事情,同时不需要部署那么多。所以开始吧,我期待着听到你的经历!