Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: gRPC Load Balancing Design in Kubernetes Environment #2195

Open
2 tasks done
cubxxw opened this issue Apr 22, 2024 · 0 comments
Open
2 tasks done

Feature: gRPC Load Balancing Design in Kubernetes Environment #2195

cubxxw opened this issue Apr 22, 2024 · 0 comments
Labels
go Pull requests that update Go code kind/feature Categorizes issue or PR as related to a new feature.

Comments

@cubxxw
Copy link
Contributor

cubxxw commented Apr 22, 2024

Checklist

  • I've searched for similar issues and couldn't find anything matching
  • I've discussed this feature request in the OpenIMSDK Slack and got positive feedback

Is this feature request related to a problem?

✅ Yes

Problem Description

Abstract:
This document outlines a gRPC load balancing solution tailored for Kubernetes, addressing the limitations of traditional Kubernetes Service-based load balancing for long-lived HTTP/2 connections typical of gRPC traffic. The design includes both client-side and server-side strategies to ensure efficient and dynamic load distribution across gRPC services.

Solution Description

Introduction:
Kubernetes Services typically operate at the network's fourth layer, utilizing kube-proxy for basic load balancing. However, due to gRPC's reliance on long-lived HTTP/2 connections, such a method leads to uneven load distribution, where all traffic might end up at a single pod. This necessitates a shift from connection-level to request-level balancing.

Design Challenges and Solutions:

  1. Client-Side Load Balancing:

    • Approach: Utilize NameResolver, load balancing policies, and a Headless Service to distribute requests.
    • Implementation:
      • The gRPC client resolves service names into IP addresses through a resolver. For Kubernetes, this involves using a Headless Service that stores pod IPs as A records.
      • Built-in load balancing algorithms such as pick_first and round_robin are used. The round_robin policy distributes requests evenly across all available service IPs.
    • Code Example:
      svc := "mygrpc:50051"
      ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
      defer cancel()
      conn, err := grpc.DialContext(
        ctx,
        fmt.Sprintf("%s:///%s", "dns", svc),
        grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy":"round_robin"}`),
        grpc.WithInsecure(),
        grpc.WithBlock(),
      )
      if err != nil {
        log.Fatal(err)
      }
  2. Server-Side Load Balancing:

    • Introduce a middleware component (like Linkerd or a Service Mesh component such as Envoy in Istio) to perform layer 7 load balancing. This intermediary component handles incoming client requests and forwards them to backend pods.

Handling Kubernetes API with Kuberesolver:

  • Overview: To dynamically adapt to changes in service endpoints due to pod scaling, a custom resolver, kuberesolver, is used. This resolver directly interacts with Kubernetes API to monitor and update endpoint changes.
  • Configuration: Requires setting appropriate RBAC permissions for the client pod to access endpoint resources.
  • Code Snippet:
    import "github.com/sercand/kuberesolver/v3"
    kuberesolver.RegisterInCluster()
    cc, err := grpc.Dial("kubernetes:///service.namespace:portname", opts...)

Benefits

Conclusion:
This design offers a robust solution for gRPC load balancing within Kubernetes, enhancing the traditional service discovery and load distribution mechanisms to effectively manage the unique challenges posed by gRPC's long-lived connections and HTTP/2 protocol.

Further Reading:

  • Detailed exploration of gRPC load balancing in Kubernetes environments can be found here.

Appendix:

  • YAML configurations for Kubernetes RBAC permissions are included to ensure proper authorization for the client pods to access the Kubernetes API.

Potential Drawbacks

No response

Additional Information

No response

@cubxxw cubxxw added kind/feature Categorizes issue or PR as related to a new feature. go Pull requests that update Go code labels Apr 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
go Pull requests that update Go code kind/feature Categorizes issue or PR as related to a new feature.
Projects
None yet
Development

No branches or pull requests

1 participant