简体   繁体   English

如何在nginx ingress中根据http header重定向URL?

[英]How to redirect URL based on http header in nginx ingress?

My requests are being proxied through Cloudflare which sets a header indicating the country in a http header based on the IP address.我的请求是通过 Cloudflare 代理的,它根据 IP 地址在 http header 中设置 header 指示国家/地区。 I want to redirect the requests with certain paths based on this header in Nginx ingress controller. How do I do this?我想在 Nginx 入口 controller 中基于此 header 重定向具有特定路径的请求。我该怎么做?

Currently Ingress resource definition for nginx-ingress does not support header based routing.当前nginx-ingress Ingress资源定义不支持基于 header 的路由。

I found a workaround to route a request by it's header (I've included the steps below) with following annotation:我找到了一个解决方法,通过它的 header 路由请求(我已经包含了以下步骤)并带有以下注释:

    nginx.ingress.kubernetes.io/configuration-snippet: |
      if ($http_LocationHeader = "PL") { proxy_pass http://goodbye-service.default.svc.cluster.local:5678; }

Other possible solutions/workarounds:其他可能的解决方案/解决方法:


As for a workaround :至于解决方法

Assuming that (for example purposes):假设(出于示例目的):

  • There are 2 Deployments: hello , goodbye有 2 个部署: hellogoodbye
  • Both are associated with their services with names: hello-service , goodbye-service两者都与他们的服务相关联,名称为: hello-servicegoodbye-service

The Ingress resource will be configured in a way that hello should always answer, but with the addition of configuration-snippet the traffic will be redirected to goodbye . Ingress资源将以hello应始终回答的方式配置,但通过添加configuration-snippet ,流量将被重定向到goodbye

Responses of this deployments:此部署的响应:

|     hello      |    goodbye     |
|----------------|----------------|
| Hello, world!  | Hello, world!  |
| Version: 2.0.0 | Version: 1.0.0 | # notice the version

Example of hello deployment with a service attached to it:附加服务的hello部署示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello
spec:
  selector:
    matchLabels:
      app: hello
  replicas: 1
  template:
    metadata:
      labels:
        app: hello
    spec:
      containers:
      - name: hello
        image: "gcr.io/google-samples/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50001"
---
apiVersion: v1
kind: Service
metadata:
  name: hello-service
spec:
  selector:
    app: hello
  ports:
    - name: hello-port
      port: 5678 # IMPORTANT
      targetPort: 50001
  type: NodePort

To get the goodbye deployment please substitute the hello for goodbye and change the image version to 1.0 .要获得goodbye部署,请用hello代替goodbye并将图像版本更改为1.0

Ingress definition to reroute the request by a header looks like this:通过 header 重新路由请求的入口定义如下所示:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-ingress 
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/configuration-snippet: |
      if ($http_LocationHeader = "PL") { proxy_pass http://goodbye-service.default.svc.cluster.local:5678; }
spec:
  rules:
  - host: 
    http:
      paths:
      - path: /
        backend:
          serviceName: hello-service 
          servicePort: hello-port

By default this Ingress definition without the configuration-snippet would always route the traffic to hello-service and then to hello pods.默认情况下,这个没有configuration-snippet的 Ingress 定义总是将流量路由到hello-service ,然后再路由到hello pod。 By adding the:通过添加:

    nginx.ingress.kubernetes.io/configuration-snippet: |
      if ($http_LocationHeader = "PL") { proxy_pass http://goodbye-service.default.svc.cluster.local:5678; }

it will check if the header named LocationHeader is present and if it matches PL .它将检查名为LocationHeader的 header 是否存在以及它是否与PL匹配。 If it does it will send the request to goodbye-service by it's DNS name.如果是这样,它将通过名称 DNS 将请求发送到goodbye-service

Focusing on:专注于:

  • http://goodbye-service.default.svc.cluster.local:5678
  • http://service_name.namespace.svc.cluster.local:port (dns name without values) http://service_name.namespace.svc.cluster.local:port (没有值的 dns 名称)

After applying this Ingress resource you should be able to send a request with LocationHeader=PL (with Postman for example) and get the response:应用此Ingress资源后,您应该能够发送带有LocationHeader=PL的请求(例如使用Postman )并获得响应:

Hello, world!
Version: 1.0.0
Hostname: goodbye-5758448754-wr64c

When I tried to use map directive I was getting following messages:当我尝试使用map指令时,我收到以下消息:

  • nginx: [emerg] "map" directive is not allowed here in /tmp/nginx-OMMITED

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM