向应用程序网关公开 WebSocket 服务器

如应用程序网关 v2 文档中所述,它为 WebSocket 和 HTTP/2 协议提供本机支持。 应用程序网关和 Kubernetes Ingress 都没有用户可配置的设置来选择性地启用或禁用 WebSocket 支持。

以下 Kubernetes 部署 YAML 显示用于部署 WebSocket 服务器的最小配置,它与部署常规 Web 服务器相同:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: websocket-server
spec:
  selector:
    matchLabels:
      app: ws-app
  replicas: 2
  template:
    metadata:
      labels:
        app: ws-app
    spec:
      containers:
        - name: websocket-app
          imagePullPolicy: Always
          image: your-container-repo.azurecr.io/websockets-app
          ports:
            - containerPort: 8888
      imagePullSecrets:
        - name: azure-container-registry-credentials

---

apiVersion: v1
kind: Service
metadata:
  name: websocket-app-service
spec:
  selector:
    app: ws-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8888

---

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: websocket-repeater
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
spec:
  rules:
    - host: ws.contoso.com
      http:
        paths:
          - backend:
              serviceName: websocket-app-service
              servicePort: 80

鉴于满足了所有先决条件,并且 AKS 中有由 Kubernetes Ingress 控制的应用程序网关,那么前面显示的部署将导致在应用程序网关的公共 IP 和 ws.contoso.com 域的端口 80 上暴露 WebSocket 服务器。

以下 cURL 命令会测试 WebSocket 服务器部署:

curl -i -N -H "Connection: Upgrade" \
        -H "Upgrade: websocket" \
        -H "Origin: http://localhost" \
        -H "Host: ws.contoso.com" \
        -H "Sec-Websocket-Version: 13" \
        -H "Sec-WebSocket-Key: 123" \
        http://1.2.3.4:80/ws

WebSocket 运行状况探测

如果部署未显式定义运行状况探测,应用程序网关会在 WebSocket 服务器终结点上尝试 HTTP GET。 根据服务器实现情况(这里有一个我们喜欢的),可能需要特定于 WebSocket 的标头(例如 Sec-Websocket-Version)。 由于应用程序网关不添加 WebSocket 标头,因此来自 WebSocket 服务器的应用程序网关的运行状况探测响应很可能是 400 Bad Request。 因此,应用程序网关将你的 Pod 标记为不正常。 此状态最终会为 WebSocket 服务器的使用者带来 502 Bad Gateway。 为了避免网关错误,你可能需要将运行状况检查的 HTTP GET 处理程序添加到服务器(例如 /health,它会返回 200 OK)。