安装环境依赖

  • docker-desktop >= 4.1.1
  • kubernetes >= 1.21.5
  • go >= 1.17
  • protobuf >= 3.17.3
  • istioctl >= 1.11.4

下载安装 Docker Desktop ,并启动内置的 Kubernetes 集群。

# 安装 Go
brew install go
# 安装 Protobuf
brew install protobuf
# 安装 Istio
brew install istioctl
kubectl config use-context docker-desktop
istioctl install -y

项目地址

https://github.com/jxlwqq/grpc-lb

Makefile 介绍

命令 说明
make init 安装 protoc-gen-go 和 protoc-gen-grpc
make protoc 基于 proto 文件,生成 *_pb.go 和 *_grpc.pb.go
make docker-build 构建 docker 镜像
make kube-deploy 在集群中部署服务
make kube-delete 删除服务
make istio-inject 注入 Istio 边车

具体逻辑,请查看 Makefile 文件。

L4 vs L7 负载均衡

所谓的四层就是基于 IP + 端口的负载均衡,而七层就是基于 URL 等应用层信息的负载均衡; Kubernetes 内置的 Service 负载均衡基于 iptables/ipvs 实现,仅支持 L4。换句话说, Service 支持 HTTP/1.1 协议,不支持 HTTP/2 协议。

而 Envoy(Istio) 则更为全能,支持被 gRPC 请求和响应的作为路由和负载均衡底层的所有 HTTP/2 功能。

项目架构

本项目分别测试 Service 和 Envoy(Istio) 对 HTTP/RPC 负载均衡的支持情况。

  • cmd/server/main.go: 服务端,同时提供 HTTP 和 RPC 服务。响应的数据为服务端容器所在的 Pod 名称,(基于 Downward API)。
  • cmd/client-http/main.go: HTTP 客户端,通过 HTTP 方式,循环调用服务端接口,并打印返回值。
  • cmd/client-grpc/main.go: gRPC 客户端,通过 RPC 方式,循环远程调用服务端方法,并打印返回值。

测试原理

服务端 server 在 Kubernetes 集群中以 Deployment 的方式部署 3 个副本,3 个副本的 Pod 名称各不相同,而 client-http 和 client-grpc 则会每秒调用一次服务端,并打印返回值。如果返回值中,三个 Pod 的名称都存在,则表明正在进行有效的负载均衡,否则,则表明未进行有效的负载均衡。

测试 Service

构建镜像:

make docker-build # 构建镜像(构建好的镜像,不 push 到远程仓库中)

查看镜像:

docker images ls

返回:

REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
grpc-lb/client-grpc latest 95d32ead8d9b 12 seconds ago 16.6MB
grpc-lb/client-http latest dbf0341206f6 22 seconds ago 11.5MB
grpc-lb/server latest 1ef346785b2a 29 seconds ago 18.2MB

部署到集群中:

make kube-deploy  # 在集群中部署服务

查看 Pod:

kubectl get pods

返回:

NAME                           READY   STATUS    RESTARTS   AGE
client-grpc-6c565594f4-tdf75 1/1 Running 0 2m48s
client-http-55d95c744d-f7nx4 1/1 Running 0 2m49s
server-7c4bfd74d-29c69 1/1 Running 0 2m51s
server-7c4bfd74d-4btvw 1/1 Running 0 2m51s
server-7c4bfd74d-fk8zf 1/1 Running 0 2m51s

查看 client-http Pod 的日志:

export CLIENT_HTTP_POD=$(kubectl get pod -l app=client-http -o jsonpath={.items..metadata.name})
kubectl logs "${CLIENT_HTTP_POD}"

返回:

#1: server-7c4bfd74d-4btvw
#2: server-7c4bfd74d-4btvw
#3: server-7c4bfd74d-29c69
#4: server-7c4bfd74d-fk8zf
#5: server-7c4bfd74d-fk8zf
#6: server-7c4bfd74d-29c69
#7: server-7c4bfd74d-fk8zf
#8: server-7c4bfd74d-4btvw
#9: server-7c4bfd74d-fk8zf

