gRPC服务端通过调用变量GRPC_SERVER
定义的服务grpc-server-svc.grpc-best.svc.cluster.local,将请求均匀地路由到4个编程语言版本的服务端上,本文介绍如何在ACK上部署gRPC服务端的Service,并对Service的负载均衡进行验证。
背景信息
4个编程语言版本的客户端通过调用变量
GRPC_SERVER
定义的服务grpc-server-svc.grpc-best.svc.cluster.local,当接收到内部请求时,可以均匀地路由到4个编程语言版本的服务端上。与此同时,通过配置Istio中的Ingress
Gateway,可以将外部请求按负载均衡策略路由到4个版本的gRPC服务端上。

步骤一:创建gRPC服务端的Service
本系列的示例只有一个命名为
grpc-server-svc的gRPC类型的Service。
说明 spec.ports.name
的值需要以grpc开头。
- 创建名为grpc-server-svc的YAML文件。
apiVersion: v1
kind: Service
metadata:
namespace: grpc-best
name: grpc-server-svc
labels:
app: grpc-server-svc
spec:
ports:
- port: 9996
name: grpc-port
selector:
app: grpc-server-deploy
- 执行以下命令,创建Service。
kubectl apply -f grpc-server-svc.yaml
步骤二:创建gRPC服务端的Deployment
完整的Deployment请参见
kube/deployment,以下以NodeJS语言的gRPC服务端的Deployment文件
grpc-server-node.yaml为例,创建gRPC服务端的Deployment。
说明 服务端的4个Deployment都需要定义app标签的值为grpc-server-deploy
,以匹配gRPC服务端Service的Selector。同时每种语言的version标签需要保证各不相同。
- 创建名为grpc-server-node的YAML文件。
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: grpc-best
name: grpc-server-node
labels:
app: grpc-server-deploy
version: v3
spec:
replicas: 1
selector:
matchLabels:
app: grpc-server-deploy
version: v3
template:
metadata:
labels:
app: grpc-server-deploy
version: v3
spec:
serviceAccountName: grpc-best-sa
containers:
- name: grpc-server-deploy
image: registry.cn-beijing.aliyuncs.com/asm_repo/grpc_server_node:1.0.0
imagePullPolicy: Always
ports:
- containerPort: 9996
name: grpc-port
- 执行以下命令,创建Depolyment。
kubectl apply -f grpc-server-node.yaml
步骤三:创建gRPC客户端的Deployment
客户端和服务端有以下两处不同。
- 服务端启动后会持续运行,而客户端完成请求后就会结束进程,因此,需要实现一种死循环的方式保持客户端容器不退出。
- 客户端需要定义变量GRPC_SERVER的值,在客户端容器启动时传递给gRPC客户端。
以下以Go语言的gRPC客户端的Deployment文件grpc-client-go.yaml为例,创建gRPC客户端的Deployment。
- 创建名grpc-client-go的YAML文件。
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: grpc-best
name: grpc-client-go
labels:
app: grpc-client-go
spec:
replicas: 1
selector:
matchLabels:
app: grpc-client-go
template:
metadata:
labels:
app: grpc-client-go
spec:
serviceAccountName: grpc-best-sa
containers:
- name: grpc-client-go
image: registry.cn-beijing.aliyuncs.com/asm_repo/grpc_client_go:1.0.0
command: ["/bin/sleep", "3650d"]
env:
- name: GRPC_SERVER
value: "grpc-server-svc.grpc-best.svc.cluster.local"
imagePullPolicy: Always
- 执行以下命令,创建Depolyment。
kubectl apply -f grpc-client-go.yaml
其中,command: ["/bin/sleep", "3650d"]
是定义Go语言的gRPC客户端启动后执行的命令,通过Sleep的方式保持客户端容器运行。env
中定义了GRPC_SERVER变量,其值为grpc-server-svc.grpc-best.svc.cluster.local
。
步骤四:部署服务和应用
- 在ACK实例中创建名为grpc-best的命名空间。
alias k="kubectl --kubeconfig $USER_CONFIG"
k create ns grpc-best
- 为命名空间启用自动注入Sidecar。
k label ns grpc-best istio-injection=enabled
- 部署ServiceAccount、Service,及8个Deployment。
k apply -f grpc-sa.yaml
k apply -f grpc-svc.yaml
k apply -f deployment/grpc-server-java.yaml
k apply -f deployment/grpc-server-python.yaml
k apply -f deployment/grpc-server-go.yaml
k apply -f deployment/grpc-server-node.yaml
k apply -f deployment/grpc-client-java.yaml
k apply -f deployment/grpc-client-python.yaml
k apply -f deployment/grpc-client-go.yaml
k apply -f deployment/grpc-client-node.yaml
结果验证
从Pod侧验证gRPC服务的负载均衡
从客户端容器请求gRPC服务端的Service,验证gRPC服务端Service的负载均衡。
- 获取4个客户端容器的名称。
client_java_pod=$(k get pod -l app=grpc-client-java -n grpc-best -o jsonpath={.items..metadata.name})
client_go_pod=$(k get pod -l app=grpc-client-go -n grpc-best -o jsonpath={.items..metadata.name})
client_node_pod=$(k get pod -l app=grpc-client-node -n grpc-best -o jsonpath={.items..metadata.name})
client_python_pod=$(k get pod -l app=grpc-client-python -n grpc-best -o jsonpath={.items..metadata.name})
- 在客户端容器中,对4个gRPC服务端的Service发起请求。
k exec "$client_java_pod" -c grpc-client-java -n grpc-best -- java -jar /grpc-client.jar
k exec "$client_go_pod" -c grpc-client-go -n grpc-best -- ./grpc-client
k exec "$client_node_pod" -c grpc-client-node -n grpc-best -- node proto_client.js
k exec "$client_python_pod" -c grpc-client-python -n grpc-best -- sh /grpc-client/start_client.sh
- 以NodeJS客户端为例,通过一个循环,验证gRPC服务端Service的负载均衡。
for ((i = 1; i <= 100; i++)); do
k exec "$client_node_pod" -c grpc-client-node -n grpc-best -- node kube_client.js > kube_result
done
sort kube_result | grep -v "^[[:space:]]*$" | uniq -c | sort -nrk1
预期输出:
26 Talk:PYTHON
25 Talk:NODEJS
25 Talk:GOLANG
24 Talk:JAVA
结果显示4个版本的gRPC服务端Service收到相近的请求数。说明ASM收到外部请求时,可以将外部请求按负载均衡策略路由到4个版本的gRPC服务端Service上。
从本地验证gRPC服务的负载均衡
从本地请求Istio中的Ingress Gateway,验证gRPC服务端Service的负载均衡。
- 登录ASM控制台。
- 在左侧导航栏,选择。
- 在网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理。
- 在数据平面区域单击入口网关服务。
- 在入口网关服务页签中单击部署自定义入口网关。
- 在部署入口网关对话框中选择命名空间,将以下内容拷贝到文本框中,然后单击确定。
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
namespace: grpc-best
name: grpc-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 9996
name: grpc
protocol: GRPC
hosts:
- "*"
- 获取Ingress Gateway的IP。
alias k="kubectl --kubeconfig $USER_CONFIG"
INGRESS_IP=$(k -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
- 验证gRPC服务端Service的负载均衡。
docker run -d --name grpc_client_node -e GRPC_SERVER="${INGRESS_IP}" registry.cn-beijing.aliyuncs.com/asm_repo/grpc_client_node:1.0.0 /bin/sleep 3650d
client_node_container=$(docker ps -q)
docker exec -e GRPC_SERVER="${INGRESS_IP}" -it "$client_node_container" node kube_client.js
for ((i = 1; i <= 100; i++)); do
docker exec -e GRPC_SERVER="${INGRESS_IP}" -it "$client_node_container" node kube_client.js >> kube_result
done
sort kube_result | grep -v "^[[:space:]]*$" | uniq -c | sort -nrk1
预期输出:
26 Talk:PYTHON
25 Talk:NODEJS
25 Talk:GOLANG
24 Talk:JAVA
结果显示4个版本的gRPC服务端Service收到相近的请求数。说明ASM收到外部请求时,可以将外部请求按负载均衡策略路由到4个版本的gRPC服务端Service上。
在文档使用中是否遇到以下问题
更多建议
匿名提交