1

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.

jns_ai_unr
  • 753
  • 1
  • 8
  • 19
  • Your second example looks good. In my opinion, a request to `https://base.url/service-a/subpath` should go to `service-a -> /subpath`. Do you have `/subpath` configured for `service-a` ? – matt_j Mar 29 '21 at 11:51
  • Obviously I do. When printing the logs via `kubectl logs ` nothing is logged so the request never reaches the service. When using `- path: /` (without the `/service-a` prefix) and removing the `nginx.ingress.kubernetes.io/rewrite-target: /$2` line the request succeeds and it is also visible in `kubectl logs `. Interestingly using `- path: /service-a` and `*/rewrite-target: /` results in a log with `/` in the logs for any request to `/service-a/*`. – jns_ai_unr Mar 29 '21 at 12:18
  • Are you using [kubernetes/ingress-nginx](https://github.com/kubernetes/ingress-nginx/) or [nginxinc/kubernetes-ingress](https://github.com/nginxinc/kubernetes-ingress) ? – matt_j Mar 29 '21 at 12:28
  • I am following this guide: https://cert-manager.io/docs/tutorials/acme/ingress/ so I guess `kubernetes/ingress-nginx`. – jns_ai_unr Mar 29 '21 at 12:40
  • Check the Ingress Controller logs, they should give you information on where the `https://base.url/service-a/subpath` request goes. – matt_j Mar 30 '21 at 08:45
  • The logs show two entries: `"GET /service-a/subpath HTTP/1.1" 301 45 "http://base.url/service-a/subpth" [...] [service-a-8080]`, `"GET /subpath HTTP/1.1" 404 146 "https://base.url/subpath" [...] [upstream-default-backend]`. And as I mentioned above the latter does not exist, thats why its handled by the default backend internally. – jns_ai_unr Mar 31 '21 at 07:37
  • Can you provide your `service-a` configuration ? Is it possible for you to query directly this Pod using `kubectl exec -it -n app-namespace -- curl localhost/subpath` or any similar command ? – matt_j Apr 07 '21 at 11:31

0 Answers0