查看 client-grpc Pod 的日志:

export CLIENT_GRPC_POD=$(kubectl get pod -l app=client-grpc -o jsonpath={.items..metadata.name})
kubectl logs "${CLIENT_GRPC_POD}"

返回:

#1: server-7c4bfd74d-fk8zf
#2: server-7c4bfd74d-fk8zf
#3: server-7c4bfd74d-fk8zf
#4: server-7c4bfd74d-fk8zf
#5: server-7c4bfd74d-fk8zf
#6: server-7c4bfd74d-fk8zf
#7: server-7c4bfd74d-fk8zf
#8: server-7c4bfd74d-fk8zf
#9: server-7c4bfd74d-fk8zf

可以看出,HTTP 请求在进行有效负载,而 RPC 请求在进行无效负载。

测试 Envoy(Istio)

我们在集群中已经部署了一个 Istio,但是没有设置自动注入的命令空间,所以我们在这里进行手动注入。

手动注入:

make istio-inject # 注入 Istio 边车

查看 Pod:

kubectl get pods

返回:

NAME                           READY   STATUS    RESTARTS   AGE
client-grpc-7864f57779-f6blx 2/2 Running 0 17s
client-http-f8964854c-jclkd 2/2 Running 0 21s
server-7846bd6bb4-bcfws 2/2 Running 0 27s
server-7846bd6bb4-fv29s 2/2 Running 0 40s
server-7846bd6bb4-hzqj6 2/2 Running 0 34s

查看 client-http Pod 的日志:

export CLIENT_HTTP_POD=$(kubectl get pod -l app=client-http -o jsonpath={.items..metadata.name})
kubectl logs "${CLIENT_HTTP_POD}"

返回:

#1: server-7846bd6bb4-hzqj6
#2: server-7846bd6bb4-fv29s
#3: server-7846bd6bb4-hzqj6
#4: server-7846bd6bb4-hzqj6
#5: server-7846bd6bb4-hzqj6
#6: server-7846bd6bb4-hzqj6
#7: server-7846bd6bb4-hzqj6
#8: server-7846bd6bb4-bcfws
#9: server-7846bd6bb4-fv29s

查看 client-grpc Pod 的日志:

export CLIENT_GRPC_POD=$(kubectl get pod -l app=client-grpc -o jsonpath={.items..metadata.name})
kubectl logs "${CLIENT_GRPC_POD}"

返回:

#1: server-7846bd6bb4-fv29s
#2: server-7846bd6bb4-hzqj6
#3: server-7846bd6bb4-fv29s
#4: server-7846bd6bb4-bcfws
#5: server-7846bd6bb4-fv29s
#6: server-7846bd6bb4-hzqj6
#7: server-7846bd6bb4-fv29s
#8: server-7846bd6bb4-bcfws
#9: server-7846bd6bb4-fv29s

可以看出,HTTP 请求 和 RPC 请求均在进行有效负载。

清理

make kube-delete
istioctl experimental uninstall --purge

