背景
需要在K8S集群中提供websocket服务。后端使用的是netty-socketio库实现了Socket.IO方式的ws服务。前端直接使用Socket.IO 客户端js实现。这里重点介绍AWS EKS中怎么通过启用ALB粘性会话的方式支持ws服务。
svc.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: {{ .Values.services.websocketServer.name }}
name: {{ .Values.services.websocketServer.name }}
namespace: {{ .Release.Namespace }}
annotations:
alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=60
alb.ingress.kubernetes.io/healthcheck-path: {{ .Values.services.websocketServer.health.path }}
alb.ingress.kubernetes.io/healthcheck-port: '{{ .Values.services.websocketServer.health.port }}'
prometheus.io/path: {{ .Values.services.websocketServer.prometheus.path }}
prometheus.io/port: '{{ .Values.services.websocketServer.prometheus.port }}'
prometheus.io/scrape: "true"
spec:
ports:
- name: http
port: {{ .Values.services.websocketServer.port }}
targetPort: {{ .Values.services.websocketServer.port }}
selector:
app: {{ .Values.services.websocketServer.name }}
type: ClusterIP
这里启用alb粘性会话关键就是如下一行:
alb.ingress.kubernetes.io/target-group-attributes: stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=60
ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Chart.Name }}-ingress
namespace: {{ .Release.Namespace }}
annotations:
alb.ingress.kubernetes.io/load-balancer-name: {{ .Values.ingress.name }}
{{/* alb.ingress.kubernetes.io/security-groups: {{ .Values.ingress.security.groups }}*/}}
alb.ingress.kubernetes.io/manage-backend-security-group-rules: "true"
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
alb.ingress.kubernetes.io/actions.response-503: >
{"type":"fixed-response","fixedResponseConfig":{"contentType":"text/plain","statusCode":"503","messageBody":"503 error text"}}
spec:
ingressClassName: alb
tls:
- hosts:
- {{ .Values.ingress.tls.host }}
rules:
- http:
paths:
- path: /socket.io/
backend:
service:
name: {{ .Values.services.websocketServer.name }}
port:
number: {{ .Values.services.websocketServer.port }}
pathType: Prefix
这里启用alb粘性会话关键就是如下一行:
...
# 启用ip类型模式让alb查找目标组
alb.ingress.kubernetes.io/target-type: ip
...
# 设置ingress拦截/socket.io/
- path: /socket.io/
...
总结
aws eks 的ingress对应的alb支持ws服务还是很简单的,只要启用alb粘性会话就可以支持Socket.IO方式的ws服务了。netty-socketio代码可以参考netty-socketio-demo项目。
简单的socketio前端连接代码,如下:
var socket = io('http://localhost:3000', {
query: {
"token": "xxxxx"
},
# 启用cookie
withCredentials: true
});
这个socketio客户端连接代码,回向服务端发送一个GET请求,类似如下:
http://localhost:3000/socket.io/?token=xxxxxx&EIO=4&transport=polling&t=OzO3sO5
通过这个GET请求获取到一个set-cookie:io=146b8d76-719d-417f-8a8c-bf3a6a0d741f,写完这个cookie之后
前端会把io当做sid,将通过101 Switching Protocols会话升级为ws协议。