Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Motivation: It is tricky to send requests to a Kubernetes cluster from outside servers without ingress. There is no way to send traffic directly to the pod, but we can send traffic to the port of nodes (NodePort) where the pods are located. This PR proposes a new EndpointGroup that can send requests with CSLB using NodeIP and NodePort to pods in Kubernetes. This way is not an ideal CSLB where servers and clients communicate directly, but it will be a safer way to send traffic without going through ingress which can be SPOF. Modifications: - Add `KubernetesEndpointGroup` on top of `KubernetesClient` to dynamically obtain Kubernetes resources. - [Permission](https://kubernetes.io/docs/reference/access-authn-authz/rbac) to watch `services`, `nodes`, `pods` is required to fetch endpoints. - `service.ports[*].nodePort` is used to create the port of `Endpoint`. - [Watch API](https://kubernetes.io/docs/reference/using-api/api-concepts/#efficient-detection-of-changes) is used to track changes in Kubernetes with a minimal delay. - `ADDED` and `MODIFIED` events are used to update resouces. - `DELETED` is used to remove the resouce. - `BOOKMARK` event is not used and `ERROR` may be ignorable. - Test `KubernetesEndpointGroup` with both a real Kubernetes cluster and a mock Kubernetes server. Result: - You can use `KubernetesEndpointGroup` to perform client-side load-balancing when sending requests. - Fixes #4497 ```java // Create a KubernetesEndpointGroup that fetches the endpoints of the 'my-service' service in the 'default' // namespace. The Kubernetes client will be created with the default configuration in the $HOME/.kube/config. KubernetesClient kubernetesClient = new KubernetesClientBuilder().build(); KubernetesEndpointGroup .builder(kubernetesClient) .namespace("default") .serviceName("my-service") .build(); // If you want to use a custom configuration, you can create a KubernetesEndpointGroup as follows: // The custom configuration would be useful when you want to access Kubernetes from outside the cluster. Config config = new ConfigBuilder() .withMasterUrl("https://my-k8s-master") .withOauthToken("my-token") .build(); KubernetesEndpointGroup .builder(config) .namespace("my-namespace") .serviceName("my-service") .build(); ```
- Loading branch information