Kubernetes 中的 gRPC 负载均衡的更多相关文章

  1. 【译】gRPC负载均衡

    原文地址:https://github.com/grpc/grpc/blob/master/doc/load-balancing.md gRPC负载均衡 范围 本文档解释了gPRC的负载均衡的设计. ...

  2. gRPC负载均衡(客户端负载均衡)

    前言 上篇介绍了如何使用etcd实现服务发现,本篇将基于etcd的服务发现前提下,介绍如何实现gRPC客户端负载均衡. gRPC负载均衡 gRPC官方文档提供了关于gRPC负载均衡方案Load Bal ...

  3. gRPC负载均衡(自定义负载均衡策略)

    前言 上篇文章介绍了如何实现gRPC负载均衡,但目前官方只提供了pick_first和round_robin两种负载均衡策略,轮询法round_robin不能满足因服务器配置不同而承担不同负载量,这篇 ...

  4. 一步一步在Windows中使用MyCat负载均衡 下篇

    之前在 一步一步在Windows中使用MyCat负载均衡 上篇 中已经讲了如何配置出MyCat.下面讲其相关的使用. 五.配置MyCat-eye 对于MyCat监控官网还提供一个MyCat-eye w ...

  5. Linux中keepalived+LVS负载均衡的搭建测试

    1.1 LVS简介       LVS(Linux Virtual Server),也就是Linux虚拟服务器, 是一个自由软件项目.使用LVS技术要达到的目标是:通过LVS提供的负载均衡技术和Lin ...

  6. 一步一步在Windows中使用MyCat负载均衡

    一步一步在Windows中使用MyCat负载均衡 http://www.cnblogs.com/zhangs1986/p/6408981.html   mycat+sqlServer简单demo配置 ...

  7. LVS集群中的IP负载均衡技术

    LVS集群中的IP负载均衡技术 章文嵩 (wensong@linux-vs.org) 转自LVS官方参考资料 2002 年 4 月 本文在分析服务器集群实现虚拟网络服务的相关技术上,详细描述了LVS集 ...

  8. Kubernetes:服务与负载均衡

    Blog:博客园 个人 参考:Service | Kubernetes.<Kubernetes进阶实战> 有了 Workload,我们可以方便地管理多实例的应用,但是要想能够方便地访问应用 ...

  9. ASP.NET中如何实现负载均衡

    ASP.NET站点中做负载均衡: 基于HTTP协议我们可能发现我们要解决两点问题: 第一,做到负载均衡,我们需要一个负载均衡器. 可以通过DNS轮询来做,在DNS服务器上配置为每次对我们做负载均衡的同 ...

随机推荐

  1. WPF进阶技巧和实战03-控件(5-列表、树、网格01)

    列表控件 ItemsControl为列表项控件定义了基本功能,下图是ItemsControl的继承关系: 在继承自ItemsControl类的层次结构中,还显示了项封装器(MenuItem.TreeV ...

  2. Linux命令行:free

                  total        used        free      shared  buff/cache   availableMem:           251G   ...

  3. MYSQL小版本升级(5.7.21至5.7.25)

    1.环境确认 [root@mysql ~]# ps -ef |grep -i mysql root 9173 1 0 2020 ? 00:00:00 /bin/sh /mysql/data/mysql ...

  4. 寻找写代码感觉(五)之Mybatis官方代码生成器的使用

    一.Mybatis Generator生成器 见名知意,官方给出的代码生成器.好处就是不用自己写实体类.接口.xml文件了,应对简单增删改查是可以的.复杂的还是需要自己手写sql的. 二.Mybati ...

  5. OGG-如何只同步最近某个时间范围的数据

    一.需求,某客户希望使用OGG只同步时间大于2021-02-01日期之后的数据变换 需求如标题所示,如何使用OGG进行配置? 客户环境需要同步的表有几百G,表数据太大了;如果同步所有数据,目标库空间存 ...

  6. Java生成6位数验证码

    public static String getCode() { return String.valueOf((int) ((Math.random() * 9 + 1) * 100000));} 生 ...

  7. Java字符串分割函数split源码分析

    spilt方法作用 以所有匹配regex的子串为分隔符,将input划分为多个子串. 例如: The input "boo:and:foo", for example, yield ...

  8. Ubuntu 用户管理/权限管理

    Ubuntu 用户管理/权限管理 小小记录一下 Ubuntu 下用户/权限管理常用的一些命令 用户管理 组管理 文件权限 给用户添加 sudo 权限 给用户添加 sudo 权限 首先先给出几个文件 / ...

  9. [技术博客] 软工-Ruby on Rails前端工具链的配置以及对Web应用结构设计的一点思考

    一.相关工具链简介 HAML HAML是专门面向Ruby on Rails模版语法设计的一门标记语言,其结合RoR的views部分模版语法的特点,对原来的*.html.erb(嵌入Ruby代码的HTM ...

  10. logstash收集的日志输出到elasticsearch中

    logstash收集的日志输出到elasticsearch中 一.需求 二.实现步骤 1.编写pipeline文件 1.`elasticsearch`配置参数解析: 2.可能会报的一个异常 2.准备测 ...