使用 Kubernetes Ingress 在网站上导航

Navigation on website with Kubernetes Ingress

我正在尝试在我的 Kubernetes 集群中公开一个网站。因此,我创建了一个链接到我的服务和我的 Pod 的 Ingress。到目前为止,一切正常。 但是现在,当我开始在我的页面上导航时,URL 发生了变化,但显示的站点仍然是“主页”。 如何在页面上导航并正确访问所有子页面?

我的部署:

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

我的服务:

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

我的入口:

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

该网页是一个 NodeJS express 网页。 这是我的 routes.js 文件供参考(如果您需要更多文件,请告诉我):

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;

每次我尝试访问该页面时,我都是从主页开始的。当我单击一些通常会将我重定向到子页面的按钮时,即使 URL 正确更改,我仍停留在主页上。 比如首页URL是:www.mydomain.com/wichteln→可以看到首页。 www.mydomain.com/wichteln/usermanagement → 我仍然可以看到主页,但想看到子页面“usermanagement”。

感谢您的帮助。

问题很可能来自于您在入口清单中的重写。

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

这意味着当入口接收到来自客户端的请求时,它会获取 url 的 path 部分并将其重写为 /,然后再将其传递给您的后端,这反过来会导致后端返回您网站的根页面。

您应该删除重写注释并使用这个注释: nginx.ingress.kubernetes.io/use-regex: "true"

在您的路径配置中,您可以尝试类似的操作:

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

此配置创建以下 NGINX 位置块:

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

路径重写 + 捕获组

您可以使用捕获组捕获路径前缀之后的部分,并在重写规则中使用它see the docs

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

上下文路径

或者,并且并不少见,是将上下文路径注入您的应用程序。然后你不需要在你的入口清单上重写任何路径。

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

要注入它,请将其添加到 pod 规范中。

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