服务网格GRPC协议多种编程语言实践.3.GRPC协议示例的容器实践

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 本篇使用上一篇分发的镜像,在阿里云容器服务(ACK)上部署。4个版本的client通过调用变量`GRPC_SERVER`定义的服务`grpc-server-svc.grpc-best.svc.cluster.local`,均匀地路由到4个版本的server上。与此同时,我们通过配置`istio-ingressgateway`的`Gateway`可以将外部请求按负载均衡策略路由到4个版本的grpc server上。

1 容器资源

本篇使用上一篇分发的镜像,在阿里云容器服务(ACK)上部署。

4个版本的client通过调用变量GRPC_SERVER定义的服务grpc-server-svc.grpc-best.svc.cluster.local,均匀地路由到4个版本的server上。与此同时,我们通过配置istio-ingressgatewayGateway可以将外部请求按负载均衡策略路由到4个版本的grpc server上。

示例完整的拓扑如下图所示。
grpc_kube.png

grpc-server-svc

本系列的示例只有一个命名为grpc-server-svc的grpc类型的Service。grpc类型的服务,spec.ports.name的值需要以grpc开头。

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

server deployment

完整的deployment详见kube/deployment目录,这里以node server的deployment文件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

服务端的4个deployment都需要定义app标签的值为grpc-server-deploy,以匹配grpc-server-svcselector。每种语言的version标签要各部相同。

client deployment

客户端和服务端有两处不同。

  • 服务端启动后会持续运行,而客户端完成请求后就会结束进程,因此,需要实现一种死循环的方式保持客户端容器不自己退出。
  • 需要定义变量GRPC_SERVER的值,在客户端容器启动时传递给grpc client。

这里以go client的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

其中,command: ["/bin/sleep", "3650d"]是定义grpc_client_go启动后执行的命令,通过长久地sleep的方式保持客户端容器运行。env中定义了GRPC_SERVER变量,值为grpc-server-svc.grpc-best.svc.cluster.local

2 部署

首先在ACK实例中创建名称为grpc-best的命名空间,然后为该命名空间启用自动注入sidecar。

alias k="kubectl --kubeconfig $USER_CONFIG"
k create ns grpc-best
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

3 从POD侧验证

kube验证包括两侧,一侧是从client容器请求grpc server service,另一侧是从本地请求ingressgateway。这里演示从client容器请求4个server容器的过程。

首先通过如下命令,获取4个client容器的名称。

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})

然后通过如下命令,在client容器中执行对grpc server 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

最后我们以node client为例,通过一个循环,验证grpc server 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

输出如下,均匀路由4个版本的服务,符合预期。

  26 Talk:PYTHON
  25 Talk:NODEJS
  25 Talk:GOLANG
  24 Talk:JAVA

4 从本地验证

接下来,我们再来验证从本地请求istio-ingressgateway。进入服务网格(ASM)实例,定义GRPC服务的Gateway,将如下内容复制到页面。

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:
        - "*"

使用如下命令获取istio-ingressgateway的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 server 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
目录
相关文章
|
13天前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker和Kubernetes入门
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性和效率的关键。本篇文章将引导读者了解如何利用Docker进行容器化打包及部署,以及Kubernetes集群管理的基础操作,帮助初学者快速入门云原生的世界。通过实际案例分析,我们将深入探讨这些技术在现代IT架构中的应用与影响。
55 2
|
14天前
|
Kubernetes Cloud Native Docker
云原生技术探索:容器化与微服务的实践之道
【10月更文挑战第36天】在云计算的浪潮中,云原生技术以其高效、灵活和可靠的特性成为企业数字化转型的重要推手。本文将深入探讨云原生的两大核心概念——容器化与微服务架构,并通过实际代码示例,揭示如何通过Docker和Kubernetes实现服务的快速部署和管理。我们将从基础概念入手,逐步引导读者理解并实践云原生技术,最终掌握如何构建和维护一个高效、可扩展的云原生应用。
|
15天前
|
Cloud Native 持续交付 Docker
Docker容器化技术:从入门到实践
Docker容器化技术:从入门到实践
|
16天前
|
存储 Kubernetes 调度
基于容器化技术的性能优化实践
基于容器化技术的性能优化实践
25 3
|
23天前
|
Kubernetes 负载均衡 Cloud Native
云原生应用:Kubernetes在容器编排中的实践与挑战
【10月更文挑战第27天】Kubernetes(简称K8s)是云原生应用的核心容器编排平台,提供自动化、扩展和管理容器化应用的能力。本文介绍Kubernetes的基本概念、安装配置、核心组件(如Pod和Deployment)、服务发现与负载均衡、网络配置及安全性挑战,帮助读者理解和实践Kubernetes在容器编排中的应用。
68 4
|
24天前
|
Kubernetes 监控 Cloud Native
云原生应用:Kubernetes在容器编排中的实践与挑战
【10月更文挑战第26天】随着云计算技术的发展,容器化成为现代应用部署的核心趋势。Kubernetes(K8s)作为容器编排领域的佼佼者,以其强大的可扩展性和自动化能力,为开发者提供了高效管理和部署容器化应用的平台。本文将详细介绍Kubernetes的基本概念、核心组件、实践过程及面临的挑战,帮助读者更好地理解和应用这一技术。
58 3
|
1月前
|
Kubernetes 监控 开发者
专家级实践:利用Cloud Toolkit进行微服务治理与容器化部署
【10月更文挑战第19天】在当今的软件开发领域,微服务架构因其高可伸缩性、易于维护和快速迭代的特点而备受青睐。然而,随着微服务数量的增加,管理和服务治理变得越来越复杂。作为阿里巴巴云推出的一款免费且开源的开发者工具,Cloud Toolkit 提供了一系列实用的功能,帮助开发者在微服务治理和容器化部署方面更加高效。本文将从个人的角度出发,探讨如何利用 Cloud Toolkit 来应对这些挑战。
35 2
|
1月前
|
存储 运维 云计算
探索Docker容器化:从入门到实践
在这个快速发展的云计算时代,Docker容器化技术正在改变应用的开发、部署和管理方式。本文旨在为初学者提供一个关于Docker的全面入门指南,并通过实践案例展示Docker在实际开发中的应用。我们将一起了解Docker的核心概念、基本操作、网络和存储,以及如何构建和部署一个简单的Web应用。无论你是开发者还是运维人员,本文都会帮助你快速掌握Docker的核心技能。
|
15天前
|
数据中心 开发者 Docker
理解并实践Docker容器化技术
理解并实践Docker容器化技术
|
2月前
|
运维 Kubernetes 调度
阿里云容器服务 ACK One 分布式云容器企业落地实践
3年前的云栖大会,我们发布分布式云容器平台ACK One,随着3年的发展,很高兴看到ACK One在混合云,分布式云领域帮助到越来越多的客户,今天给大家汇报下ACK One 3年来的发展演进,以及如何帮助客户解决分布式领域多云多集群管理的挑战。
阿里云容器服务 ACK One 分布式云容器企业落地实践
下一篇
无影云桌面