代码之家  ›  专栏  ›  技术社区  ›  Yehuda

GKE Ingress在使用HTTPS时丢弃WebSocket连接

  •  1
  • Yehuda  · 技术社区  · 6 年前

    我有一个入口(默认的gke-one),它在我的服务之前处理所有的SSL。我的服务之一是WebSocket服务(python autobahn)。当我使用LoadBalancer公开服务时,不通过抛出入口,使用WS://EverythousWorkingGood。相反,当我使用nodeport暴露它并通过入口时,我经常看到连接正在下降,即使没有客户机连接。以下是自动驾驶仪:

    WARNING:autobahn.asyncio.websocket.WebSocketServerProtocol:dropping connection to peer tcp:10.156.0.58:36868 with abort=False: None
    

    当我使用带有wss/的客户机连接时,连接成功,但是 每隔几秒钟发生一次断开(无法获得一致的数字)。 虽然我不认为这是相关的,但我将gce中相关后端服务的超时时间更改为3600秒,并尝试使用clientip和cookie赋予它会话关联性,但似乎没有一个可以阻止断开连接。 这是我的入口定义:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: {{ .Values.ingressName }}-ingress
      annotations:
          kubernetes.io/ingress.global-static-ip-name: {{ .Values.staticIpName }}-static-ip
      labels:
        oriient-app: "rest-api"
        oriient-system: "IPS"
    spec:
      tls:
      - secretName: sslcerts
      rules:
      - host: {{ .Values.restApiHost }}
        http:
          paths:
          - backend:
              serviceName: rest-api-internal-service
              servicePort: 80
      - host: {{ .Values.dashboardHost }}
        http:
          paths:
          - backend:
              serviceName: dashboard-internal-service
              servicePort: 80
      - host: {{ .Values.monitorHost }}
        http:
          paths:
          - backend:
              serviceName: monitor-internal-service
              servicePort: 80
      - host: {{ .Values.ipsHost }}
        http:
          paths:
          - backend:
              serviceName: server-internal-ws-service
              servicePort: 80
    

    WS服务是“服务器内部WS服务”。 有什么建议吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Yehuda    6 年前

    我没有解决这个问题,但是我确实通过使用负载均衡器服务公开我的WSS绕过了这个问题,并且我自己实现了WebSocket的安全层。 我将证书(私钥和全链公钥-PEM格式)保存为机密,并将其作为卷装入,然后在python中使用sslcontex并将其传递给Asyncio循环创建服务器。

    要创建证书机密,请创建yaml:

    apiVersion: v1
    kind: Secret
    type: tls
    metadata:
      name: sslcerts
    data:
      # this is base64 of your pem fullchain and private key
      tls.crt: XXX 
      tls.key: YYY
    

    然后

    kubectl apply -f [path to the yaml above]
    

    在服务器部署中,装载机密:

        apiVersion: apps/v1beta2
        kind: Deployment
        metadata:
          labels:
            ...
          name: server
        spec:
          replicas: {{ .Values.replicas }}
          selector:
            matchLabels:
              ...
          template:
            metadata:
              labels:
                ...
            spec:
              volumes:
              - name: wss-ssl-certificate
                secret:
                  secretName: sslcerts
           containers:
            - image: ...
            imagePullPolicy: Always
            name: server
            volumeMounts:
              - name: wss-ssl-certificate
                mountPath: /etc/wss
    

    在python代码中:

     sslcontext = ssl.SSLContext()
     sslcontext.load_cert_chain(/etc/wss/tls.crt, /etc/wss/tls.key)
     wssIpsClientsFactory = WebSocketServerFactory()
     ...        
     loop = asyncio.get_event_loop()
     coro = loop.create_server(wssIpsClientsFactory, '0.0.0.0', 9000, ssl=sslcontext)
     server = loop.run_until_complete(coro)
    

    希望它能帮助别人