项目作者: joa

项目描述 :
Just add water load balancer for gRPC
高级语言: Go
项目地址: git://github.com/joa/jawlb.git
创建时间: 2018-11-28T21:59:10Z
项目社区:https://github.com/joa/jawlb

开源协议:MIT License

下载


Jawlb

Jawlb (pronounced jolp) is an unsophisticated grpclb implementation for things running in Kubernetes talking to gRPC
services within that same Kubernetes cluster.

This load balancer performs service discovery via the Kubernetes API and announces any changes it sees
via the grpclb protocol to its clients.

Building

You’ll want to push the result of docker build -f Dockerfile . into your registry.

grpclb

The grpclb Go implementation (others maybe too) requires you to define a SRV record for the loadbalancer.
The easy solution is to define a Kubernetes service with a port named grpclb and you’re all set.

Example

The example shows a load balancer setup that’ll forward requests to myservice:grpc.
We assume that RBAC isn’t required.

Load Balancer Deployment

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: myservice-lb
  5. spec:
  6. selector:
  7. matchLabels:
  8. app: jawlb
  9. service: myservice
  10. replicas: 3
  11. template:
  12. metadata:
  13. labels:
  14. app: jawlb
  15. service: myservice
  16. spec:
  17. restartPolicy: Always
  18. containers:
  19. - image: "your.regist.ry/jawlb:yolo"
  20. name: jawlb
  21. ports:
  22. - containerPort: 8000
  23. name: grpclb
  24. readinessProbe:
  25. tcpSocket:
  26. port: grpclb
  27. initialDelaySeconds: 5
  28. periodSeconds: 10
  29. livenessProbe:
  30. tcpSocket:
  31. port: grpclb
  32. initialDelaySeconds: 15
  33. periodSeconds: 60
  34. env:
  35. # The name of the upstream service we want
  36. # to balance
  37. - name: JAWLB_SERVICE
  38. value: "myservice"
  39. # The name of the port exposed by this service
  40. # which we want to forward to
  41. - name: JAWLB_TARGETPORT
  42. value: "grpc"
  43. # The namespace in which jawlb performs the lookup
  44. # and we use the current one simply
  45. - name: JAWLB_NAMESPACE
  46. valueFrom:
  47. fieldRef:
  48. fieldPath: metadata.namespace

Load Balancer Service

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: myservice-lb
  5. labels:
  6. app: jawlb
  7. service: myservice
  8. spec:
  9. # Make this a headless service because we'll have to use
  10. # the dns:// resolver in the Go client
  11. clusterIP: None
  12. ports:
  13. # The port MUST be named grpclb in order to create
  14. # the proper DNS SRV entry
  15. - name: grpclb
  16. port: 8000
  17. targetPort: grpclb
  18. selector:
  19. app: jawlb
  20. service: myservice

gRPC Client

  1. import _ "google.golang.org/grpc/balancer/grpclb"
  2. // When dialing, gRPC's DNS resolver will issue a SRV lookup and
  3. // because we're so nice to provide the grpclb entry, everything
  4. // works as expected
  5. //
  6. // If no SRV record exists, gRPC will fall back to a vanilla connection
  7. // without the loadbalancer.
  8. conn, err := grpc.Dial(
  9. "dns:///myservice-lb", // must use the dns resolver
  10. grpc.WithInsecure())
  11. // ... magic 🧙‍♀️

Configuration

Everything is passed via environment variables.

  • JAWLB_NAMESPACE in which namespace service lookup is performed, default "default"
  • JAWLB_SERVICE the name of the Kubernetes service to balance, required
  • JAWLB_TARGETPORT the name(!) of the target port on that service, default "grpc"
  • JAWLB_LABELSELECTOR an additional label selector, default ""
  • JAWLB_HOST the hostname to listen on, default""
  • JAWLB_PORT port to listen on, default 8000
  • JAWLB_SHUTDOWNGRACEPERIOD Grace period for open connections during shutdown, default "25s"

What’s missing

  • Potentially some actual load balancing
  • Implementation of LoadReporter service
  • Readiness Probe
  • Health Check

Resources