k8s nginx ingress 在加载时随机返回 502 错误

mic*_*afn 5 bad-request kubernetes rancher-2 nginx-ingress

我们在 k8s 集群 (v.1.17) 上使用 nginx (1.15.8.1) 作为入口控制器,由 rancher (2.5.7) 管理。

到目前为止,这工作得很好,但现在我们设置了一个自定义 API pod,可以通过 ingress 从外部访问。

现在,通过每秒在 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>
Run Code Online (Sandbox Code Playgroud)

各自登录入口控制器:

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"
Run Code Online (Sandbox Code Playgroud)

我们在非 K8s 环境中运行与 docker 容器完全相同的容器,之前我们从未遇到过这个问题,所以目前我认为这不是容器/API 实现的问题。

我的想法是:

1- 抽象 API pod 的服务定义无法将流量路由到 pod,因此会回复 502

-> 我将入口更改为直接进入工作负载进行测试,以了解这是否是问题所在。然后我得到了同样的错误,所以服务定义似乎不是问题

2- 入口资源超时(b/c 帖子回复延迟)可能会导致路由失败

-> 我将超时设置为

    nginx.ingress.kubernetes.io/proxy-connect-timeout: 1d
    nginx.ingress.kubernetes.io/proxy-read-timeout: 1d
    nginx.ingress.kubernetes.io/proxy-send-timeout: 1d
Run Code Online (Sandbox Code Playgroud)

但再次遇到同样的错误。所以这似乎也不是问题

3- API 容器中的错误(最不可能)发送回错误

-> 检查容器日志显示,API 容器从未收到丢失的请求(返回 502 或类似的内容,然后在入口级别评估为 502)。此外,从流量路由的角度来看,这根本没有意义。

4- 作为最后一步,我将 Pod 扩展到两个容器,一切都运行良好。

摘要:根据上面的结果,我总结出 1- 服务定义不可能是问题(测试 1) 2- 入口超时不可能是问题 3- api 本身不可能是问题

考虑测试 4,它表明 Pod 中的容器可用性可能是一个问题,因为当容器处于特定状态时,API 会丢弃请求(导致 502)(这可以解释为什么它与 2 一起工作)容器扩展)或流量路由在途中某个地方超时。

目前我没有任何进一步的想法从这里去哪里。任何提示表示赞赏。

小智 4

如果您使用 nginx 入口反向代理,这可能是原因。尝试检查 Configmap 中的proxy-next-upstream设置,并扩展它来处理这种http_502情况。如果收到 502 的请求是 POST、LOCK、PATCH(如果您的应用程序这样做是安全的),
还请启用。retry-non-idempotent

我的猜测:当后端 pod 达到其负载限制(或 pod 回收)时,它会“拒绝”新请求,并且 nginx 反向代理对此拒绝更加敏感。如果没有 nginx-ingress,k8s 会处理负载平衡,它可以更好地处理所有事情,排队而不是拒绝。