最近jenkins遇到了一次事故,还好现阶段处于planning阶段,对日常的开发工作影响较小。来盘点下这次issue。
周五下午的时候,jenkins pod毫无征兆的频繁重启。查看pod的logs发现启动并没有异常log,最后一行是
JVM is terminating. Shutting down Jetty
然后就是周而复始的restart。目前有两个问题摆在面前:1. 什么原因导致jenkins重启? 2. jenkins重启为啥启动不了?
查看volumns所在的磁盘,执行ls -lt发现有个文件当时被修改queue.xml。执行cat queue.xml进去后发现里面是描述一些job的情况,按照字面意思应该是当时宕机后正在排队执行的job。返现其中有个节点label写的是k8s建的动态slave的label,看到这个地方显然是有问题的,因为一旦jenkins重启, 那些动态slave与jenkins server通信的通道就会被关闭,从而导致轮询找不到node,所以基本上定位了为啥反复起不来的原因。先备份排队job,执行"echo '' > queue.xml",再次重新启动,发现jenkins能够正常启动了,而不会出现因为load不到动态slave而shut down。
问题2解决了,但是导致宕机的原因是什么呢?排查这个jenkins server还是比较稳定的,近期的配置改动也比较小,怀疑是新的pipeline代码导致的,带着这一丝疑虑,找到git仓库,翻看近期的PR,发现最近有DEV在修改我们的pipeline code,其中有段判断异常的地方引起警觉“System.exit(1)”,这个应该就是”凶手“了。我们知道jenkins使用java代码写的,也是跑在jvm里面,采用system.exit(1)会把当前的进程杀死,如果job又正好在jenkins所在的master机器上处理任务的话,就达到了杀死自己的条件。后来又去比对了当时宕机时间点,改PR执行job的触发时间,完全吻合。
此处issue还是带来了一些警示:
1.代码一定要review,专业的人做专业的事,至少他知道更多的“坑“和risk。
2.流程需要规范,这次DEV是通过改动自己的code跑PR,。绕过了我们对code的控制,导致jenkins异常。
3.jenkins也需要多种环境,将我们平时测试编写的job放在备用jenkins上,不要影响生产jenkins。