Home > Mobile >  Navigation on website with Kubernetes Ingress
Navigation on website with Kubernetes Ingress

Time:12-05

I'm trying to expose a website inside my Kubernetes Cluster. Therefor I created an Ingress that links to my Service and so to my Pod. Till this point, everything works perfectly fine. But now when I start navigating on my Page the URL changes, but the shown site stays the “Homepage”. How is it possible to navigate on the page and access all the subpages properly?

My Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wichteln-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wichteln
  template:
    metadata:
      labels:
        app: wichteln
    spec:
      containers:
      - image: jonasgoetz01/website:V1.0
        name: wichteln-container
        command: ["/bin/sh"]
        args:
          - -c
          - >-
              apt update

My Service:

apiVersion: v1
kind: Service
metadata:
  name: wichteln-service
spec:
  selector:
    app: wichteln
  ports:
    - protocol: TCP
      port: 5000
      targetPort: 5000

My Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: wichteln-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: public
  rules:
    - http:
        paths:
          - path: /wichteln/*
            pathType: Prefix
            backend:
              service:
                name: wichteln-service
                port:
                  number: 5000

The Webpage is a NodeJS express Webpage. Here is my routes.js file for reference (If you need more files, please let me know):

const express = require('express');
const router = express.Router();
const controller = require('../controllers/controller');

// Routes
router.get('/', controller.home);

router.get('/usermanagement/', controller.viewuser);
router.post('/usermanagement/', controller.finduser);
router.get('/usermanagement/adduser', controller.formuser);
router.post('/usermanagement/adduser', controller.createuser);
router.get('/usermanagement/edituser/:id', controller.edituser);
router.post('/usermanagement/edituser/:id', controller.updateuser);
router.get('/usermanagement/viewuser/:id', controller.viewalluser);
router.get('/usermanagement/:id',controller.deleteuser);
  
module.exports = router;

Every time I try to access the page, I start at the homepage. When I click on some buttons that normally would redirect me to a subpage, I stay at the homepage even if the URL changes correctly. For example, the home URL is: www.mydomain.com/wichteln → I can see the homepage. www.mydomain.com/wichteln/usermanagement → I can still see the homepage but want to see the subpage “usermanagement”.

Thank you for your help.

CodePudding user response:

The issue is most likely coming from the rewrite that you have in your ingress manifest.

    nginx.ingress.kubernetes.io/rewrite-target: /

this means that when the ingress receives the request from the client it takes the path portion of the url and rewrites it to be /, before passing it down to your backend, which in turn results in backend returning the root page of your website.

CodePudding user response:

You should remove the rewrite annotation and use this one: nginx.ingress.kubernetes.io/use-regex: "true"

And in your path configuration you can try something like that:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: wichteln-ingress
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  ingressClassName: public
  rules:
    - http:
        paths:
          - path: /wichteln/.*
            pathType: Prefix
            backend:
              service:
                name: wichteln-service
                port:
                  number: 5000

This configuration creates the following NGINX location block:

location ~* "^/wichteln/.*" {
  ...
}

CodePudding user response:

Path Rewrite Capture Groups

You can use capture groups to capture the part after the path prefix and use it in the rewrite rule see the docs.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: wichteln-ingress
  annotations:
      nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: public
  rules:
    - http:
        paths:
          - path: /wichteln/(/|$)(.*)
            pathType: Prefix
            backend:
              service:
                name: wichteln-service
                port:
                  number: 5000

Context Path

Alternatively, and not uncommon, is it to inject a context path into your application. Then you don't need any path rewrite on your ingress manifest.

...
const ctx = process.env.CONTEXT_PATH || ''
router.get(`${ctx}/`, controller.home);
router.get(`${ctx}/usermanagement/`, controller.viewuser);
...

To inject it, add it to the pod spec.

...
spec:
  containers:
    - image: jonasgoetz01/website:V1.0
      env:
        - name: CONTEXT_PATH
          value: /wichteln
...
  • Related