nginx.ingress.kubernetes.io/rewrite-target: /$1 在 minikube 注释中究竟是什么意思?

vag*_*i k 4 nginx kubernetes minikube nginx-ingress

在使用 minikube ingress 时,我必须编写nginx.ingress.kubernetes.io/rewrite-target: /$1. 我一直在努力理解为什么我们需要这个注释以及如何使用它。

我知道医生说以下内容:

在某些情况下,后端服务中暴露的 URL 与 Ingress 规则中指定的路径不同。如果没有重写,任何请求都将返回 404。将注释 nginx.ingress.kubernetes.io/rewrite-target 设置为服务预期的路径。

但我无法准确理解到底the exposed URL in the backend service differs from the specified path in the Ingress rule是什么意思。我无法清楚地理解这个想法。

此外,在尝试使用服务执行入口文件时:

代码1:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: example-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - host: myexample.com
      http:
        paths:
          - path: /
            pathType: Prefix 
            backend:
              service:
                name: example-service
                port:
                  number: 80
Run Code Online (Sandbox Code Playgroud)

代码2:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: example-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: myexample.com
      http:
        paths:
          - path: /
            pathType: Prefix 
            backend:
              service:
                name: example-service
                port:
                  number: 80
Run Code Online (Sandbox Code Playgroud)

代码3:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: example-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - host: myexample.com
      http:
        paths:
          - path: /index
            pathType: Prefix 
            backend:
              service:
                name: example-service
                port:
                  number: 80
Run Code Online (Sandbox Code Playgroud)

关于上面提到的重写目标和路径,上述 3 个代码片段的每一对之间究竟有什么区别?

PS:我是 minikube 的新手,并试图弄清楚事情的确切工作方式。请帮忙。

And*_*ndD 6

我不知道情况是否会随着 Ingress 资源的新版本或 Nginx Ingress Controller 的新版本而改变,但我认为这就是它的工作原理。

假设我想在同一个域下使用 Ingress 为 2 个不同的 Web 应用程序提供服务。

  • 应用程序 A 正在等待以下请求 /
  • 应用程序 B 正在等待以下请求 /

因此,两个应用程序都期望它们的请求直接在 root 下,这(乍一看)似乎使它们无法在同一个域中提供服务。

除了重写目标,我可以。我可以在不同的路径下为他们服务,但将目标重写为/

  • 服务应用程序 A 下 myexample.com/aaa/
  • 服务应用程序 B 下 myexample.com/bbb/

并添加重写目标以删除路径的第一部分。这只是重写目标可用于什么的一个示例,它只是让您能够在应用程序本身期望的不同路径下为应用程序提供服务。

入口示例:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: example-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
    - host: myexample.com
      http:
        paths:
          - path: /aaa(/|$)(.*)
            pathType: Prefix 
            backend:
              service:
                name: app-a
                port:
                  number: 80
          - path: /bbb(/|$)(.*)
            pathType: Prefix 
            backend:
              service:
                name: app-b
                port:
                  number: 80
Run Code Online (Sandbox Code Playgroud)

请注意,虽然这在 Rest API 和类似的东西上工作得很好,但它在网页上可能不太好用,因为网页可能会尝试在不同的路径加载资源(例如,如果它不使用相对路径)。这就是为什么(通常)前端应用程序需要知道它们在域下的哪条路径上提供服务。


关于重写目标的语法,我以我上面写的Ingress为例。有几件事情需要考虑:

  • 小路
  • 路径类型
  • 重写目标

让我们开始pathpathType互动。通过路径,我可以定义在哪里为我的服务提供服务。取决于pathType,它可能只是Prefix整个路径的一个,Exact路径,或者它可以取决于入口控制器(又名ImplementationSpecific)。一切都在文档中用一长串示例很好地解释了 ( https://kubernetes.io/docs/concepts/services-networking/ingress/#examples )

我几乎可以用 path 和 pathType 做所有事情,除非我想要服务的应用程序期望在与 Ingress 中指定的路径不同的路径上提供服务;这就是rewrite-target发挥作用的时候。

就像在上面的示例中一样,我可以使用rewrite-target与预期路径不同的路径为应用程序提供服务,根据需要组合 url。我还可以使用正则表达式和捕获组(这是什么$1$2等等)

例如,如果我写path: /bbb(/|$)(.*)我的意思是这个路径将匹配 /bbb 下的所有内容,在 bbb 之后有或没有 /。如果我接着写rewrite-target: /$2,我的意思是请求将被重写,以取代/bbb/再取第二个捕获组(意即第二正则表达式(.*)

文档很好地解释了它,即使它仍然使用旧的 Ingress 资源(https://kubernetes.github.io/ingress-nginx/examples/rewrite/