istio 配置实现socket.io 的集群模式(原创)
istio是一个完全开源的服务网格,作为透明的一层接入到现有的分布式应用里。通过对网格的定义,将应用集群化,灵活控制应集群的通讯。在网络控制上支持4-7层的协议,目前的kubernetes自带的ingress和traefik只支持7层协议(如http和https)。它也是一个平台,拥有可以集成任何日志、遥测和策略系统的 API 接口。Istio 多样化的特性方便使用者成功且高效地运行和调试分布式微服务架构,并提供保护、连接和监控微服务的统一方法。
参考文章:《kubernetes 下实现socket.io 的集群模式》介绍了在kubernetes下通过traefik实现socket.io的集群化。以下称参考文章。
问题与解决思路
socket.io 单节点模式是很容易部署的,但是往往在生产环境单节点不能满足业务需求可靠性和大负载变化的需求,需要提供一个可伸缩的集群环境。具体问题的现象与解决思路请参考上述参考文章。
我们尝试在istio环境下部署参考文章的应用,在用例上我们也沿用参考文章的用例与测试方式。
istio下的配置
1.环境:
使用kubernetes环境,建立自动注入的名字空间(namespace) istio-wb-server,参考istio的配置
2.发布redis.
由于镜像需要使用redis服务,其服务名为"redis",端口为6379,我们简单起见发布一个单点的redis, 发布集群参考其他文章。
$vi istio-redis-dp.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: redis
namespace: istio-wb-server
labels:
app: redis
spec:
selector:
matchLabels:
app: redis
role: master
tier: backend
replicas: 1
template:
metadata:
labels:
app: redis
role: master
tier: backend
spec:
containers:
- name: master
image: redis:3.2
resources:
limits:
cpu: "1"
memory: "2Gi"
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 6379
$ kubectl apply -f istio-redis-dp.yaml
$ vi istio-redis-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: istio-wb-server
labels:
app: redis
spec:
ports:
- name: redis
port: 6379
protocol: TCP
targetPort: 6379
selector:
app: redis
kubectl apply -f istio-redis-svc.yaml
- 发布应用
$vi istio-wb-dp.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: wb
namespace: istio-wb-server
labels:
app: wb
spec:
selector:
matchLabels:
app: wb
replicas: 3
template:
metadata:
labels:
app: wb
spec:
containers:
- name: wb
image: cnych/socketdemo:k8s #与参考文章一样
imagePullPolicy: Always
ports:
- containerPort: 3000
protocol: TCP
resources:
limits:
cpu: 100m
memory: 100Mi
requests:
cpu: 50m
memory: 50Mi
$kubectl apply -f istio-wb-dp.yaml
$ cat istio-wb-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: wb-svc
namespace: istio-wb-server
labels:
app: wb
spec:
ports:
- port: 3000
name: http
selector:
app: wb
$kubectl apply -f istio-wb-svc.yaml
5.测试wb 应用,将服务端口映射到本地,检查服务是否正常。
kubectl port-forward -n istio-wb-server svc/wb-svc 3000:3000
浏览器访问 : http://127.0.0.1:3000/
此时,不同机器的不同浏览器的白板可能不互通。
6.配置istio路由.根据请求的header中cockie 内的io值 hash 的istio路由到pod,也可以在应用中通过设置chanelID或roomID的cockie来实现路由hash。
$ vi istio-wb-gw.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: wb-gateway
namespace: istio-wb-server
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 3000
name: wb
protocol: http
hosts:
- "wb.example.com" # 配置你的网址
$kubectl apply -f istio-wb-gw.yaml
$ vi istio-wb-vs.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: istio-wb-vs
namespace: istio-wb-server
spec:
hosts:
- wb.example.com # 配置你的网址
gateways:
- wb-gateway
http:
- match:
- port: 3000
route:
- destination:
host: wb-svc.istio-wb-server.svc.cluster.local
port:
number: 3000
$kubectl apply -f istio-wb-vs.yaml
$ vi istio-wb-dr.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: wb-dr
namespace: istio-wb-server
spec:
host: wb-svc.istio-wb-server.svc.cluster.local
trafficPolicy:
loadBalancer:
consistentHash:
httpCookie:
name: io
ttl: 0s
$kubectl apply -f istio-wb-dr.yaml
7.检查istio-system空间中的istio-ingressgateway 服务是否开启映射3000端口,如果不映射出来外部无法访问。
8.测试
用浏览器访问
http:// wb.example.com:3000 #(假设example.com 是你的域名)
应该能看到参考文章的画面。从不同的浏览器和不同的机器访问,白板内容都是相通的。
9.故障诊断方法
在istio的目录下
$./bin/istioctl dashboard kiali
在浏览器中启动图形化界面,登录其中:
查看各组件是否报错,纠正错误。
还可以通过选择看到服务间通讯的关系,如下图:
后记
以上描述的是一个在istio上配置过程,不涉及socket.io和应用程序的原理。
另外,特别感谢参考文章作者的分析与提供的实验镜像!
参考
1.《kubernetes 下实现socket.io 的集群模式》 2.istio destination-rule