如何在 Kubernetes 入口控制器中将请求 uri 的一部分作为自定义 header 传递

How to pass the part of request uri as custom header in Kubernetes ingress controller

我在 ingress.yaml 中进行了以下配置,它将带有 /default/demoservice/health 或 /custom/demoservice/health 之类的 uris 的请求转发到后端演示服务。我想从 uri 中检索 uri 的第一部分(即上面示例中的默认或自定义)并作为自定义 header 传递给上游。

我已经使用自定义 header

部署了入口配置映射
X-MyVariable-Path: ${request_uri} 

但这会发送完整的请求 uri。我该如何拆分?

- path: "/(.*?)/(demoservice.*)$"
  backend:
    serviceName: demoservice
    servicePort: 80

我找到了两种实现此目的的方法。

一种是在您的 configmap 中使用正则表达式来解析 request_uri 的第一部分。

要执行上述操作,您需要在您的入口添加 nginx.ingress.kubernetes.io/use-regex: "true" 注释,然后再这样做。因为这默认设置为 false

另一种方法是在注释本身中定义特定的 header 并添加类似 </code> 的内容,下面是示例。</p> <pre><code>ingress.kubernetes.io/configuration-snippet: | more_set_headers "X-MyVariable-Path: ";

不完全确定,这对你有用。但是我从这里的 Rewrite 示例中得到了这个逻辑。

并将路径添加为 /customheader(/|$)(.*) 这样会创建一个捕获组。

希望它有用并有所帮助。

我找到了解决方案,对其进行了测试并且有效。
您只需要在入口对象中添加以下注释即可:

nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/configuration-snippet: |  
proxy_set_header X-MyVariable-Path ;  

其中 </code> 引用 <code>path: 字段中第一组正则表达式中捕获的任何内容。

我使用以下 yaml 重现了您的场景:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/configuration-snippet: |
      proxy_set_header  X-MyVariable-Path  ;
    nginx.ingress.kubernetes.io/use-regex: "true"
  name: foo-bar-ingress
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: echo
          servicePort: 80
        path: /(.*?)/(demoservice.*)$
---
apiVersion: v1
kind: Service
metadata:
  labels:
    run: echo
  name: echo
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    run: echo
---
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: echo
  name: echo
spec:
  containers:
  - image: mendhak/http-https-echo
    imagePullPolicy: Always
    name: echo

您可以使用 curl 进行测试:

curl -k https://<your_ip>/default/demoservice/healthz

输出:

 {
  "path": "/default/demoservice/healthz",
  "headers": {
    "host": "192.168.39.129",
    "x-request-id": "dfcc67a80f5b02e6fe6c647c8bf8cdf0",
    "x-real-ip": "192.168.39.1",
    "x-forwarded-for": "192.168.39.1",
    "x-forwarded-host": "192.168.39.129",
    "x-forwarded-port": "443",
    "x-forwarded-proto": "https",
    "x-scheme": "https",
    "x-myvariable-path": "default", # your variable here
    "user-agent": "curl/7.52.1",
    "accept": "*/*"
  },
  "method": "GET",
  "body": "",
  "fresh": false,
  "hostname": "192.168.39.129",
  "ip": "::ffff:172.17.0.4",
  "ips": [],
  "protocol": "http",
  "query": {},
  "subdomains": [],
  "xhr": false,
  "os": {
    "hostname": "echo"
  }
}

希望对您有所帮助=)