nginx-ingress is not able to route to pod application

44 Views Asked by At

I have an nginx-ingress controller deployed in my k8s cluster.

Also, I have defined path for the service to route which is the root path to the load balancer.

The app(react) is working fine, routes to pages as per the react app.

The url changes as the react app router, but when i refresh the page its giving error 404 not found.

My Thoughts: when reloading the page its calling the ingress controller but there is no path defined for the url. so not found error(404)

I want the page to load again from the react app but its showing 404.

My ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: host-ingress
  namespace: feeleat
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: admin.example.com
    http:
      paths:
      - pathType: Prefix
        path: /(.*)
        backend:
          service:
            name: example-service
            port:
              number: 80
  - host: api.example.ch
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: example-1-service
            port:
              number: 80
1

There are 1 best solutions below

7
Jim Wright On

I think that your rewrite is incorrect. From the docs I think that all requests will be rewritten to /.

Try specifying the capture groups within the routes like this:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: host-ingress
  namespace: feeleat
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
  - host: admin.example.com
    http:
      paths:
      - pathType: ImplementationSpecific
        path: (/|$)(.*)
        backend:
          service:
            name: example-service
            port:
              number: 80
  - host: api.example.com
    http:
      paths:
      - pathType: ImplementationSpecific
        path: (/|$)(.*)
        backend:
          service:
            name: example-1-service
            port:
              number: 80

That said, I don't think you actually need a rewrite. You are mapping paths directly to the service. Rewrites are only needed if the backend app expects something different. For example: A route of api.example.com/my-app/food in the ingress when the backend app expects api.example.com/food would need a rewrite like so:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: host-ingress
  namespace: feeleat
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - host: api.example.com
    http:
      paths:
      - pathType: ImplementationSpecific
        path: /my-app(/|$)(.*)
        backend:
          service:
            name: example-service
            port:
              number: 80

Try removing it completely:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: host-ingress
  namespace: feeleat
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: admin.example.com
    http:
      paths:
      - pathType: Prefix
        path: /
        backend:
          service:
            name: example-service
            port:
              number: 80
  - host: api.example.com
    http:
      paths:
      - pathType: Prefix
        path: /
        backend:
          service:
            name: example-1-service
            port:
              number: 80

EDIT: You commented that you also need SSL certificates.

In kubernetes, SSL certs are stored as secrets and referenced in the spec.tls config.

If you already have the certificates you can create a secret and reference them inside of the ingress. The following assumes a wildcard SSL cert for example.com.

kubectl create secret tls wildcard-example-tls \
    --namespace feeleat\
    --key server.key \
    --cert server.crt

And then tell nginx that you want to use it:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: host-ingress
  namespace: feeleat
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  tls:
  - hosts:
    - admin.example.com
    - api.example.com
    secretName: wildcard-example-tls
  rules:
  - host: admin.example.com
    http:
      paths:
      - pathType: Prefix
        path: /
        backend:
          service:
            name: example-service
            port:
              number: 80
  - host: api.example.com
    http:
      paths:
      - pathType: Prefix
        path: /
        backend:
          service:
            name: example-1-service
            port:
              number: 80

If you don't already have a certificate, or you don't want to manage them manually, then you can use cert-manager. I won't go into detail on cert-manager here, but it will automatically manage the issuing and re-issuing of certificates for you.

You may find this documentation useful: https://cert-manager.io/docs/tutorials/acme/nginx-ingress/