I want to have one base url with different services deployed at different subpath in my Kubernetes cluster like this:
https://base.url/service-a # -> service-a
https://base.url/service-b # -> service-b
# ...
But I don't want the service to know about its prefix. I would like to avoid hardcoding the /serivce-*
prefix in each service.
So internally I need all /service-a/*
routes to map to /*
. While externally the url should stay the same. So I do not want to be redirected from https://base.url/service-a/subpath
to https://base.url/subpath
.
My first thought was, that this should work:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: main
namespace: app-namespace
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- base.url
secretName: some-secret
rules:
- host: base.url/service-a
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service-a
port:
number: 8080
# ... other services as different hosts
But it does not. It fails with Invalid value: "base.url/service-a": a DNS-1123 subdomain must consist of lower case alphanumeric characters, '-' or '.'
. Seems like the spec.rules[*].host
is not allowed to contain path elements.
I also tried using the nginx-ingress
controller with the nginx.ingress.kubernetes.io/rewrite-target
annotation as suggested in multiple questions like this one or this one:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: main
namespace: app-namespace
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/issuer: "letsencrypt-staging"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
tls:
- hosts:
- base.url
secretName: some-secret
rules:
- host: base.url
http:
paths:
- path: /service-a(/|$)(.*)
pathType: Prefix
backend:
service:
name: service-a
port:
number: 8080
# ... other services as different paths
If I use postman or the browser and make a request to https://base.url/service-a/subpath
I am redirected to https://base.url/subpath
which returns a 404
because this is not a valid endpoint on my cluster.
I simply want to remove the prefix /service-a
for internal routing.
NOTE: I also want to avoid hosting the services in subdomains like service-a.base.url
because this would make my setup more complicated in regards to CORS.