首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

虽然惊天地,但不是人人都会哭泣——再论Kubernetes 惊天地泣鬼神之大Bug

前两天,朋友圈里疯转了一篇知乎上的帖子,《Kubernetes 惊天地泣鬼神之大Bug》(https://zhuanlan.zhihu.com/p/37217575)。很多朋友看到了帖子,纷纷转发给我以表慰问。看到该bug会影响到所有的kubernetes集群,吓得我赶紧吃根辣条冷静一下。

在线上的巡检邮件梳理了一遍,貌似没发现异常。冷静下来再想想,以我们的集群规模,如果真有这个bug,那么早就该发现了,为何到现在没有爆出来。按照作者的触发方式,我进行了反复的实验,怎么也触发不了。我感觉又不淡定了,啥情况,不是说所有的都会影响么?为啥触发不了?我决定追根溯源,来找找到底为啥会出现这样的问题。

此bug,按照作者的描述,基本上是这样的,对于k8s的某一种资源(不仅是service,其他的资源一样应该也是如此),如果先创建一个最早的对象a,然后再执行一些创建对象的操作,最后再删除那个最早的对象a,此时watch到的删除event中的对象a的resourceVersion不是期待的一个最新最大的resourceVersion,而是最早创建这个对象a时的创建event中的那个老的resourceVersion,从而导致controller-manager的一些回放event的行为。对应到资源service上就是作者描述的service的删除创建被回放,导致其所属的endpoint的消失和重建,从而造成服务的不稳定性。

看完我们立刻在自己的环境上验证,看是否可以重现,结果是未能重现,实验结果如下,所有event的object的resourceVersion都是递增的。

这与作者描述的完全不符合啊。算了,我们还是去源码里找答案吧。

delete时间的resourceVersion是在这里,在我们的主力版本(1.6)上,该代码是这样的。

这里的入参 watchCacheEvent的event是从etcd中获取的。我们使用命令行从etcd中把这些事件抓取出来。

其中kv对应的是event中的Object,prev_kv对应的是event中的PrevObject。红线圈出的Delete情况的event.preObject的resourceVersion是此对象上一次event的mod_revision,因此会小于Object的resourceVersion。这样我们就可以理解了,在1.6版本中,始终是以当前的Object的resourceVersion作为watch event的resourceVersion,这样所有的event中的resourceVersion都是递增的。这个是没有问题的。

而在1.7+的版本中,该代码是这样的。

这个时候,watch event的resourceVersion变为了PreObject的,这样就必然存在在watch的event的resourceVersion不是严格递增的,当遇到delete事件时,会返回到前面某个event的resourceVersion上去的问题。

之后社区的修复#58547后的代码是这样的。

这里可以看到,watch event的resourceVersion被更新为了event的ResouceVersion,重新保证了event的resourceVersion始终是递增的。

在对比了github上的commit记录,可以看到,此bug是在#46223这个pr中引入的。该pr被合入到1.7.0之后的版本,可以参见https://github.com/kubernetes/kubernetes/commit/e9e69356e4907fa4d0f45ea7e7768357ba71aba9#diff-dc17590f6b960d2fea2b44de5c0fbc10

而社区在#58547这个pr中修复此问题,也就是说可以对比https://github.com/kubernetes/kubernetes/commit/57998d247df74cc96547158a0b39e5d7bffa271b#diff-dc17590f6b960d2fea2b44de5c0fbc10中之后的版本得以修复。因此受影响的版本主要是介于两个pr之间的版本。

这里我们介绍一下复现的方法,大家可以参照来自检下自己的集群是否需要修复。

kubernetes版本不断向前发展,这其中会有老的bug被修复,也可能会有新的bug被引入。这些对于社区都是很正常的。但是对于生产环境来说,又是存在着较大的风险的。在实际生产过程中,我们开发了一系列的周边工具和运营监控系统,用以保证集群的稳定。毕竟稳定可靠对于生产环境来说,才是最基本的原则。

在618之前,我们JDOS团队会用一系列文章,来介绍我们在大规模kubernetes集群的定制和运营方面的经验,在未来也会将陆续释放一些工具开源给大家,希望能为大家提供一些参考。欢迎大家关注我们的公众号,我们将会在TIGCHAT公众号中首发相关资料。敬请期待!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180528G1GU2C00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券