0

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

Gene Smith
  • 169
  • 12

2 Answers2

1

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

Shubham Vaishnav
  • 1,637
  • 6
  • 18
  • Thanks, Having a look at the logs of the pod, I can actually see the requests coming through regardless of the path I set. This should be perfect for a few webservice endpoints I have set up. – Gene Smith Mar 20 '23 at 08:54
  • I was also under the impression that the 404 was coming back from Nginx itself (not being able to find the service), but it was actually the webservice in the pod. – Gene Smith Mar 20 '23 at 09:04
0

I actually ended up making use of the Nginx Ingress resource "VirtualServer". Something like the following can be used to proxy and rewrite paths. https://github.com/nginxinc/kubernetes-ingress/tree/v3.0.2/examples/custom-resources/rewrites

apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
  name: web-server-ingress-vs
  namespace: web
spec:
  host: somehost.com
  upstreams:
  - name: web-test
    service: web-server-service
    port: 5000
  - name: another-one
    service: web-server-service
    port: 5000
  routes:
  - path: /
    action:
      pass: web-test
  - path: /test
    action:
      proxy:
        upstream: another-one
        requestHeaders:
          pass: true
        rewritePath: /
  - path: /test2
    action:
      proxy:
        upstream: another-one
        requestHeaders:
          pass: true
        rewritePath: /
Gene Smith
  • 169
  • 12