Nginx 入口控制器 websocket 支持

Posted

技术标签:

【中文标题】Nginx 入口控制器 websocket 支持【英文标题】:Nginx ingress controller websocket support 【发布时间】:2019-03-23 19:57:18 【问题描述】:

最近我一直在使用 Kubernetes 开发一个玩具应用程序。该应用程序的一部分是需要支持 WebSockets 的 Web 服务器。目前,我正在使用端口转发来访问 Web 服务器,一切正常。

我想改用 Ingress 和 IngressController 来避免使用端口转发。

这是我的Ingress 配置:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/secure-backends: "true"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
spec:
  rules:
  - http:
      paths:
      - path: /app
        backend:
          serviceName: web-svc
          servicePort: 3030
      - path: /ws
        backend:
          serviceName: web-svc
          servicePort: 3030

现在通过$(minikube ip)/app 访问应用程序可以正常工作,但是 WebSocket 请求都失败了,因为 nginx 返回的是 200 而不是 101。

我尝试添加 nginx.org/websocket-services 注释,但这似乎也不起作用。

有没有人遇到过类似的情况?

干杯

【问题讨论】:

根据kubernetes.github.io/ingress-nginx/user-guide/miscellaneous/… "对 websockets 的支持由 NGINX 开箱即用。无需特殊配置。"但我无法让它工作。由于两个 nginx 控制器,也很容易混淆。见nginx.com/blog/… 关于超时的引号对于较新的 k8s 版本似乎很重要 【参考方案1】:

通过查看nginx ingress controller docs 和nginx docs,您可能需要这样的东西作为您的Kubernetes Ingress 上的注释:

nginx.ingress.kubernetes.io/configuration-snippet: |
   proxy_http_version 1.1;
   proxy_set_header Upgrade "websocket";
   proxy_set_header Connection "Upgrade";

请注意,一旦您添加了该注释,您的所有 Ingress 规则将在您的 nginx 配置中的 location 块中包含该 sn-p。因此,如果您想在其他规则中忽略它,则必须创建一个单独的 Kubernetes Ingress

编辑:

根据gist 和Nginx ingress docs ?,这个注释似乎解决了问题:

nginx.ingress.kubernetes.io/proxy-read-timeout: 3600
nginx.ingress.kubernetes.io/proxy-send-timeout: 3600

【讨论】:

我还在战斗。当我了解问题时,我会在这里发表评论 好的,我做到了。我已经在这个要点中描述了工作配置:gist.github.com/jsdevtom/… @Tom 你能描述一下重要的部分吗?我似乎错过了你的要点。 我同意。 @tom 在你的 sn-p 我找不到 nginx-ingress 配置 sn-p 关于它是如何工作的你所拥有的是入口规则而不是入口控制器注释。 编辑了问题,好像是超时注释【参考方案2】:

这些对我有用。

他们似乎通过注释添加了支持 (example in docs):

nginx.org/websocket-services: "service1[,service2,...]"

我用telsocket 测试了我的连接,这是一个连接到 WS/WSS 套接字的小工具。

有各种不同的客户端,这也可能有助于找到连接的罪魁祸首。

重要提示:有两个 nginx 入口控制器可用,更多信息here。

此答案仅限于 nginxinc 版本,与问题中使用的不同,接受的答案是目前唯一的解决方案。

【讨论】:

从哪个版本开始支持? 基于链接文件的 git 历史记录,从 v1.12.1 开始。您可以检查提交 here 。 我的错,它是从 2016 年开始收录的,所以包含此代码的第一个标签是:v0.3。 这只适用于 NGINX Inc 控制器吗? 是的,不幸的是它仅限于 nginxinc 版本。

以上是关于Nginx 入口控制器 websocket 支持的主要内容,如果未能解决你的问题,请参考以下文章

Nginx支持WebSocket配置

nginx支持websocket

centos nginx配置支持WebSocket(signalR)

具有多个入口资源对象的 Kubernetes nginx 入口控制器

sentinel系统规则

Nginx支持WebSocket服务