2
votes

I have been trying my Nginx Path-Based routing to work, however, after spending almost 4 hours, I am failed to understand, why is it not working. I have gone through almost every possible answer on StackOverflow before anyone downgrades my question, but none worked for me.

So here what I did:

  1. I installed nginx-ingress using Helm 3 (https://docs.nginx.com/nginx-ingress-controller/installation/installation-with-helm/) in a separate namespace - nginx-test:

    helm install my-release nginx-stable/nginx-ingress

A version of the ingress controller (https://hub.helm.sh/charts/nginx-edge/nginx-ingress):

$ POD_NAME=$(kubectl get pods -l app=nginx-controller-nginx-ingress -o jsonpath='{.items[0].metadata.name}')
$ 
$ kubectl exec -it $POD_NAME -- /nginx-ingress --version
Version=edge GitCommit=50e908aa
$ 
  1. There are 2 basic nginx deployments, 2 services already configured in the same namespace, and working fine when I configure host-based routing for them.

  2. Below one works fine for me (when I define host-based routing and get the required page index.html when I run both individual URLs):

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
  - host: nginx1.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx1
          servicePort: 80

  - host: nginx2.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx2
          servicePort: 80

Now I wanted to achieve the same result using Path-Based routing, where there will be 1 URL and 2 Paths /nginx1 (pointing to nginx1 service) and /nginx2 (pointing to nginx2 service). So I configured the below ingress resource (and many permutations and combinations I applied based on different examples on internet), none of them worked for me.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-path-based
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: nginx.example.com
    http:
      paths:
      - path: /nginx1
        backend:
          serviceName: nginx1
          servicePort: 80
      - path: /nginx2
        backend:
          serviceName: nginx2
          servicePort: 80

When I access services directly, it works fine, however when I try to access - curl http://nginx.example.com/nginx1 or curl http://nginx.example.com/nginx2 - I get 404 Not Found error.

I was expecting to receive the same response which I was getting for Host-Based routing. But it does not seem to work.

1
nginx ingress controller version?Arghya Sadhu
I see you are using "nginx.ingress.kubernetes.io/rewrite-target: / " in the path based routing, any specific reason for the rewrite? Can you please try once by removing it.Naveen Kulkarni
@NaveenKulkarni I have tested almost all ways to implement this, it does not work with or without it. Though I mentioned it while raising a question.Gaurav Bhaskar
@ArghyaSadhu - I have edited my question with the ingress controller version. I have been thinking there is a problem with this version for sure. I am planning to install it manually instead of helm to have it checked, but this should also work.Gaurav Bhaskar
If the version is 0.22 or above then you need to use capture group kubernetes.github.io/ingress-nginx/examples/rewrite/…Arghya Sadhu

1 Answers

2
votes

So finally I had to install the controller using manifests, instead of helm charts (edge version).

I installed it from here (https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal), changed NodePort to LoadBalancer to get a LoadBalancer IP. I am using MetalLB on BareMetal.

$ POD_NAME=$(kubectl get pods -n $POD_NAMESPACE -l app.kubernetes.io/component=controller -o jsonpath='{.items[0].metadata.name}')
$ kubectl exec -it $POD_NAME -n $POD_NAMESPACE -- /nginx-ingress-controller --version
-------------------------------------------------------------------------------
NGINX Ingress controller
  Release:       0.32.0
  Build:         git-446845114
  Repository:    https://github.com/kubernetes/ingress-nginx
  nginx version: nginx/1.17.10

-------------------------------------------------------------------------------

$ 

My Ingress resource looks like the same which I posted while asking the question.

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-path-based
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
  - host: nginx.gofork8s.com
    http:
      paths:
      - path: /nginx1
        backend:
          serviceName: nginx1
          servicePort: 80
      - path: /nginx2
        backend:
          serviceName: nginx2
          servicePort: 80

Modified the new LoadBalancer IP in /etc/hosts file to get the domain work.

192.168.0.1 nginx.example.com

Now I am able to access - http://nginx.example.com/nginx1 and http://nginx.example.com/nginx2.

I hope it will help someone. I still need to figure out settings with Helm Charts.