关于k8s:k8s-服务发现-以及-gRPC-长连接负载均衡

60次阅读

共计 1536 个字符,预计需要花费 4 分钟才能阅读完成。

家喻户晓 gRPC 是基于 HTTP/2,而 HTTP/2 是基于 TCP 长连贯的。

k8s 自带一套基于 DNS 的服务发现机制 —— Service。

但基于 Service 的服务发现对于 gRPC 来说并不是开箱即用的,这外面有很多坑。

谬误姿态 ClusterIP Service

gRPC client 间接应用 ClusterIP Service 会导致负载不平衡。因为 HTTP/2 多个申请能够复用一条连贯,并发达到最大值才会创立新的连贯。这个最大值由 MaxConcurrentStreams 管制,Golang client 默认是 100。

除非运气比拟好,例如并发数是 (200, 300],正好与三个不同 pod 建设了三条长连贯。所以应用 ClusterIP Service 不太靠谱。

为什么 HTTP/1.1 不受影响

HTTP/1.1 默认开启 Keepalive,也会放弃长连贯。然而 HTTP/1.1 多个申请不会共享一个连贯,如果连接池里没有闲暇连贯则会新建一个,通过 Service 的负载平衡,各个 pod 上的连贯是绝对平衡的。

正确姿态

长连贯负载平衡的原理是与后端每个 pod 都建设一个长连贯,LB 算法抉择一个写入申请。

gRPC client LB 配合 Headless Service

创立 Headless Service 后,k8s 会生成 DNS 记录,拜访 Service 会返回后端多个 pod IP 的 A 记录,这样利用就能够基于 DNS 自定义负载平衡。

在 grpc-client 指定 headless service 地址为 dns:/// 协定,DNS resolver 会通过 DNS 查问后端多个 pod IP,而后通过 client LB 算法来实现负载平衡。这些 grpc-go 这个库都帮你做了。

conn, err := grpc.DialContext(ctx, "dns:///"+headlessSvc,
    grpc.WithInsecure(),
    grpc.WithBalancerName(roundrobin.Name),
    grpc.WithBlock(),)

残缺代码参考:https://github.com/win5do/go-…

Proxy LB 或 ServiceMesh

如果不想在 client 代码中来做 LB,能够应用 Envoy 或 Nginx 反向代理。

Proxy Server 与后端多个 pod 放弃长连贯,需配置对应模块来辨认 HTTP/2 申请,依据 LB 算法抉择一个 pod 转发申请。

Istio 做长连贯 LB 不要求 Headless Service,因为网格控制器不会间接应用 Service,而是获取 Service 背地 Endpoint(IP)配置到 Envoy 中。

Proxy 如果本身有多个 replicas,则 proxy 与 client 之间也有长连贯的问题,这就套娃了。

但 Istio 等服务网格会为每个 pod 注入一个专用的 Envoy 代理作为 sidecar,所以问题不大。

gRPC 应用 Envoy proxy 可参考 Google Cloud 的教程:

https://github.com/GoogleClou…

比照

client 和 proxy 两种形式的比照其实就是 侵入式服务治理 vs 网格化服务治理

侵入式 网格化
长处 – 性能好,没有屡次转发
– 逻辑清晰,开发人员能很快定位问题
– 基础设施下沉,逻辑统一,不便跨语言异构
– 非侵入,利用无感知
– 服务治理生态凋敝
毛病 – 多种编程语言须要别离开发 client 库
– 对接监控告警、链路追踪等基础设施工作量大
– 链路长,有性能损耗
– 上层逻辑简单,不通明,出问题抓瞎
– 还不够成熟

Reference

https://kubernetes.io/blog/20…

https://zhuanlan.zhihu.com/p/…

https://zhuanlan.zhihu.com/p/…

正文完
 0