Non-deterministic behaviour when two HTTP routes match the same rule in different namespaces

What should happen when two different IngressRoute in different namespaces match the same rule?

Say I install an application that responds with a picture of Stilton cheese when I visit http://stilton.cheese :

---
apiVersion: v1
kind: Service
metadata:
  name: cheese
  labels:
    app.kubernetes.io/name: cheese
spec:
  type: ClusterIP
  ports:
    - name: web
      port: 80
      targetPort: 80
      protocol: TCP
  selector:
    app.kubernetes.io/name: cheese
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cheese
  labels:
    app.kubernetes.io/name: cheese
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: cheese
  template:
    metadata:
      name: cheese
      labels:
        app.kubernetes.io/name: cheese
    spec:
      containers:
        - image: errm/cheese:stilton
          name: stilton
          ports:
            - name: web
              containerPort: 80
              protocol: TCP
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ingress
  labels:
    app.kubernetes.io/name: cheese
spec:
  entryPoints:
    - web
  routes:
    - kind: Rule
      match: Host(`stilton.cheese`)
      services:
        - name: cheese
          kind: Service
          port: 80
kubectl apply -f <file> -n stilton 

And as expected, curling for the stilton.cheese host gets me a page with stilton:

❯ kubectl run -it --rm --image=curlimages/curl curly -- sh
~ $ curl --header "Host: stilton.cheese" <ip of traefik service>
...
    <h1>Stilton</h1>
...

If I then I try to install an application that responds with a picture of cheddar cheese under http://cheddar.cheese, but by mistake I set the same match rule in the IngressRoute configuration:

---
apiVersion: v1
kind: Service
metadata:
  name: cheese
  labels:
    app.kubernetes.io/name: cheese
spec:
  type: ClusterIP
  ports:
    - name: web
      port: 80
      targetPort: 80
      protocol: TCP
  selector:
    app.kubernetes.io/name: cheese
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cheese
  labels:
    app.kubernetes.io/name: cheese
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: cheese
  template:
    metadata:
      name: cheese
      labels:
        app.kubernetes.io/name: cheese
    spec:
      containers:
        - image: errm/cheese:cheddar
          name: cheddar
          ports:
            - name: web
              containerPort: 80
              protocol: TCP
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: ingress
  labels:
    app.kubernetes.io/name: cheese
spec:
  entryPoints:
    - web
  routes:
    - kind: Rule
      match: Host(`stilton.cheese`)   # mistake! should be cheddar.cheese
      services:
        - name: cheese
          kind: Service
          port: 80
kubectl apply -f <file> -n cheddar 

Then it's not clear how Traefik determines which HTTP service to direct to. Should I get a picture of cheddar or stilton when I curl for http://stilton.cheese ?

In fact, if I remove and re-apply the previous configurations multiple times, each time I will be directed to a different service (apparently in random fashion). Is this a bug, or am I misunderstanding how this is supposed to work?

I would assume that k8s stores the config and provides it to Traefik. Then Traefik sorts by priority (which is explicitly set or derived from the length of the rule).

When two rules have no priority and the same length, then it probably depends on which is first in the list. But I am not sure in what order k8s provides the config to Traefik.

So if you want a fixed order, you could set priority by yourself

But that’s all guessing as a Traefik user.

Looks like that's it. I understood from the documentation that the priority setting was only applied to rules declared within the same IngressRoute, but it looks like it's actually used for all the rules defined in Traefik. If I add a priority: 999 to any of the rules above, then I no longer get a "random" cheese back, I instead consistently get the one with the highest priority. Thank you for the answer!

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.