WebSocket是一种网络传输协议,允许在单个TCP连接上进行双向通信,位于OSI模型的应用层。与传统HTTP请求相比,WebSocket使服务端能够主动向客户端推送数据,从而实现实时交互,适用于需要即时更新的应用场景,例如在线游戏、金融市场数据传输等。遵守WebSocket协议的服务即为WebSocket服务。本文通过示例介绍如何通过Nginx Ingress访问集群内的WebSocket服务。
前提条件
已安装了Nginx Ingress Controller组件。具体操作,请参见管理Nginx Ingress Controller组件。
已安装WebSocat工具。具体操作,请参见WebSocat。
步骤一:部署示例应用
在集群中部署示例WebSocket应用和服务。
使用以下内容,创建名为websocket.yaml文件。
apiVersion: apps/v1 kind: Deployment metadata: labels: app: ws name: websocket-server namespace: default spec: replicas: 1 selector: matchLabels: app: ws template: metadata: labels: app: ws spec: containers: - image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/websocket-echo-server:latest imagePullPolicy: IfNotPresent name: echo env: - name: BIND_PORT value: "3000" ports: - containerPort: 3000 protocol: TCP resources: limits: cpu: 1000m memory: 1000Mi requests: cpu: 100m memory: 100Mi --- apiVersion: v1 kind: Service metadata: labels: app: ws name: websocket-server namespace: default spec: ports: - name: ws port: 3000 protocol: TCP targetPort: 3000 selector: app: ws type: ClusterIP
执行以下命令,部署示例应用websocket.yaml。
kubectl apply -f websocket.yaml
步骤二:部署示例Ingress
为示例Ingress设置代理发送超时时间和代理读取超时时间规则。
使用以下内容,创建名为websocket-ingress.yaml文件。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: # 根据实际情况调整读写超时时间,默认值为60秒。 nginx.ingress.kubernetes.io/proxy-read-timeout: "600" # 设置读超时时间为600秒。 nginx.ingress.kubernetes.io/proxy-send-timeout: "600" # 设置写超时时间为600秒。 name: ws namespace: default spec: ingressClassName: nginx rules: - host: test.example.com http: paths: - backend: service: name: websocket-server port: number: 3000 path: / pathType: ImplementationSpecific
执行以下命令,部署示例Ingress。
kubectl apply -f websocket-ingress.yaml
执行以下命令,查看该应用的Ingress配置。
kubectl get ing ws
预期输出:
NAME HOSTS ADDRESS PORTS AGE ws test.example.com 47.XX.XX.53 80 8m
步骤三:通过Nginx Ingress访问WebSocket服务
执行以下命令,修改
/etc/hosts
配置文件来进行本地域名解析。echo "47.XX.XX.53 test.example.com" | sudo tee -a /etc/hosts
执行以下命令,访问WebSocket服务。
websocat ws://test.example.com/
预期输出:
说明WebSocket Server是一个回声服务,它会将您发送的请求原样返回。例如当您输入helloworld和test时,系统会相应地回显相同的内容。
步骤四: 使用WSS协议访问WebSocket服务
WSS(WebSocket Secure)协议通过HTTPS为WebSocket通信提供安全保障,确保数据在传输过程中得到保护和完整性。在使用WSS协议访问WebSocket服务之前,需要为域名test.example.com
配置HTTPS证书。
执行以下命令,使用OpenSSL生成的证书。
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=test.example.com/O=test.example.com"
执行以下命令,创建证书密钥。
kubectl create secret tls tls-test-ingress --key tls.key --cert tls.crt
执行以下命令,编辑websocket-ingress.yaml文件,新增TLS证书内容后保存并退出。
vim websocket-ingress.yaml
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: # 根据实际情况调整读写超时时间,默认值为60秒。 nginx.ingress.kubernetes.io/proxy-read-timeout: "600" # 设置读超时时间为600秒。 nginx.ingress.kubernetes.io/proxy-send-timeout: "600" # 设置写超时时间为600秒。 name: ws namespace: default spec: ingressClassName: nginx tls: # 引用TLS证书。 - hosts: - test.example.com # 证书所对应的域名。 secretName: tls-test-ingress # 引用Sercret。 rules: - host: test.example.com http: paths: - backend: service: name: websocket-server port: number: 3000 path: / pathType: ImplementationSpecific
执行以下命令,使TLS证书配置生效。
kubectl apply -f websocket-ingress.yaml
执行以下命令,访问
wss://test.example.com/
。说明如果使用OpenSSL生成的自签证书,需要加
-k
参数,否则会报错。而如果是受信任的CA签发的证书,则无需额外参数正常连接即可。websocat -k wss://test.example.com/
预期输出:
相关文档
在ACK中哪些网关支持WebSocket协议,请参见Nginx Ingress、ALB Ingress和MSE Ingress对比。
如果您需要维持较长时间的WebSocket连接,建议您配置自定义超时设置。关于自定义超时Annotation,请参见Custom timeouts。