非容器应用与K8s工作负载的服务网格化实践-4 基于ASM的POD和VM互访实践-GRPC协议篇

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 为了实现高可用,非容器应用通常有一套服务注册和发现的机制。相对而言,kubernetes容器服务为POD提供了统一的基于dns的注册和发现机制。对于http协议的非容器应用的迁移,因为都是基于dns机制,切换成本交底。而对于使用非http协议的非容器应用,服务注册和发现这个技术点为迁移带来了额外的困难。如何从非容器的注册和发现大脑最终迁移到kubernetes的注册和发现大脑,目前尚没有广泛认可的方案。目前常见的讨论是双脑方案,就是让非容器应用在启动时同时向两套大脑注册,并从两套中发现依赖服务,然后逐步实现向kubernetes大脑过度。这套方案的优点是可以通过随时摆动来保证可用性。

为了实现高可用,非容器应用通常有一套服务注册和发现的机制。相对而言,kubernetes容器服务为POD提供了统一的基于dns的注册和发现机制。对于http协议的非容器应用的迁移,因为都是基于dns机制,切换成本交底。而对于使用非http协议的非容器应用,服务注册和发现这个技术点为迁移带来了额外的困难。

如何从非容器的注册和发现大脑最终迁移到kubernetes的注册和发现大脑,目前尚没有广泛认可的方案。目前常见的讨论是双脑方案,就是让非容器应用在启动时同时向两套大脑注册,并从两套中发现依赖服务,然后逐步实现向kubernetes大脑过度。这套方案的优点是可以通过随时摆动来保证可用性。

我个人比较倾向于彻底的kubernetes一脑模式。相比多脑,一脑的复杂度会极大下降。遗留大脑集群保持现状,kubernetes大脑集群使用新的方案。这样可以将服务发现和网格化解耦为两个独立的问题。借助服务网格的蓝绿部署/流量转移,可以将验证完毕依赖关系的集群逐步放行并最终替换遗留大脑集群。这个方案最有挑战的地方是如何在不改变非容器应用代码的前提下,将其底层协议替换。如果可以替换为grpc,那么就可以按照本篇的实践实现网格化。目前这个想法还很不成熟,期待交流。

1 POD和VM互访

路由规则

服务网格的流量转移是一脑方案的核心。首先需要明确的是,网格化的服务链路都会经过sidecar,sidecar内部(envoy)实现了对grpc的负载均衡,grpc协议的上游服务通过长链接和下游服务各个节点保持连接,在不配置流量转移的情况下,上游请求会均匀地路由到下游各个节点。

与http协议通过path配置流量转移类似,grpc的配置是通过service/method或者service.method来定义匹配规则的。grpc的路由配置示意如下。

spec:
  hosts:
    - hello2-svc
  http:
    - name: grpc-hello-route
      match:
        - uri:
            prefix: /org.feuyeux.grpc.Greeter/SayHello
      route:
        - destination:
            host: hello2-svc
            subset: v1
          weight: 30
        - destination:
            host: hello2-svc
            subset: v2
          weight: 60
        - destination:
            host: hello2-svc
            subset: v3
          weight: 10
AI 代码解读

搭建实验环境

本篇示例实验与前一篇相仿,不再冗述重复部分。我们希望路由到hello2 en/fr/es的流量比例为:30%:60%:10%。

示例(grpc_reciprocal_demo)包含如下元素:

  • hello1 deployment(镜像grpc_springboot_v1)
  • hello3 deployment(镜像grpc_springboot_v1)
  • hello2 docker containers(镜像grpc_springboot_v1/grpc_springboot_v2/grpc_springboot_v3)
  • 入口网关:istio-ingressgateway
  • 入口流量配置:gateway/virtualservice
  • hello1流量配置:hello1 service
  • hello2流量配置:hello2 service/hello2 virtualservice/hello2 destinationrule
  • hello3流量配置:hello3 service
  • hello2 serviceentry/hello2 workloadentry

与前一篇http所用示例类似,grpc示例使用的镜像为grpc_springboot-{version},是一个基于springboot开发的grpc服务(源代码在这里)。每个实例可以通过环境变量GRPC_HELLO_BACKEND定义下游服务。

启动hello2应用

通过如下命令分别在3个ecs节点上启动hello2的 docker container

#ssh1.sh
docker run \
--rm \
--network host \
--name http_v1 \
-e GRPC_HELLO_BACKEND=hello3-svc.grpc-reciprocal-hello.svc.cluster.local \
registry.cn-beijing.aliyuncs.com/asm_repo/grpc_springboot_v1:1.0.0
#ssh2.sh
docker run \
--rm \
--network host \
--name http_v2 \
-e GRPC_HELLO_BACKEND=hello3-svc.grpc-reciprocal-hello.svc.cluster.local \
registry.cn-beijing.aliyuncs.com/asm_repo/grpc_springboot_v2:1.0.0
#ssh3.sh
docker run \
--rm \
--network host \
--name http_v3 \
-e GRPC_HELLO_BACKEND=hello3-svc.grpc-reciprocal-hello.svc.cluster.local \
registry.cn-beijing.aliyuncs.com/asm_repo/grpc_springboot_v3:1.0.0
AI 代码解读

