【问题标题】:Kubernetes: Issue with 2 Ingress object with regex pathKubernetes:带有正则表达式路径的 2 个 Ingress 对象的问题
【发布时间】:2022-01-25 18:21:54
【问题描述】:

我有 2 个入口对象

first-ingress.yml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: first-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt"
    acme.cert-manager.io/http01-edit-in-place: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  tls:
    - hosts:
        - www.example.com
      secretName: example-tls
  rules:
    - host: www.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: first-service
                port:
                  number: 80

second-ingress.yml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: second-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    cert-manager.io/cluster-issuer: "letsencrypt"
    acme.cert-manager.io/http01-edit-in-place: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  tls:
    - hosts:
        - www.example.com
      secretName: example-tls
spec:
  rules:
    - host: www.example.com
      http:
        paths:
          - path: /test(/|$)(.*)
            pathType: Prefix
            backend:
              service:
                name: second-service
                port:
                  number: 80

期望是:

www.example.com/test/whatever -> 二次服务

www.example.com -> 第一服务

我看到的是www.example.com/test/whateverwww.example.com都到达了第一服务

如果我更改第二入口以将正则表达式替换为静态路径,它将起作用。 www.example.com/test/whatever会打二服

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: second-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt"
    acme.cert-manager.io/http01-edit-in-place: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  tls:
    - hosts:
        - www.example.com
      secretName: example-tls
spec:
  rules:
    - host: www.example.com
      http:
        paths:
          - path: /test
            pathType: Prefix
            backend:
              service:
                name: second-service
                port:
                  number: 80

知道为什么正则表达式不起作用吗?我需要重写目标规则,这就是我使用正则表达式的原因

【问题讨论】:

    标签: kubernetes nginx-ingress


    【解决方案1】:

    您发布的正则表达式与 NGINX Ingress Controller docs 中的示例完全相同,但 yaml 文件错误(一个错误与双 spec,下面是更多信息)-我在 Kubernetes 上测试了您的 yamls 文件v.1.21、NGINX 控制器版本 v.1.0.2 和 Cert Manager v1.6.1。

    关于可能出错的一些注释/想法:


    而不是使用两次spec: (second-ingress.yaml) , use spec only once。我没有观察到前缀本身的行为变化,但是在第二个入口的kubectl get ing 命令中没有指定 443 端口。当我运行kubectl get ing second-ingress -o yaml 时,缺少 TLS 部分。

    之前(错误设置)second-ingress.yaml文件:

    spec:
      tls:
        - hosts:
            - www.example.com
          secretName: example-tls
    spec:
      rules:
    

    kubectl get ing 输出(缺少第二个入口的 443 端口):

    user@cloudshell:~/ingress-two-services $ kubectl get ing
    NAME             CLASS    HOSTS             ADDRESS       PORTS     AGE
    first-ingress    <none>   www.example.com   xx.xx.xx.xx   80, 443   5h7m
    second-ingress   <none>   www.example.com   xx.xx.xx.xx   80        50m
    

    kubectl get ing second-ingress -o yaml 输出(缺少tls 部分):

    user@cloudshell:~/ingress-two-services $ kubectl get ing second-ingress -o yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    ...
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - backend:
              service:
                name: second-service
                port:
                  number: 80
            path: /test(/|$)(.*)
            pathType: Prefix
    status:
    ...
    

    之后(良好的设置)second-ingress.yaml文件:

    spec:
      tls:
        - hosts:
            - www.example.com
          secretName: example-tls
      rules:
    

    kubectl get ing 输出:

    user@cloudshell:~/ingress-two-services $ kubectl get ing
    NAME             CLASS    HOSTS             ADDRESS       PORTS     AGE
    first-ingress    <none>   www.example.com   xx.xx.xx.xx  80, 443   5h18m
    second-ingress   <none>   www.example.com   xx.xx.xx.xx  80, 443   61m
    

    kubectl get ing second-ingress -o yaml 输出:

    user@cloudshell:~/ingress-two-services $ kubectl get ing second-ingress -o yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    ...
    spec:
      rules:
      - host: www.example.com
        http:
          paths:
          - backend:
              service:
                name: second-service
                port:
                  number: 80
            path: /test(/|$)(.*)
            pathType: Prefix
      tls:
      - hosts:
        - www.example.com
        secretName: example-tls
    status:
    ...
    

    另一件值得注意的事情是,修改后的第二个入口配置的行为与不适合您的配置不同。

    使用nginx.ingress.kubernetes.io/rewrite-target: /$2 + path: /test(/|$)(.*)

    • www.example.com/test/ 会将对 pod 的请求重写为 /
    • www.example.com/test/whatever 将对 Pod 的请求重写为 /whatever

    但是,只使用path: /test:

    • www.example.com/test/ 会将对 Pod 的请求重写为 /test
    • www.example.com/test/whatever 会将对 Pod 的请求重写为 /test/whatever

    请确保您使用的是适用于您的应用的正确设置。


    其他提示:

    • 确保通过运行kubectl get ing 命令应用入口
    • 获取 NGINX Ingress Controller 的日志。获取 Ingress Controller pod 的名称 (kubectl get pods -n ingress-nginx),然后运行 ​​kubectl logs -n ingress-nginx ingress-nginx-controller-{...}。检查您的请求是如何处理的以及它们被转发到哪里(哪个服务)
    • 检查部署中的 pod 日志并检查它们如何处理请求 (kubectl logs {pod-name})
    • 如果您使用的是 Kubernetes 的一些过时版本,最好升级它

    【讨论】:

    猜你喜欢
    • 2017-02-21
    • 2021-08-31
    • 2018-01-08
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    • 2018-01-23
    • 2023-03-07
    • 1970-01-01
    相关资源
    最近更新 更多