记一次生产环境问题排查(k8s环境)

本文为原创文章,转载请注明出处,否则追究责任。

最近线上生产环境出现一些问题,经过排查后进行了解决,记录下来便于总结。

 

问题1:

最近研发新上一个微服务,上线后启动了6个Pod,运行一段时间后一直很稳定,但有一天用户访问有问题,在手机端打开直接提示“网络错误”。

分析解决:

对于这个报错,研发那边的反馈是运维环境有问题,网络不稳定造成的,但我们实际的生产环境是在K8s上,每个node都在一个网络内,而且都是内网通讯,如果是网络原因,那应该也会影响其他项目的pod,但从现象看,别的同Node节点的服务运行稳定,查了日志,也没有任何报错,后来经过排查,发现这6个pod,在运行一段时间后有那么2~3个pod会出现假死状态,就是说pod显示是运行状态,但实际上已经无法处理外部请求了,因为是新服务,上线的时候并没有配置Liveness probe, readness probe, 在这种情况下,因为没有这些检测,service并不知道某个pod有问题,所以请求还是会转发到该Pod上,这样就导致了用户出现问题:

解决:

给这个服务配置存活和就绪检查,问题到这里就结束了,在最后我想说的是:给每个服务上线配置存活检测和就绪检查真的很基础也很重要,尤其是生产环境,一定要配置,别重蹈覆辙,因为这样即使是程序有问题,也不会影响到用户端的访问,当然这个程序突然就不工作假死的问题研发也在查代码解决,但从客户访问角度运维已经解决了问题。

 

问题2:

我们服务一直是采用滚动更新策略在进行更新,而且是晚上时段进行大版本的更新迭代,一直也没有什么影响,但最近用途突增,晚上用户量也很大,别的合作方在使用我们api接口时会有报错,影响了他们使用。

分析:

这种问题还是得查日志,查到最后我们在nginx日志里发现了在更新的时间段的确是有几条错误日志,时间跟我们更新的时间段相匹配,那按说采用滚动更新模式在加配置了探针,理论上应该不会出现这种问题, 所以跟研发对了下,通过日志里访问的记录,得出这几个都是比较耗时的长连接,那么问题就来了,因为在滚动更新时,正在更新的pod是不会有新请求进来,因为配置了探针,但一旦更新完一个pod,老的pod就会被杀掉, 那么在杀掉这个pod上如果还存在这连接业务没有处理完,就会被断开,因为pod没了,问题到这里就清晰了。

解决:

解决这个问题就要增加pod生命周期钩子,在pod被销毁前给出一段时间让该pod把业务处理完,实例代码如下:

在这里我强调下,这个钩子是针对容器的,因为最终处理业务是容器,这里要注意下。

这里还还有一个疑问,那到底设置多长时间?10秒还是30秒,这个没有确切的答案,数字只能根据实际业务来,但设置太长也不好,会让人产生误解pod停不掉了。

另外我再说一个这个钩子的应用场景,就是在做HPA的时候,扩容的时候不会有问题,但在缩容的时候也会存在很多已经存在在pod上的连接还没来得及处理pod就被销毁的问题,这个也会对生产环境产生影响,这时候就必须要配置生命周期钩子了,这样才能保障在缩容的情况下业务是稳定用户无感知的。

 

这篇就写到这里,希望大家后续少踩坑,有问题的小伙伴欢迎留言沟通交流。