其他部分的搭建与前篇类似,可以参考前篇和本篇示例脚本,余文不在冗述。

grpcurl

相对于http的验证工具curl,我们使用grpcurl对grpc服务进行验证。

当grpc服务提供反射protocolbuf能力时,可以使用如下命令进行请求验证:

k exec "$hello1_pod" -c hello-v1-deploy -n grpc-reciprocal-hello \
  -- grpcurl -plaintext -d '{"name":"eric"}' \
  hello3-svc.grpc-reciprocal-hello.svc.cluster.local:7001 org.feuyeux.grpc.Greeter/SayHello | jq -r '.reply'
  
Hello eric(172.18.1.10)
AI 代码解读

如果上述命令返回错误,说明grpc服务无法反射protocolbuf,需要在执行grpccurl时,通过-import-path-proto参数提供proto文件。示意如下。

k exec "$hello1_pod" -c hello-v1-deploy -n grpc-reciprocal-hello -- \
grpcurl -plaintext -d '{"name":"eric"}' \
-import-path /opt -proto hello.proto \
hello3-svc.grpc-reciprocal-hello.svc.cluster.local:7001 org.feuyeux.grpc.Greeter/SayHello | jq -r '.reply'

Hello eric(172.18.1.10)
AI 代码解读

KUBE验证-POD和VM互访

初步掌握grpccurl命令后,我们验证基于grpc协议的POD和VM互访。请求从hello1 POD发向hello2 service,然后路由到各VM中的hello2 app,再由hello2 app请求到hello3 POD。

for i in {1..6}; do
  k exec "$hello1_pod" -c hello-v1-deploy -n grpc-reciprocal-hello \
    -- grpcurl -plaintext -d '{"name":"eric"}' localhost:7001 org.feuyeux.grpc.Greeter/SayHello | jq -r '.reply'
done
AI 代码解读
Hello eric(172.18.1.11)<-Hola eric(192.168.0.172)<-Hello eric(172.18.1.10)
Hello eric(172.18.1.11)<-Bonjour eric(192.168.0.171)<-Hello eric(172.18.1.10)
Hello eric(172.18.1.11)<-Hello eric(192.168.0.170)<-Hello eric(172.18.1.10)
...
AI 代码解读

MESH验证-全链路流量转移

最后部署gateway/virtualservice/destinationrule进行端到端验证。

