【问题标题】:Error on Websocket Implementation on Azure Kubernetes Cluster Not workingAzure Kubernetes 集群上的 Websocket 实现错误不工作
【发布时间】:2020-08-03 19:29:10
【问题描述】:

我正在尝试使 websocket 服务在我们组织环境中的 Azure Kubernetes 集群上运行。 我现有的环境也有 REST api 和 Angular 应用程序使用 ssl 处理入口。 但是当我在入口添加 websocket 服务时,它不起作用。

所以,我尝试使用 Azure 免费订阅首先实现相同的无 SSL。对于我的应用程序,我启用了 Http Routing 并使用注释 addon-http-application-routing。

我遇到了错误。 'ws://40.119.7.246/ws' 失败:WebSocket 握手期间出错:意外响应代码:404

请帮忙确认我哪里做错了?

下面是配置的详细信息。

Dockerfile

FROM node:alpine
WORKDIR /app
COPY package*.json /app/
RUN npm install

COPY ./ /app/
RUN npm run build

CMD ["node","./dist/server.js"]

EXPOSE 8010

socketserver.yaml - 包含部署和服务。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: socketserver
spec:
  replicas: 1
  selector:
    matchLabels:
      app: socketserver
  template:
    metadata:
      labels:
        app: socketserver
    spec:
      containers:
      - name: socketserver
        image: regkompella.azurecr.io/socketserver:1.0.0
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 8010
      imagePullSecrets:
      - name: regkompella-azurecr-io
---
apiVersion: v1
kind: Service
metadata:
  name: socketserver-svc
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8010
  selector:
    app: socketserver
  type: ClusterIP
---

ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: demo-ingress
  annotations:
    kubernetes.io/ingress.class: addon-http-application-routing
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/proxy-body-size: 10m
    nginx.ingress.kubernetes.io/websocket-services: socketserver-svc
    nginx.org/websocket-services: socketserver-svc
spec:
  rules:
  - host: demosocket.com
  - http:
      paths:
      - path: /
        backend:
          serviceName: angular-application-svc
          servicePort: 80
      - path: /ws
        backend:
          serviceName: socketserver-svc
          servicePort: 80

【问题讨论】:

  • 你是如何测试的?我可以在你的入口配置中看到主机`host:demosocket.com`,但在你的测试中'ws://40.119.7.246/ws。错误 404 是正确的,因为你什么都没有使用主机 demosocket.com nginx 入口不识别这个 IP 只是主机。您可以使用在您的主机文件中配置的demosocket.com 进行测试,您使用curl -H 'Host: demosocket.com' http://40.119.7.246/ws
  • 这是一个虚拟主机,我将其命名为 demosocket.com。但同样,我想用我的 ingress 的公共 IP,我可以测试它。这不是真的吗?我是否需要在入口处注明主机名?
  • 我尝试将入口公共 IP 的 DNS 名称赋予这个名称 demosocket.southcentralus.cloudapp.azure.com。并指出它也是 ingress.yaml 上的主机名。当我尝试连接时,出现以下错误。 ** index.js:15 WebSocket 连接到“ws://demosocket.southcentralus.cloudapp.azure.com/ws”失败:WebSocket 握手期间出错:意外响应代码:404**
  • @KoopaKiller - 我有些想念你在聊天中的最后一条评论。我也尝试使用 demosocket.com 和 dns 名称进行卷曲。使用 demosocket.com 我得到了 404 并且 DNS 名称返回给我 curl -H 'demosocket.southcentralus.cloudapp.azure.com' 20.45.1.216/ws 308 永久重定向

    308 永久重定向


    nginx/1.15.3
    跨度>

标签: websocket kubernetes-ingress nginx-ingress azure-aks


【解决方案1】:

在阅读了很多文章并参考了一些github论坛之后(在下面添加了参考文章)。在做了这两件事之后,我的 websocket 实现开始工作了。我还不确定这是否是正确的方法。我完全通过跟踪和错误方法实现了这个解决方案。因此,我要求每个掌握良好的人,请提出是否有更好的方法来解决我的问题。总是小心翼翼地迈出我的步伐。

  1. link 安装了NGINX Ingress 控制器。

