在 Kubernetes 环境中实现 gRPC 负载均衡( 二 )

同时将我们的 gRPC server 部署三个节点 , 再部署了一个客户端节点:
? k get podNAMEREADYSTATUSRESTARTSnative-tools-2-d6c454689-52wgd1/1Running0native-tools-2-d6c454689-67rx41/1Running0native-tools-2-d6c454689-zpwxt1/1Running0native-tools-65c5bd87fc-2fsmc2/2Running0我们进入客户端节点执行多次 grpc 请求:
k exec -it native-tools-65c5bd87fc-2fsmc bashGreeting: hostname:native-tools-2-d6c454689-zpwxt, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-d6c454689-zpwxt, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-d6c454689-zpwxt, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-d6c454689-zpwxt, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-d6c454689-zpwxt, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-d6c454689-zpwxt, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-d6c454689-zpwxt, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-d6c454689-zpwxt, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2会发现每次请求的都是同一个节点 native-tools-2-d6c454689-zpwxt , 这也就证明了在 kubernetes 中直接使用 gRPC 负载是不均衡的,一旦连接建立后就只能将请求发往那个节点 。
使用 IstioIstio 可以拿来解决这个问题,我们换到一个注入了 Istio 的 namespace 下还是同样的 代码,同样的 service 资源进行测试 。
关于开启 namespace 的 Istio 注入会在后续更新,现在感兴趣的可以查看下官方文档:https://istio.io/latest/docs/setup/additional-setup/sidecar-injection/
Greeting: hostname:native-tools-2-5fbf46cf54-5m7dl, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-xprjz, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-5m7dl, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-5m7dl, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-xprjz, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-xprjz, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-5m7dl, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-5m7dl, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-nz8h5, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2Greeting: hostname:native-tools-2-5fbf46cf54-nz8h5, in:worldistio-proxy@n:/$ curl http://127.0.0.1:8081/grpc_client?name=native-tools-2可以发现同样的请求已经被负载到了多个 server 后端 , 这样我们就可以不再单独维护一个客户端 SDK 的情况下实现了负载均衡 。
原理其实本质上 Istio 也是客户端负载均衡的一种实现 。

在 Kubernetes 环境中实现 gRPC 负载均衡

文章插图
图片
以 Istio 的架构图为例:
  • 每一个 Pod 下会新增一个 Proxy 的 container,所有的流量入口和出口都会经过它 。
  • 它会从控制平面 Istiod 中拿到服务的注册信息,也就是 kubernetes 中的 service 。
  • 发生请求时由 proxy 容器中的 Envoy 进行最终的负载请求 。
【在 Kubernetes 环境中实现 gRPC 负载均衡】可以在使用了 Istio 的 Pod 中查看到具体的容器:
? k get pod native-tools-2-5fbf46cf54-5m7dl -n istio-test-2 -o json | jq '.spec.containers[].name'"istio-proxy""native-tools-2"可以发现这里存在一个 istio-proxy 的容器,也就是我们常说的 sidecar , 这样我们就可以把原本的 SDK 里的功能全部交给 Istio 去处理 。
总结当然 Istio 的功能远不止于此,比如: