Default Load Balancing in Kubernetes

2/17/2019

I've recently started working with Kubernetes clusters. The flow of network calls for a given Kubernetes service in our cluster is something like the following:

External Non-K8S Load Balancer -> Ingress Controller -> Ingress Resource -> Service -> Pod

For a given service, there are two replicas. By looking at the logs of the containers in the replicas, I can see that calls are being routed to different pods. As far as I can see, we haven't explicitly set up any load-balancing policies anywhere for our services in Kubernetes.

I've got a few questions:

1) Is there a default load-balancing policy for K8S? I've read about kube-proxy and random routing. It definitely doesn't appear to be round-robin. 2) Is there an obvious way to specify load balancing rules in the Ingress resources themselves? On a per-service basis?

Looking at one of our Ingress resources, I can see that the 'loadBalancer' property is empty:

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
ingress.kubernetes.io/rewrite-target: /
kubectl.kubernetes.io/last-applied-configuration: |
  {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"ingress.kubernetes.io/rewrite-target":"/","nginx.ingress.kubernetes.io/rewrite-target":"/"},"name":"example-service-ingress","namespace":"member"},"spec":{"rules":[{"host":"example-service.x.x.x.example.com","http":{"paths":[{"backend":{"serviceName":"example-service-service","servicePort":8080},"path":""}]}}]}}
nginx.ingress.kubernetes.io/rewrite-target: /
  creationTimestamp: "2019-02-13T17:49:29Z"
  generation: 1
  name: example-service-ingress
  namespace: x
  resourceVersion: "59178"
  selfLink: /apis/extensions/v1beta1/namespaces/x/ingresses/example-service-ingress
  uid: b61decda-2fb7-11e9-935b-02e6ca1a54ae
spec:
  rules:
  - host: example-service.x.x.x.example.com
    http:
      paths:
      - backend:
          serviceName: example-service-service
          servicePort: 8080
status:
  loadBalancer:
    ingress:
    - {}

I should specify - we're using an on-prem Kubernetes cluster, rather than on the cloud.

Cheers!

-- Danny Noam 父
kubernetes

2 Answers

2/17/2019

The "internal load balancing" between Pods of a Service has already been covered in this question from a few days ago.

Ingress isn't really doing anything special (unless you've been hacking in the NGINX config it uses) - it will use the same Service rules as in the linked question.

If you want or need fine-grained control of how pods are routed to within a service, it is possible to extend Kubernetes' features - I recommend you look into the traffic management features of Istio, as one of its features is to be able to dynamically control how much traffic different pods in a service receive.

-- Paul Annetts
Source: StackOverflow

2/18/2019

I see two options that can be used with k8s:

  1. Use istio's traffic management and create a DestinationRule. It currently supports three load balancing modes:

    • Round robin
    • Random
    • Weighted least request

      apiVersion: networking.istio.io/v1alpha3
      kind: DestinationRule
      ...
      spec:
        ...
        subsets:
        - name: test
          ...
          trafficPolicy:
            loadBalancer:
              simple: ROUND_ROBIN
  2. Use lb_type in envoy proxy with ambassador on k8s. More info about ambassador is in https://www.getambassador.io.

-- Vikram Hosakote
Source: StackOverflow