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
The solution is to use a regular expression (regex) to match all paths except /someendpoint.
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 :
Refer to this ingress path matching for more information on path priority