skip to Main Content

In Kubernetes we need a new service to handle the root path, but but still a catch everything else on our current frontend.

Current frontend Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: current-frontend
  labels:
    app: current-frontend
    tier: frontend
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  tls:
    - hosts:
      - my.domain.com
      secretName: tls-secret
  rules:
    - host: my.domain.com
      http:
        paths:
          - backend:
              service:
                name: current-frontend
                port:
                  number: 80
            path: /
            pathType: Prefix

New service Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: new-service
  labels:
    app: new-service
    tier: frontend
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  tls:
  - hosts:
    - my.domain.com
    secretName: tls-secret
  rules:
  - host: my.domain.com
    http:
      paths:
      - backend:
          service:
            name: new-service
            port:
              number: 80
        path: /someendpoint
        pathType: ImplementationSpecific
      - backend:
          service:
            name: new-service
            port:
              number: 80
        path: /
        pathType: Exact

According to the documentation of Kuberntes Ingress, it should prioritize Exact over Prefix

If two paths are still equally matched, precedence will be given to paths with an exact path type over prefix path type.

https://kubernetes.io/docs/concepts/services-networking/ingress/#multiple-matches

The problem is that everything else then my.domain.com/someendpoint goes to the current-frontend, while the expected would be that my.domain.com/ would go to new-service.

How do I achieving this?


Solution

I got it working, even If it doesn’t seams to be the optimal solution (According to the Documentation)

I Followed Hemanth Kumar’s answer and changed the Current Frontend to use Regex, with (.+) instead of (.*) as I wanted at least one char after the slash for it to be hit.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: current-frontend
  labels:
    app: current-frontend
    tier: frontend
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
    kubernetes.io/ingress.class: nginx
spec:
  tls:
    - hosts:
      - my.domain.com
      secretName: tls-secret
  rules:
    - host: my.domain.com
      http:
        paths:
          - backend:
              service:
                name: current-frontend
                port:
                  number: 80
            path: /(.+)
            pathType: Prefix

At the same time I needed to change the New service to use Prefix instead of Exact as it does not work, event if there is no other services to hit.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: new-service
  labels:
    app: new-service
    tier: frontend
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  tls:
  - hosts:
    - my.domain.com
    secretName: tls-secret
  rules:
  - host: my.domain.com
    http:
      paths:
      - backend:
          service:
            name: new-service
            port:
              number: 80
        path: /someendpoint
        pathType: ImplementationSpecific
      - backend:
          service:
            name: new-service
            port:
              number: 80
        path: /
        pathType: Prefix

2

Answers


  1. The solution is to use a regular expression (regex) to match all paths except /someendpoint.

    Login or Signup to reply.
  2. Ingress path matching can be enabled by setting the

    nginx.ingress.kubernetes.io/use-regex annotation to true .

    See the description of the use-regex annotation :

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: test-ingress
      annotations:
        nginx.ingress.kubernetes.io/use-regex: "true"
    spec:
      ingressClassName: nginx
      rules:
      - host: test.com
        http:
          paths:
          - path: /foo/.*
            pathType: Prefix
            backend:
              service:
                name: test
                port:
                  number: 80
    

    Refer to this ingress path matching for more information on path priority

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search