Search code examples
load-balancingistio

How Istio DestinationRule related to Kubernetes Service?


I trying to understand how to work load balancing in Istio.

Istio DestinationRule define rules for traffic balancing between pods. K8s Service similar manages traffic load balancing between pods.

DestinationRule define host and k8s service define host.

But without k8s service, request failed with http code 503.

How k8s Service relates to DestinationRule?


Solution

  • Kubernetes service

    Kubernetes service type ClusterIP uses kube-proxy's iptables rules to distribute the requests.

    The documentation says:

    By default, kube-proxy in userspace mode chooses a backend via a round-robin algorithm.

    More about it here.

    Destination rule

    As mentioned here

    You can think of virtual services as how you route your traffic to a given destination, and then you use destination rules to configure what happens to traffic for that destination. Destination rules are applied after virtual service routing rules are evaluated, so they apply to the traffic’s “real” destination.

    Every HTTP route must have a target: a route, or a redirect. A route is a forwarding target, and it can point to one of several versions of a service described in DestinationRules. Weights associated with the service version determine the proportion of traffic it receives.

    DestinationRule defines policies that apply to traffic intended for a service after routing has occurred.

    And here

    While a virtual service matches on a rule and evaluates a destination to route the traffic to, destination rules define available subsets of the service to send the traffic.

    For example, if you have a service that has multiple versions running at a time, you can create destination rules to define routes to those versions. Then use virtual services to map to a specific subset defined by the destination rules or split a percentage of the traffic to particular versions.

    503 without kubernetes service

    But without k8s service, request failed with http code 503.

    It's failing because there is no host, which was specified in virtual service, and destination rule.

    For example, take a look at this virtual service and destination rule.

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: reviews-route
    spec:
      hosts:
      - reviews.prod.svc.cluster.local
      http:
      - name: "reviews-v2-routes"
        match:
        - uri:
            prefix: "/wpcatalog"
        route:
        - destination:
            host: reviews.prod.svc.cluster.local  <---
            subset: v2
      - name: "reviews-v1-route"
        route:
        - destination:
            host: reviews.prod.svc.cluster.local  <---
            subset: v1
    
    
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: reviews-destination
    spec:
      host: reviews.prod.svc.cluster.local  <---
      subsets:
      - name: v1
        labels:
          version: v1
      - name: v2
        labels:
          version: v2
    

    If you check the host then you see there is your kubernetes service specified, and it won't work without it.


    Additionaly when setting route rules to direct traffic to specific versions (subsets) of a service, care must be taken to ensure that the subsets are available before they are used in the routes. Otherwise, calls to the service may return 503 errors during a reconfiguration period.

    More about it here.

    DestinationRule define host and k8s service define host.

    Destination rule host is your kubernetes service. Kubernetes service hosts are your pods, you may be wondering, but why do I need a service?

    As mentioned here.

    A Kubernetes Service is an abstraction which defines a logical set of Pods running somewhere in your cluster, that all provide the same functionality. When created, each Service is assigned a unique IP address (also called clusterIP). This address is tied to the lifespan of the Service, and will not change while the Service is alive. Pods can be configured to talk to the Service, and know that communication to the Service will be automatically load-balanced out to some pod that is a member of the Service.

    Kubernetes Service relates to DestinationRule

    I couldn't find the exact information how it works, so I will explain how I understand it.

    You need kubernetes service so virtual service and destination rule could actually work.

    As kubernetes service uses kube-proxy's iptables rules to distribute the requests, I assume that istio destination rule can ovveride it with his own rules, and apply them through envoy sidecar, because all traffic that your mesh services send and receive (data plane traffic) is proxied through Envoy, making it easy to direct and control traffic around your mesh without making any changes to your services.

    More about it here.


    Additional resources:


    Let me know if you have any more questions.