How do I host multiple services using subdirectories with nginx-ingress?

11/21/2019

Problem

I would like to host multiple services on a single domain name under different paths. The problem is that I'm unable to get request path rewriting working using nginx-ingress.

What I've tried

I've installed nginx-ingress using these instructions:

helm install stable/nginx-ingress --name nginx-ingress --set controller.publishService.enabled=true
CHART                   APP VERSION
nginx-ingress-0.3.7     1.5.7

The example works great with hostname based backends:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-kubernetes-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: first.testdomain.com
    http:
      paths:
      - backend:
          serviceName: hello-kubernetes-first
          servicePort: 80

However, I can't get path rewriting to work. This version redirects requests to the hello-kubernetes-first service, but doesn't do the path rewrite so I get a 404 error from that service because it's looking for the /foo directory within that service (which doesn't exist).

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-kubernetes-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: first.testdomain.com
    http:
      paths:
      - backend:
          serviceName: hello-kubernetes-first
          servicePort: 80
        path: /foo

I've also tried this example for paths / rewriting:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-kubernetes-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - host: first.testdomain.com
    http:
      paths:
      - backend:
          serviceName: hello-kubernetes-first
          servicePort: 80
        path: /foo(/|$)(.*)

But the requests aren't even directed to the hello-kubernetes-first service.

It appears that my rewrite configuration isn't making it to the /etc/nginx/nginx.conf file. When I run the following, I get no results:

kubectl exec nginx-ingress-nginx-ingress-XXXXXXXXX-XXXXX  cat /etc/nginx/nginx.conf | grep rewrite

How do I get the path rewriting to work?

Additional information:

  • kubectl / kubernetes version: v1.14.8
  • Hosting on Azure Kubernetes Service (AKS)
-- RQDQ
kubernetes
kubernetes-ingress
nginx
nginx-ingress
url-rewriting

1 Answer

11/26/2019

This is not likely to be an issue with AKS, as the components you use are working on top of Kubernetes layer. However, if you want to be sure you can deploy this on top of minikube locally and see if the problem persists.

There are also few other things to consider:

  1. There is a detailed guide about creating ingress controller on AKS. The guide is up to date and confirmed to be working fine.

This article shows you how to deploy the NGINX ingress controller in an Azure Kubernetes Service (AKS) cluster. The cert-manager project is used to automatically generate and configure Let's Encrypt certificates. Finally, two applications are run in the AKS cluster, each of which is accessible over a single IP address.

  1. You may also want to use alternative like Traefik:

Traefik is a modern HTTP reverse proxy and load balancer made to deploy microservices with ease.

  1. Remember that:

Operators will typically wish to install this component into the kube-system namespace where that namespace's default service account will ensure adequate privileges to watch Ingress resources cluster-wide.

Please let me know if that helped.

-- OhHiMark
Source: StackOverflow