使用nginx的ingress时遇到的502问题怎么解决

今天小编给大家分享一下使用nginx的ingress时遇到的502问题怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

创新互联服务项目包括睢阳网站建设、睢阳网站制作、睢阳网页制作以及睢阳网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,睢阳网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到睢阳省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!

启用 keep-alive,502 响应增加

nginx-ingress-controller 0.20 之前的版本存在一个 bug,配置模版 nginx.tmpl 中没有在启用 keep-alive 时清除请求中的 “Connection: close”,反而是为所有转发给 upstream 的 http 请求加上了该请求头:

使用nginx的ingress时遇到的502问题怎么解决

image

应该是

使用nginx的ingress时遇到的502问题怎么解决

image

因为该 bug 的存在, 0.20 之前的版本即使在 config-map 中配置了 keep-alive,nginx 与 pod 之间的 http 通信依旧是短连接,每产生一个请求就建立一个连接。连接利用效率低,并且大量连接处于 time-wait 状态,浪费了数量有限的本地端口。

发现该问题后,我们进行了及时修复,然后问题来了。

nginx 的请求日志显示,keep-alive 真正生效以后,502 响应的数量有所增多,大部分业务系统对此不敏感,但有个别系统因 502 响应而频繁告警,这些系统在 keep-alive 没有生效之前,没有遇到 502 响应。

调查工作开始。

502 响应占比很少很少,并且出现的时机不明,一开始毫无头绪,通过翻阅 nginx 的日志和分析抓取的部分报文发现,出现 502 响应时,nginx 向 upstream 转发请求后,立即收到了 RST 报文:连接被 pod 断开了

Nginx 转发给 Pod 的请求中指定了 keep-alive,连接也持续了较长时间,来回有过多次请求了,为什么会突然被 Pod 断开连接呢?

各种胡思乱想之后,将目标锁定为在 Pod 中运行的业务系统。在 Pod 中运行的业务系统是一个 tomcat 服务,tomcat 本身就是一个请求代理软件。

事实上,客户端发起的请求经过了两次代理,第一次由 nginx 代理到 Pod 中的 tomcat,第二次由 tomcat 代理到处理该请求的进程。

翻看 tomcat 的配置手册时,发现 tomcat 有几个和 nginx 类似的配置,它们分别指定了长连接的闲置超时时间(keepAliveTimeout)和长连接中的请求数量上限(maxKeepAliveRequest)。

使用nginx的ingress时遇到的502问题怎么解决

image

使用nginx的ingress时遇到的502问题怎么解决

image

很巧的是,这两个配置项的默认值和 nginx 中类似配置的默认值相同,都是连接闲置 60s 秒后断开,以及连接中请求数量达到 100 后,断开连接。那么问题来了,nginx 和 tomcat 谁会先断开连接?

从捕获的报文来看,有时候是 tomcat 先断开的,nginx 后知后觉依旧转发请求,结果收到了 RST 大礼包,继而回应 502。502 错误码含义正是:上游返回了非预期的数据。

随后我们分析了另一个有同样问题的 python 服务,这个 python 服务也不是直接监听端口处理请求的,而是用 Gunicorn 代理。查了一下 Gunicorn 的默认配置,更夸张,它的连接闲置超时时间是 2 秒!

分析该 python 服务的报文时还在纳闷,为什么它的连接很快就断开?一度让我们怀疑前面的假设,直到发现它的默认超时时间是 2 秒,才释然:报文显示,连接正是在闲置 2 秒之后,被 Pod 端主动断开的!

使用nginx的ingress时遇到的502问题怎么解决

image

要避免 Pod 先断开连接,方法其实很简单,让 nginx 中的相关配置小于 Pod 中的代理软件的相关配置即可。譬如tomcat 的 maxKeepAliveRequest 是 100,那么 nginx 中配置成 99,确保连接是被 nginx 主动断开的。

这里只大概说明一下原委,查看当时的调查记录,点击「阅读原文」。

另外还有一个 504 的问题,504 其实是 kube-apiserver 的配置错误导致的,因为配置错误导致 endpoints 没有及时更新,继而导致 nginx 的配置文件没有更新。

Nginx 的 upstream 配置中的 IP 地址早已不存在,或者已经分配给其它 Pod,从而导致客户端收到 504 响应或者得到的是另一个服务的响应。

以上就是“使用nginx的ingress时遇到的502问题怎么解决”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注创新互联行业资讯频道。


分享标题:使用nginx的ingress时遇到的502问题怎么解决
分享地址:http://scyanting.com/article/joejjg.html