在使用 Azure Kubernetes 服务时,我应用了文档中的以下 yaml。

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud/deploy.yaml
  1. 接下来,我对我的服务的演示入口配置进行了必要的更改。

我知道 kubernetes.io/ingress.class: addon-http-application-routing 注解不支持 websocketing。所以,不得不禁用它。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: demo-ingress
  annotations:
    # this one annotation is making the websocket work.
    nginx.ingress.kubernetes.io/websocket-services: socketserver-svc

    # this one I left as-is. And not playing any role for this websocket 
    # implementation to work
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, OPTIONS"

    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/proxy-body-size: 10m

    # I thought sticky session is also required for websocket to work. But seems 
    # this has no effect after I installed nginx ingress controller.
    # so disabled all the below annotations also.

    #nginx.org/websocket-services: socketserver-svc
    #nginx.ingress.kubernetes.io/affinity: cookie
    #nginx.ingress.kubernetes.io/affinity-mode: balanced
    #nginx.ingress.kubernetes.io/session-cookie-samesite: Strict
    #kubernetes.io/ingress.class: nginx
    #kubernetes.io/ingress.class: addon-http-application-routing

spec:
  rules:
  - host: demosocket.com
  - http:
      paths:
      - path: /ws
        backend:
          serviceName: socketserver-svc
          servicePort: 80
  1. 我尝试通过公共 IP 地址访问。而且我可以成功发送和接收消息。

ws://52.188.38.118/ws

现在,如果我想在不安装 NGINX 入口控制器(在步骤 1 中指出)的情况​​下使 websocket 实现工作,并且想尝试使用 AKS/minikube 附带的默认入口控制器,该怎么办。答案如下。

根据以上步骤,

a) 避免第 1 步:安装 NGINX 入口控制器。

b) 下面只有需要对入口进行的更改。在入口 yaml 文件中使用以下注释而不是步骤 2 中指示的注释。事情将开始运作。

# this annotation is making my web application also work if I plan to configure something in future.
nginx.ingress.kubernetes.io/ingress.class: nginx

# this one annotation is making the websocket work.
nginx.ingress.kubernetes.io/websocket-services: socketserver-svc

# by default ssl is true - as I am trying locally and want to disable ssl-# redirect. So set this to false.
nginx.ingress.kubernetes.io/ssl-redirect: "false"

# Below are just additional annotation to allow CORS etc.
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, OPTIONS"
nginx.ingress.kubernetes.io/proxy-body-size: 10m

参考文章:

  1. https://medium.com/flant-com/comparing-ingress-controllers-for-kubernetes-9b397483b46b

  2. https://kubernetes.github.io/ingress-nginx/deploy/#azure

  3. 先生。 dstrebel 的 cmets -> https://github.com/Azure/AKS/issues/768

    我通常建议只在集群上设置一个入口控制器而不启用“http-application-routing”,因为它有很多限制。 HTTP 应用程序路由的目标是让用户使用 Ingress 快速进行设置,但由于配置限制,并非真正用于生产部署。

  4. DenisBiondic 于 2018 年 10 月 2 日发表评论 -> https://github.com/Azure/AKS/issues/672

    我不是 100% 确定,因为我不使用应用程序路由功能,但 >我认为它不使用 https://github.com/nginxinc/kubernetes-ingress/tree/master/examples/websocket 控制器,而是使用 https://github.com/kubernetes/ingress-nginx。如果是后者,我认为启用 cookie 的会话亲和性可能就足够了:https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md#session-affinity

    在您的情况下,您使用了错误的注释,该注释不适用于后台的应用程序路由入口控制器。

我欢迎提出建议和最佳做法。

【讨论】:

  • 即使我找到了问题的解决方案,但我仍在思考如何在不安装 NGINX 入口控制器的情况下解决这个问题,而 AKS 上只有入口控制器可用?我要求每个人提供你的想法。这将帮助我节省一些运行 NGINX 入口控制器所需的 cpu 进程。
  • 我在上一条评论中添加了解决方案。感谢所有试图指导我找到这些解决方案的人。
猜你喜欢
  • 2020-11-06
  • 2019-04-24
  • 2020-01-18
  • 2023-04-02
  • 1970-01-01
  • 2020-03-26
  • 1970-01-01
  • 2019-02-01
  • 2016-03-22
相关资源
最近更新 更多