Nginx 入口控制器重写目标注释和规则以向 url

时间:2020-12-28 19:00:19

标签: kubernetes kubernetes-ingress nginx-ingress

我正在尝试将静态网站部署到使用官方 Nginx Ingress 控制器的 Kubernetes 集群。网站的文件夹结构看起来有点像这样:

/
├── about
│   └── index.html
├── casestudy
│   ├── data-and-analytics
│   │   └── index.html
│   └── workflow-automation
│       └── index.html
├── contact
│   └── index.html
├── css
│   ├── font-awesome.min.css
│   ├── fonts
│   │   ├── slick.eot
│   │   ├── slick.svg
│   │   ├── slick.ttf
│   │   └── slick.woff
│   ├── footer.css
│   ├── layout.css
...

我的入口定义如下:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: website-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    # nginx.ingress.kubernetes.io/rewrite-target: /$2
    cert-manager.io/cluster-issuer: letsencrypt
spec:
  tls:
    - hosts:
        - website.com
      secretName: website-tls
  rules:
    - host: website.com
      http:
        paths:
          - path: /
            backend:
              serviceName: website-svc
              servicePort: 8080

这在大多数情况下都可以正常工作,但如果我忘记在 URL 末尾添加一个斜杠,例如 https://website.com/about,我将被路由到错误页面。我明白为什么会发生这种情况 - Nginx 正在寻找一个 about.html 文件但没有找到。但我不知道如何解决这个问题。

理想情况下,我想在没有 / 的请求中添加一个尾随 YourClass.class.getResourceAsStream("foo.txt")。但我也不想在浏览器请求 css 文件时这样做。

我应该为此使用什么重定向注释和规则?

谢谢。

2 个答案:

答案 0 :(得分:2)

最终对这种情况起作用的是这样的片段:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: website-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt
    nginx.ingress.kubernetes.io/rewrite-target: /
    # Rewrite all URLs not ending with a segment containing . or ? with a trailing slash
    # So basically we are rewriting all folder names with a trailing slash.
    nginx.ingress.kubernetes.io/configuration-snippet: |
      rewrite ^([^.?]*[^/])$ $1/ redirect;
spec:
  tls:
    - hosts:
        - website.com
      secretName: website-tls
  rules:
    - host: website.com
      http:
        paths:
          - path: /
            backend:
              serviceName: website-svc
              servicePort: 8080

这将让我们重写所有以不包含 . (句点 - 从而避免文件名)? (问号 - 从而避免所有查询字符串) 带有尾部斜杠。这适用于我的情况。

答案 1 :(得分:0)

试试这个:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: website-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$1/
spec:
  rules:
    - http:
        paths:
          - path: /(.*)
            backend:
              serviceName: website-svc
              servicePort: 8080

它非常适合我。运行后:

curl <ingress ip>/about

您可以在日志中看到以下内容:

入口控制器

kubectl logs -n ingress-nginx ingress-nginx-controller-6dc856845b-rf2ft

<ip address> - - [29/Dec/2020:18:40:13 +0000] "GET /about HTTP/1.1" 200 7 "-" "curl/7.64.0" 83 0.000 [default-nginx-deployment-80] [] 10.0.1.8:80 7 0.000 200 (...)

为网站提供服务的 nginx pod

kubectl logs nginx-deployment-6c8c7fdf65-w4h4b

10.0.1.10 - - [29/Dec/2020:18:40:13 +0000] "GET /about/ HTTP/1.1" 200 7 "-" "curl/7.64.0" "<ip address>"