【问题标题】:Ingress-nginx on GKE configuration 502 bad gatewayGKE 配置 502 错误网关上的 Ingress-nginx
【发布时间】:2020-08-26 16:21:39
【问题描述】:

我正在尝试通过 ingress-nginx 和谷歌云负载均衡器在 GKE 集群中公开一个 mlflow 模型。

各个部署的服务配置如下:

apiVersion: v1
kind: Service
metadata:
  name: model-inference-service
  labels:
    app: inference
spec:
  ports:
  - port: 5555
    targetPort: 5555
  selector:
    app: inference

当使用kubectl port-forward service/model-inference-service 5555:5555将此服务转发到本地主机时,我可以通过使用以下script向api端点发送测试图像来成功查询模型。

请求发送到的 url 是http://127.0.0.1:5555/invocations这按预期工作,因此我假设运行暴露模型的 pod 的部署和相应的 clusterIP 服务 model-inference-service 配置正确。

接下来,我将 ingress-nxinx 安装到集群中

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install my-release ingress-nginx/ingress-nginx

入口配置如下(我怀疑错误一定在这里?):

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
#    nginx.ingress.kubernetes.io/rewrite-target: /invocations
  name: inference-ingress
  namespace: default
  labels:
    app: inference
spec:
  rules:
    - http:
        paths:
          - path: /invocations
            backend:
              serviceName: model-inference-service
              servicePort: 5555

入口控制器 pod 运行成功:

my-release-ingress-nginx-controller-6758cc8f45-fwtw7   1/1     Running   0          3h33m

在 GCP 控制台中,我可以看到负载均衡器也已成功创建,我可以选择其 IP。

当使用我之前使用的相同测试脚本向 Rest api 端点发出请求(之前服务被转发到 localhost)但现在使用负载均衡器的 ip 时,我收到 502 Bad Gateway 错误:

网址现在如下:http://34.90.4.0:80/invocations

Traceback (most recent call last):
  File "test_inference.py", line 80, in <module>
    run()
  File "//anaconda3/lib/python3.7/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "//anaconda3/lib/python3.7/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "//anaconda3/lib/python3.7/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "//anaconda3/lib/python3.7/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "test_inference.py", line 76, in run
    print(score_model(data_path, host, port).text)
  File "test_inference.py", line 54, in score_model
    status_code=response.status_code, text=response.text
Exception: Status Code 502. <html>
<head><title>502 Bad Gateway</title></head>
<body>
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.19.1</center>
</body>
</html>

在浏览器中访问相同的 url 时会显示:

502 Bad Gateway
nginx/1.19.1

入口控制器状态的日志:

2020/08/26 16:06:45 [warn] 86#86: *42282 a client request body is buffered to a temporary file /tmp/client-body/0000000009, client: 10.10.0.30, server: _, request: "POST /invocations HTTP/1.1", host: "34.90.4.0"
2020/08/26 16:06:45 [error] 86#86: *42282 connect() failed (111: Connection refused) while connecting to upstream, client: 10.10.0.30, server: _, request: "POST /invocations HTTP/1.1", upstream: "http://10.52.3.7:5555/invocations", host: "34.90.4.0"
2020/08/26 16:06:45 [error] 86#86: *42282 connect() failed (111: Connection refused) while connecting to upstream, client: 10.10.0.30, server: _, request: "POST /invocations HTTP/1.1", upstream: "http://10.52.3.7:5555/invocations", host: "34.90.4.0"
2020/08/26 16:06:45 [error] 86#86: *42282 connect() failed (111: Connection refused) while connecting to upstream, client: 10.10.0.30, server: _, request: "POST /invocations HTTP/1.1", upstream: "http://10.52.3.7:5555/invocations", host: "34.90.4.0"
10.10.0.30 - - [26/Aug/2020:16:06:45 +0000] "POST /invocations HTTP/1.1" 502 157 "-" "python-requests/2.24.0" 86151 0.738 [default-model-inference-service-5555] [] 10.52.3.7:5555, 10.52.3.7:5555, 10.52.3.7:5555 0, 0, 0 0.000, 0.001, 0.000 502, 502, 502 0d86e360427c0a81c287da4ff5e907bc

为了测试入口和负载均衡器是否在原则上正常工作,我将 docker 映像替换为我想用这个 docker image 公开的真正的 rest api,它在端口 5050 和路径 / 上返回“hello world”。我在上面显示的服务和入口清单中更改了端口和路径(从/invocations/),并且在浏览器中访问负载均衡器的 ip 时可以成功看到“hello world”。

有人知道我可能做错了什么吗? 非常感谢!

最好的问候,

F

【问题讨论】:

  • 你能分享来自调用服务 pod 的日志吗?它是否收到来自入口的任何请求?
  • 遗憾的是,使用kubectl logs &lt;pod id&gt; 获得的日志不包含有关向服务器发出的请求的任何信息。通过从集群转发到本地主机的服务/端口发出成功请求时也不会。在 pod 中运行的 Mlflow 使用 nginx 和 gunicorn。我附加到 pod,找到了 nginx.conf,但文件 access_log /var/log/nginx/access.log 在此 pod 上不存在。不幸的是,我不知道日志在哪里可以告诉我 pod 是否收到来自入口的任何请求。 Mlflow 文档没有给出答案。我可以尝试什么?
  • 使用mendhak/http-https-echo 图像并检查服务器接收到的路径和数据(您可以将其添加到您的问题中)。也可以尝试不使用rewrite-target 注释。

标签: nginx kubernetes kubernetes-ingress nginx-config nginx-ingress


【解决方案1】:

您共享的配置看起来不错。您的集群环境中一定有某些东西导致了这种行为。查看 pod 到 pod 的通信是否正常。在与 Nginx 入口控制器相同的节点上启动一个测试 pod,并从该 pod 到目标服务执行curl。查看您是否遇到任何 DNS 或网络问题。在调用服务时尝试更改主机头,看看它是否对此敏感。

【讨论】:

    猜你喜欢
    • 2019-10-21
    • 2011-05-14
    • 2019-06-05
    • 2015-08-10
    • 2021-09-11
    • 1970-01-01
    • 2014-01-30
    • 2021-11-19
    • 2012-09-25
    相关资源
    最近更新 更多