由于最近线上故障频出,公司决定对现有各个核心系统做故障演练,来加强核心系统的健壮性和可用性。我们演练的场景很简单,模拟单机房挂掉,所有的服务仍然可用。CI 作为各个业务系统所以依赖的核心组件,它的可用性是一定要严格保证的。 CI 中的 jenkins master 当然也是我们组演练的重中之重。而在这之前 jenkins master 都是单点运行的,可能运气比较好,还没有出过事故 ......
为了落实公司的故障演练计划,我们针对当前系统的 jenkins master 做了 active/passive 模式的 HA 方案,
具体如下:
讨论方案前,让我们先来回顾下 jenkins 的存储模型, jenkins 使用的是本地文件存储,所有数据都存储在环境变量 JENKINS_HOME 对应的目录。
jenkins 启动时会把本地文件中的数据加载到内存,在这之后配置的变更都是先写内存,然后异步写磁盘。也就是说一旦Jenkins启动,就再也不会尝试从磁盘重新加载了。假设我们从磁盘中读取了10个任务,如果有从Jenkins UI页面或者API提交修改任务的请求,那么Jenkins会去读内存中的任务配置信息,然后修改内存数据,再异步刷新到磁盘上。
也就是说 jenkins master 是有状态的,它依赖本地文件。本地文件是可以放到共享存储来解决,但是内存中的状态数据是拆不出来的。看了一些其他公司的 jenkins master HA 方案, 有使用 pacemaker 和 gearman 等,但是这些架构本身也比较复杂,它们自身也要保证HA,复杂度增加了很多,因此我们也没有考虑这些架构。
为了解决上面的问题,我们在业务端做了下改变,所有的 job 有个统一的模版,如果请求发现 job 不存在,那我们就用模版新建一个 job, 然后触发运行。业务只关系构建结果,在哪个节点上构建,通过哪个 master 分配,其实都是没有影响的。这也间接的解了 jenkins 中 job 的同步问题,同时也让使得上面的 active/passive 架构有意义。
总结一下,jenkins 的 HA 是有很多解法的,重要的是结合自己的场景。期望 jenkins 社区可用为用户解决 HA 这个大问题,让 jenkins 更易用, 更强大。