Multiple DestinationRules for the same host

Hi,

i’m not sure what this is hinting at

A DestinationRule can also be fragmented with similar merge semantic and restrictions.

  1. There should only be one definition of any given subset across multiple destination rules for the same host. If there is more than one with the same name, the first definition is used and any following duplicates are discarded. No merging of subset content is supported.
    from:
    https://istio.io/docs/ops/best-practices/traffic-management/#multiple-virtual-services-and-destination-rules-for-the-same-host

What is meant by “one definition” and which “name” is this paragraph referring to ?

I have multiple deployments with version labels like

  • live
  • demo

I have a VirtualService / DestinationRule for each version, routing traffic depending on a prefix match

This seems to be a problem… but combining the configs (which i tried manually to get it to work) is a problem too, because deployment-wise those are two distinct deployments

I will post the yaml stuff later, after i did a clean deploy.

any help appreciated ! :slight_smile:

live-virtualservice
Note : ${K8SDOMAIN} is replaced via envsubst during deployment

---
# Source: gesellschafter-live/templates/virtualservice.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: gesellschafter-live
  namespace: neo
spec:
  hosts:
  - gesellschafter-neo.${K8SDOMAIN}
  - gesellschafter.neo.svc.cluster.local
  gateways:
  - neo-gateway
  - mesh
  http:
  - match:
    - uri:
        prefix: "/live/"
    - uri:
        prefix: "/live"
    rewrite:
      uri: "/"
    route:
    - destination:
        host: gesellschafter
        port:
          number: 8888
        subset: live

demo-virtualservice

---
# Source: gesellschafter-demo/templates/virtualservice.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: gesellschafter-demo
  namespace: neo
spec:
  hosts:
  - gesellschafter-neo.${K8SDOMAIN}
  - gesellschafter.neo.svc.cluster.local
  gateways:
  - neo-gateway
  - mesh
  http:
  - match:
    - uri:
        prefix: "/demo/"
    - uri:
        prefix: "/demo"
    rewrite:
      uri: "/"
    route:
    - destination:
        host: gesellschafter
        port:
          number: 8888
        subset: demo

live-destinationrule

---
# Source: gesellschafter-live/templates/destinationrule.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: gesellschafter-live-destinationrule
  namespace: neo
spec:
  host: gesellschafter.neo.svc.cluster.local
  subsets:
  - name: live
    labels:
      version: live

demo-destinationrule

---
# Source: gesellschafter-demo/templates/destinationrule.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: gesellschafter-demo-destinationrule
  namespace: neo
spec:
  host: gesellschafter.neo.svc.cluster.local
  subsets:
  - name: demo
    labels:
      version: demo

With this config i get this error in Kiali

image

And this with istioctl:

istioctl x describe pod gesellschafter-demo-5b858dd48d-7vpzs -n neo
Pod: gesellschafter-demo-5b858dd48d-7vpzs
   Pod Ports: 8888 (gesellschafter-demo), 15090 (istio-proxy)
--------------------
Service: gesellschafter
   Port: http 8888/HTTP targets pod port 8888
DestinationRule: gesellschafter-demo-destinationrule for "gesellschafter"
   Matching subsets: demo
   No Traffic Policy
Pod is PERMISSIVE, client protocol unspecified


Exposed on Ingress Gateway http://172.26.1.86
VirtualService: gesellschafter-live
   /demo/*, /demo*
   1 additional destination(s) that will not reach this pod
~ $ istioctl x describe pod gesellschafter-live-d9f5c4b5b-fzp5n -n neo
Pod: gesellschafter-live-d9f5c4b5b-fzp5n
   Pod Ports: 8888 (gesellschafter-live), 15090 (istio-proxy)
--------------------
Service: gesellschafter
   Port: http 8888/HTTP targets pod port 8888
DestinationRule: gesellschafter-demo-destinationrule for "gesellschafter"
  WARNING POD DOES NOT MATCH ANY SUBSETS.  (Non matching subsets demo)
   Matching subsets: 
      (Non-matching subsets demo)
   No Traffic Policy
Pod is PERMISSIVE, client protocol unspecified


Exposed on Ingress Gateway http://172.26.1.86
VirtualService: gesellschafter-live
   WARNING: No destinations match pod subsets (checked 2 HTTP routes)
      Warning: Route to UNKNOWN subset live; check DestinationRule gesellschafter-demo-destinationrule
      Route to non-matching subset demo for (/demo/*, /demo*)

As soon as i combine my DestinationRules it works… but that is not very deployment friendly…

I worked around there isses a little, but it still would be nice to have both DestinationRule and VirtualService merging in both Gateways and Sidecars
Related issue on GitHub

Any approaches you guys use to solve this are welcome !

Hey erSitzt,

Did you found any workaround for this issue? I’m stuck with the same issue. I´m getting the same error, the 2nd subset appears to be missing but for some reason is working but I´m not sure.

Thanks

My workaround is using the internal names of my services, which are all different rather than using the external names.

For example

The first one is used when the service is accessed from outside the cluster via the ingress gateway and different versions of the service are selected by the destinationrule using prefixes like /v1.0.0 or /live or /demo.
The second one contains the version in the name, so no host merging is necessary. But a drawback is the resulting url looks like this
http://gesellschafter-v1-0-0.neo.svc.expert-k8s.local/v1.0.0
which is a bit redundand, but works for now.

Support for host merging in sidecars when using the mesh-gateway would be way nicer though…

Hi erSizt,

Thanks for your reply. Unfortunately that approach will no work for our scenario. We have a multibranch staging environment and we want keep each service talking with the same branch name unaware of endpoint config for each version just using sourceLabel match.

Anyway, thanks again!