grpc中的dns负载均衡

栏目: 服务器 · 发布时间: 6年前

内容简介:grpc中的dns负载均衡(金庆的专栏 2018.8)grpc-go 中如下连接服务器,请求将在多个IP之间轮转。

grpc中的dns负载均衡

(金庆的专栏 2018.8)

grpc-go 中如下连接服务器,请求将在多个IP之间轮转。

conn, err := grpc.Dial(
        "dns:///rng-headless:8081",
        grpc.WithBalancerName(roundrobin.Name),
        grpc.WithInsecure())

标准的目标名应该是这样的: "dns://authority/endpoint_name" ,

此处 authority 为空,详见: https://github.com/grpc/grpc/blob/master/doc/naming.md

服务器开3个实例,所有请求在3个实例上轮转:

[jinqing@host-10-2-3-4 RoundRobin]$ kubectl run -it --rm jinqing-roundrobin --image=jinq0123/roundrobin:4
If you don't see a command prompt, try pressing enter.
2018/08/28 10:18:01 request 7754383576636566559
2018/08/28 10:18:02 request 2543876599219675746
2018/08/28 10:18:03 request 927204261937181213
2018/08/28 10:18:04 request 7754383576636566559
2018/08/28 10:18:05 request 2543876599219675746
2018/08/28 10:18:06 request 927204261937181213
...

服务器返回一个随机数,不同实例的随机数不同。代码是从

https://github.com/kcollasarundell/balancing-on-k8s 修改的。

...
const (
        port = ":8081"
)

type server struct{}

var r int64

func init(){
    rand.Seed(time.Now().UnixNano())
    r = rand.Int63()
}

func (s *server) Rng(context.Context, *rng.Source) (*rng.RN, error) {
        return &rng.RN{RN: r}, nil
}

func main() {
        lis, err := net.Listen("tcp", port)
        if err != nil {
                log.Fatalf("failed to listen: %v", err)
        }
        s := grpc.NewServer()
        rng.RegisterRngServer(s, &server{})
        // Register reflection service on gRPC server.
        reflection.Register(s)

        if err := s.Serve(lis); err != nil {
                log.Fatalf("failed to serve: %v", err)
        }
}

先编译,打包成镜像,然后用 balancing-on-k8s\backend\kube.yaml 运行:

kubectl apply -f kube.yaml

backend\kube.yaml 创建了一个 ClusterIP 服务和一个 Headless 服务,部署了 3 个服务器实例。

[jinqing@host-10-2-3-4 RoundRobin]$ kubectl get svc
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
kubernetes     ClusterIP   10.96.0.1       <none>        443/TCP             93d
rng-cluster    ClusterIP   10.111.30.205   <none>        8081/TCP            4h
rng-headless   ClusterIP   None            <none>        8081/TCP,8080/TCP   4h

客户端是一个简单的grpc, 定时发送请求,打印返回的随机数。

balancing-on-k8s\clientSideBalancer\RoundRobin\main.go 中的地址需要添加端口,

不然grpc会去连接 443 端口而失败。

扩容后,测到大概3分钟后才看到负载转移。缩容后会立即生效。

kubectl scale --replicas=5 deployment/rng

如果是 ClusterIP 服务, 则服务名对应一个ClusterIP;

如果是 Headless 服务,则服务名对应各个Pod的IP:

/ # nslookup rng-headless
Server:         10.96.0.10
Address:        10.96.0.10#53

Name:   rng-headless.default.svc.cluster.local
Address: 10.244.3.27
Name:   rng-headless.default.svc.cluster.local
Address: 10.244.0.108
Name:   rng-headless.default.svc.cluster.local
Address: 10.244.2.66

/ # nslookup rng-cluster
Server:         10.96.0.10
Address:        10.96.0.10#53

Name:   rng-cluster.default.svc.cluster.local
Address: 10.111.30.205

/ #

如果去除 “dns:///”, 仅仅是域名加端口:

conn, err := grpc.Dial(
        "rng-headless:8081",
        grpc.WithBalancerName(roundrobin.Name),
        ...

则只会请求同一个实例。只有当该实例pod被删除后才会切换到另一个实例。

使用缩容时发现会优先删除没有客户端连接的实例。

用2个客户端连接到不同服务器实例,然后缩容为1实例,就可以看到请求切换。

如果客户端和服务器数量很大,这个dns负载均衡就不合适了,因为客户端会连接每个服务器实例。

参考:

Exploring Kubernetes Service Discovery and loadbalancing ( https://kca.id.au/post/k8s_service/ )


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Kubernetes权威指南

Kubernetes权威指南

龚正、吴治辉、王伟、崔秀龙、闫健勇、崔晓宁、刘晓红 / 电子工业出版社 / 2016-10 / 99

Kubernetes是由谷歌开源的Docker容器集群管理系统,为容器化的应用提供了资源调度、部署运行、服务发现、扩容及缩容等一整套功能。《Kubernetes权威指南:从Docker到Kubernetes实践全接触(第2版)》从一个开发者的角度去理解、分析和解决问题,囊括了Kubernetes入门、核心原理、实践指南、开发指导、高级案例、运维指南及源码分析等方面的内容,图文并茂、内容丰富、由浅入......一起来看看 《Kubernetes权威指南》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换