基于云原生网关实现WebSocket服务的转发

WebSocket协议实现了客户端与服务器间的持续、双向通讯,确保了连接的持久性和低延迟。在Kubernetes集群外部访问WebSocket服务时,云原生网关承担了请求接收和转发的角色,根据预定的路由规则将请求分发到相应的后端服务。本文介绍了如何在容器服务 Kubernetes 版集群部署WebSocket应用,并通过云原生网关进行流量转发。

前提条件

步骤一:使用容器服务部署WebSocket应用

应用部署的具体操作,请参见创建无状态工作负载Deployment

在本示例中,使用容器服务K8s原生的服务发现方式,即通过声明式Service API资源将后端服务注册到CoreDNS。示例中的后端服务提供了多个WebSocket接口,在容器服务ACK中应用如下资源:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: sockbin
  name: sockbin-app
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 2
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: sockbin
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: sockbin
    spec:
      containers:
        - image: therebelrobot/sockbin
          imagePullPolicy: Always
          name: sockbin
          ports:
            - containerPort: 4080
              protocol: TCP
          resources:
            limits:
              cpu: 500m
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: sockbin
  name: sockbin-service
  namespace: default
spec:
  ports:
    - name: http
      port: 4080
      protocol: TCP
      targetPort: 4080
  selector:
    app: sockbin
  sessionAffinity: None
  type: NodePort

步骤二:使用云原生网关作为WebSocket的路由分发

添加ACK集群作为网关的服务来源并添加Sockbin服务。

添加服务来源

  1. 登录MSE管理控制台,并在顶部菜单栏选择地域。

  2. 在左侧导航栏,选择云原生网关 > 网关列表,单击目标网关名称。

  3. 在左侧导航栏,选择路由管理,然后选择来源页签。

  4. 单击创建来源并配置相关参数,配置完成后单击确定

    配置项

    描述

    来源类型

    选择容器服务服务来源。

    ACK/ACK Serverless集群

    选择后端服务所在的集群。

    监听K8s Ingress

    开启监听Ingress配置后,云原生网关会自动监听Ingress资源的变化,并生效Ingress资源中域名、路由的相关配置。

    关闭监听Ingress配置后,云原生网关会放弃监听Ingress资源,同时,之前已监听的Ingress资源中域名、路由相关配置会失效。

    说明

    通过管控手动配置的域名、路由的相关配置的优先级高于Ingress资源。

添加服务

  1. 登录MSE管理控制台,并在顶部菜单栏选择地域。

  2. 在左侧导航栏,选择云原生网关 > 网关列表,单击目标网关名称。

  3. 在左侧导航栏,选择路由管理,然后选择服务页签。

  4. 单击创建服务并配置相关参数,然后单击确定

    配置项

    说明

    服务来源

    选择容器服务

    命名空间

    选择目标集群的命名空间。

    服务列表

    在服务列表中选择服务。

添加网关到Sockbin服务的路由

  1. 登录MSE管理控制台,并在顶部菜单栏选择地域。

  2. 在左侧导航栏,选择云原生网关 > 网关列表,单击目标网关名称。

  3. 在左侧导航栏,单击路由管理,然后选择路由页签。

  4. 单击创建路由并配置相关参数,然后单击保存并发布

    配置项

    说明

    路由名称

    设置为sockbin-route

    域名

    选择默认关联域名*。

    路径(Path)

    选择匹配条件为前缀是,Path以/开头。

    使用场景

    选择使用场景为单服务

    后端服务

    选择目标服务以及服务端口

结果验证

本文为您提供两种方式来验证WebSocket服务可用性。

方式一:通过Sockbin服务的界面直接进行测试

  1. 登录MSE管理控制台,并在顶部菜单栏选择地域。

  2. 在左侧导航栏,选择云原生网关 > 网关列表,单击目标网关名称。

  3. 在网关基本概览页面,找到网关入口页签,在绑定的SLB中找到公网入口地址,在浏览器中访问入口地址。

    网关会根据WebSocket握手时携带的域名和Path进行路由,即可得到Sockbin服务的界面。sockbin服务的界面

方式二:使用各种语言的WebSocket客户端进行测试

例如,使用Python的WebSocket客户端来得到一个延迟1秒的服务端响应。

#!/usr/bin/env python

import asyncio
import websockets

async def hello():
    async with websockets.connect("ws://ip_addr/delay/1000") as websocket:
        await websocket.send("Hello Test")
        text = await websocket.recv()
        print(text)

asyncio.run(hello())