IP=$(k -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

for i in {1..100}; do
  resp=$(grpcurl -plaintext -d '{"name":"eric"}' "$IP":7004 org.feuyeux.grpc.Greeter/SayHello | jq -r '.reply')
  echo "$resp" >>test_traffic_shift_result
done

echo "expected 30%(Hello eric)-60%(Bonjour eric)-10%(Hola eric):"
sort test_traffic_shift_result | grep -v "^[[:space:]]*$"| uniq -c | sort -nrk1
AI 代码解读
  57 Hello eric(172.18.1.11)<-Bonjour eric(192.168.0.171)<-Hello eric(172.18.1.10)
  32 Hello eric(172.18.1.11)<-Hello eric(192.168.0.170)<-Hello eric(172.18.1.10)
  11 Hello eric(172.18.1.11)<-Hola eric(192.168.0.172)<-Hello eric(172.18.1.10)
AI 代码解读

2 grpc基准测试

ghz

ghz是grpc协议的基准测试工具,功能与http协议下的apache benchfortio类似。我们可以通过ghz对服务网格内的grpc服务进行测试和调参。ghz的基本用法示意如下。

hello1_pod=$(k get pod -l app=hello1-deploy -n grpc-reciprocal-hello -o jsonpath={.items..metadata.name})

k exec "$hello1_pod" -c hello-v1-deploy -n grpc-reciprocal-hello -- \
  ghz --insecure -d '{"name":"eric"}' \
  --proto /opt/hello.proto \
  --call org.feuyeux.grpc.Greeter/SayHello \
  -n 2000 \
  -c 20 \
  -q 500 \
  localhost:7001
AI 代码解读
  • -n参数用来指定请求数量
  • -c参数用来指定并发数量
  • -q参数用来指定QPS

测试结果示意如下。

Summary:
  Count:        2000
  Total:        5.60 s
  Slowest:      851.86 ms
  Fastest:      4.88 ms
  Average:      54.51 ms
  Requests/sec: 357.21

Response time histogram:
  4.883 [1]     |
  89.580 [1919] |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎
  174.278 [43]  |∎
  258.976 [3]   |
  343.673 [5]   |
  428.371 [2]   |
  513.068 [4]   |
  597.766 [3]   |
  682.464 [0]   |
  767.161 [7]   |
  851.859 [13]  |

Latency distribution:
  10 % in 24.37 ms 
  25 % in 31.71 ms 
  50 % in 41.98 ms 
  75 % in 53.87 ms 
  90 % in 70.67 ms 
  95 % in 83.83 ms 
  99 % in 683.16 ms 

Status code distribution:
  [OK]   2000 responses   
AI 代码解读

上述结果表示RT/latency基本(1919/2000)落在90ms以内,平均54.51 ms,95%的请求延迟在83.83 ms以内,99 %段的延迟在683.16 ms,存在长尾,需要进一步优化服务网格的配置以及服务源代码。

trafficPolicy

通过修改hello2的DestinationRule可以随时调整连接池配置。我们可以结合基准测试,不断调整配置找到最佳性能点。示意如下。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: hello2-dr
  namespace: grpc-reciprocal-hello
spec:
  host: hello2-svc
  subsets:
    - labels:
        version: v1
      name: v1
    - labels:
        version: v2
      name: v2
    - labels:
        version: v3
      name: v3
  trafficPolicy:
    connectionPool:
      http:
        http1MaxPendingRequests: 20
        http2MaxRequests: 100
        maxRequestsPerConnection: 10
        maxRetries: 1
      tcp:
        connectTimeout: 10s
        maxConnections: 10
AI 代码解读

到此,POD和VM互访的grpc协议流量管理讲述完毕。

本篇示例完整演示了非容器应用网格化过程中的一个比较经典的场景。覆盖到从istio-ingressgateway到deployment、workloadentry等各种CRD的配置,较完整地展示了POD和VM互访中遇到的各技术点的配置。

接下来,我们在此基础上,验证下POD和VM作为同一service的混合流量,如何实现流量转移。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
六翁
+关注
目录
打赏
0
0
0
0
78624
分享
相关文章
ACK Gateway with Inference Extension:优化多机分布式大模型推理服务实践
本文介绍了如何利用阿里云容器服务ACK推出的ACK Gateway with Inference Extension组件,在Kubernetes环境中为多机分布式部署的LLM推理服务提供智能路由和负载均衡能力。文章以部署和优化QwQ-32B模型为例,详细展示了从环境准备到性能测试的完整实践过程。
ACK Gateway with AI Extension:面向Kubernetes大模型推理的智能路由实践
本文介绍了如何利用阿里云容器服务ACK推出的ACK Gateway with AI Extension组件,在Kubernetes环境中为大语言模型(LLM)推理服务提供智能路由和负载均衡能力。文章以部署和优化QwQ-32B模型为例,详细展示了从环境准备到性能测试的完整实践过程。
ACK Gateway with AI Extension:大模型推理的模型灰度实践
本文介绍了如何使用 ACK Gateway with AI Extension 组件在云原生环境中实现大语言模型(LLM)推理服务的灰度发布和流量分发。该组件专为 LLM 推理场景设计,支持四层/七层流量路由,并提供基于模型服务器负载感知的智能负载均衡能力。通过自定义资源(CRD),如 InferencePool 和 InferenceModel,可以灵活配置推理服务的流量策略,包括模型灰度发布和流量镜像。
容器数据保护:基于容器服务 Kubernetes 版(ACK)备份中心实现K8s存储卷一键备份与恢复
阿里云ACK备份中心提供一站式容器化业务灾备及迁移方案,减少数据丢失风险,确保业务稳定运行。
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
基于阿里云容器服务(ACK)的微服务架构设计与实践
本文介绍如何利用阿里云容器服务Kubernetes版(ACK)构建高可用、可扩展的微服务架构。通过电商平台案例,展示基于Java(Spring Boot)、Docker、Nacos等技术的开发、容器化、部署流程,涵盖服务注册、API网关、监控日志及性能优化实践,帮助企业实现云原生转型。
从单集群到多集群的快速无损转型:ACK One 多集群应用分发
ACK One 的多集群应用分发,可以最小成本地结合您已有的单集群 CD 系统,无需对原先应用资源 YAML 进行修改,即可快速构建成多集群的 CD 系统,并同时获得强大的多集群资源调度和分发的能力。
96 9
从单集群到多集群的快速无损转型:ACK One 多集群应用分发
本文介绍如何利用阿里云的分布式云容器平台ACK One的多集群应用分发功能,结合云效CD能力,快速将单集群CD系统升级为多集群CD系统。通过增加分发策略(PropagationPolicy)和差异化策略(OverridePolicy),并修改单集群kubeconfig为舰队kubeconfig,可实现无损改造。该方案具备多地域多集群智能资源调度、重调度及故障迁移等能力,帮助用户提升业务效率与可靠性。
K8s集群实战:使用kubeadm和kuboard部署Kubernetes集群
总之,使用kubeadm和kuboard部署K8s集群就像回归童年一样,简单又有趣。不要忘记,技术是为人服务的,用K8s集群操控云端资源,我们不过是想在复杂的世界找寻简单。尽管部署过程可能遇到困难,但朝着简化复杂的目标,我们就能找到意义和乐趣。希望你也能利用这些工具,找到你的乐趣,满足你的需求。
384 33

相关产品

  • 容器服务Kubernetes版
  • 推荐镜像

    更多
    AI助理

    你好,我是AI助理

    可以解答问题、推荐解决方案等

    登录插画

    登录以查看您的控制台资源

    管理云资源
    状态一览
    快捷访问