我们在由 Rancher (2.5.7) 管理的 k8s 集群 (v.1.17) 上使用 nginx (1.15.8.1) 作为入口控制器。
到目前为止,一切都运行良好,但现在我们设置了一个可以通过入口从外部访问的自定义 API pod。
现在,通过每秒向 API 发出请求对 API 进行一些负载测试,每隔几个请求就会随机返回“502 Bad Gateway”。但不是定期返回。
<html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>openresty/1.15.8.1</center>
</body>
</html>
相应登录入口控制器:
2021/04/11 11:02:48 [error] 25430#25430: *55805583 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: xxx, server: xxx, request: "POST /api/v1/xxx HTTP/2.0", upstream: "http://xxx/api/v1/xxx", host: "xxx"
我们在非 K8s 环境中运行了与 Docker 容器完全相同的容器,以前从未遇到过此问题,因此目前我认为这不是容器/API 实现的问题。
我的想法是:
1-抽象 API pod 的服务定义无法将流量路由到 pod,因此回复 502
-> 我更改了入口,直接进入工作负载进行测试,以了解这是否是问题所在。然后我得到了同样的错误,所以服务定义似乎不是问题
2- 入口资源超时(因为帖子回复有延迟)可能会导致路由失败
-> 我将超时设置为
nginx.ingress.kubernetes.io/proxy-connect-timeout: 1d
nginx.ingress.kubernetes.io/proxy-read-timeout: 1d
nginx.ingress.kubernetes.io/proxy-send-timeout: 1d
但再次出现同样的错误。所以这似乎也不是问题
3- API 容器出错(可能性最小),返回错误
-> 检查容器日志发现,API 容器从未收到丢失的请求(返回 502 或任何类似信息,然后在入口级别评估为 502)。此外,从流量路由的角度来看,这根本没有意义。
4-最后一步,我将 pod 扩大到两个容器,一切都运行良好。
总结:根据以上结果,我总结出:1- 服务定义不可能是问题(测试 1)2- 入口超时不可能是问题 3- API 本身不可能是问题
考虑测试 4,它指出了一个方向,即当容器处于特定状态时,API 会丢弃请求(导致 502)(这可以解释为什么它可以与 2 个容器扩展一起使用)或流量路由在途中的某个地方超时。
目前我还不知道接下来该怎么做。如有任何提示,我将不胜感激。
答案1
如果您使用 nginx 入口反向代理,这可能是原因。尝试检查 Configmap 中的proxy-next-upstream
设置,并扩展它以处理这种http_502
情况。如果收到 502 的请求是 POST、LOCK、PATCH,
则启用它retry-non-idempotent
,如果您的应用程序这样做是安全的。
我的猜测是:当后端 pod 达到其负载限制(或 pod 回收)时,它会“拒绝”新请求,而 nginx 反向代理对这种拒绝更为敏感。如果没有 nginx-ingress,k8s 会处理负载平衡,它可以更好地处理所有事情,排队而不是拒绝。