amazon-web-serviceskubernetesnginx-ingressingress-controller

Routing through nginx to service based off entered path


I deployed a test service that's called "web-server-service". That is connected to a container which when working just displayed a message on the screen (like a browser, etc): "It works!". Purley as a connectivity test.

enter image description here

Ingress controller = Nginx. All of this is running in AWS.

I have set up an ingress controller and created an ingress resource

apiVersion: v1
kind: Namespace
metadata:
  name: web
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
  namespace: web
spec:
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: httpd
        image: httpd:2.4.48-alpine3.14
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: web-server-service
  namespace: web
spec:
  selector:
    app: web
  ports:
    - protocol: TCP
      port: 5000
      targetPort: 80

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-server-ingress
  namespace: web
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  ingressClassName: nginx
  rules:
  - host: somehost.com
    http:
      paths:
      - path: / #this works
        pathType: Prefix
        backend:
          service:
            name: web-server-service
            port:
              number: 5000
      - path: /test #this does not work. returns 404
        pathType: Prefix
        backend:
          service:
            name: web-server-service
            port:
              number: 5000

The problem I am having is that as long as I keep the path as just "/" then it works when I connect through the browser, curl, etc. But as soon as I actually add in a different path like "/test", it sends back a 404. It is almost like when it does the poxy_pass it adds that path to the end of the proxy_path url, making it not find the correct destination.

I expect this to act like a proxy to send the request to a service. In this case, it is the same service but eventually, it will be different services that are running.

Using Rewrite:

I understand that there is some rewrite functionality but I could not get it to work. It still returns the same 404. This is the ingress config I tried for that:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-server-ingress
  namespace: web
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  rules:
  - host: somehost.com
    http:
      paths:
      - path: / #this works
        pathType: Prefix
        backend:
          service:
            name: web-server-service
            port:
              number: 5000
      - path: /test(/|$)(.*) #this still does not work. returns 404
        pathType: Prefix
        backend:
          service:
            name: web-server-service
            port:
              number: 5000

Perhaps my rewrite is incorrect?

I essentially just want it to pass the request along to the service and not add in any paths when it does. I expect both the path of "/" and "/test" to be able to display the "It works!" message.

Has anyone got any input on what I am doing wrong? Thanks


Solution

  • Debug Steps:

    1. Check your ingress controller pod logs to see what request is it actually making in the background due to which you are getting 404.

    Details w.r.t. Ingress to get the rewrite-target functionality along with the use-cases

    $ echo '
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        nginx.ingress.kubernetes.io/use-regex: "true"
        nginx.ingress.kubernetes.io/rewrite-target: /$2
      name: rewrite
      namespace: default
    spec:
      ingressClassName: nginx
      rules:
      - host: rewrite.bar.com
        http:
          paths:
          - path: /something(/|$)(.*)
            pathType: Prefix
            backend:
              service:
                name: http-svc
                port: 
                  number: 80
    ' | kubectl create -f -
    

    In this ingress definition, any characters captured by (.*) will be assigned to the placeholder $2, which is then used as a parameter in the rewrite-target annotation.

    For example, the ingress definition above will result in the following rewrites:

    rewrite.bar.com/something rewrites to rewrite.bar.com/
    rewrite.bar.com/something/ rewrites to rewrite.bar.com/
    rewrite.bar.com/something/new rewrites to rewrite.bar.com/new
    

    Source: https://github.com/kubernetes/ingress-nginx/tree/main/docs/examples/rewrite