Search code examples
kuberneteskubernetes-ingressnginx-ingressdocker-for-windowsmicrok8s

Ingress - simple fanout configuration not working


I'm using Ubuntu 20.04.2 LTS. I installed microk8s 1.20.6 rev 2143 and experimenting with ingress. I must be missing something - but it doesn't work as I expect it to. I tracked the strange behavior down to the following configuration:

ingress.yaml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ubuntu
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: my-ubuntu
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx
            port:
              number: 80
      - path: /nginx
        pathType: Prefix
        backend:
          service:
            name: nginx
            port:
              number: 80

nginx-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
    - port: 80
      name: http
    - port: 443
      name: https
  type: ClusterIP
  selector:
    app: nginx

Now,

curl my-ubuntu/                     # this returns Welcome page, as expected
curl my-ubuntu/nginx                # this returns Welcome page, as expected
curl my-ubuntu/bad-page.html        # this returns 404 Not Found, as expected
curl my-ubuntu/nginx/bad-page.html  # this returns Welcome page. WHY?

Any request under my-ubuntu/nginx/* returns Welcome page, even when the url is correct and should have returned different content. Did I configure something wrong?

I was able to reproduce the same strange behavior using Docker for Windows + WSL2 + Ubuntu + ingress installed using:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.41.2/deploy/static/provider/cloud/deploy.yaml

EDIT

nginx-deployment.yaml I used:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 1
  revisionHistoryLimit: 0
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        imagePullPolicy: Always
        name: nginx

When I try /nginx/ instead of /nginx like @HarshManvar suggested, I get this behavior:

curl my-ubuntu/                     # this returns Welcome page, as expected
curl my-ubuntu/bad-page.html        # this returns 404 Not Found, as expected
curl my-ubuntu/nginx                # this returns 404 Not Found
curl my-ubuntu/nginx/               # this returns Welcome page
curl my-ubuntu/nginx/bad-page.html  # this returns Welcome page

Kubernetes Ingress documentation about Simple fanout also does use /nginx pattern but not working as described above.


Solution

  • https://kubernetes.github.io/ingress-nginx/examples/rewrite/ explains how to use rewrite-target annotation. I was able to make it work with the following ingress.yaml:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-ubuntu
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /$1
    spec:
      rules:
      - host: localhost
        http:
          paths:
          - path: /(.*)
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
          - path: /nginx($|/.*)
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
    

    Each path defines regular expression with ( ), which yields $1, $2, etc., aka. regex capture group variables. Now you put rewrite-target using those variables, and that will be the actual URL that is passed to the service's container that handles the request.

    Maybe there is another way, but this is the only way I was able to make it work.