[英]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:其他可能的解决方案/解决方法:
Traefik
: Docs.traefik.io: Routing: Routers使用Traefik
: Docs.traefik.io:路由:路由器Ambassador
: Getambassador.io: Docs: Using: Headers使用Ambassador
: Getambassador.io:文档:使用:标头Istio
: Istio.io: Traffic management: Request routing使用Istio
: Istio.io:流量管理:请求路由nginx-ingress
to nginx pod/deployment/daemonset with header based routing logic included: Stackoverflow.com: How to have a header routing logic with nginx ingress-controller?使用基于 header 的路由逻辑将流量从nginx-ingress
路由到 nginx pod/deployment/daemonset: Stackoverflow.com:How to have a header routing logic with nginx ingress-controller? (last comment under the answer) (答案下的最后评论)As for a workaround :至于解决方法:
Assuming that (for example purposes):假设(出于示例目的):
hello
, goodbye
有 2 个部署: hello
, goodbye
hello-service
, goodbye-service
两者都与他们的服务相关联,名称为: hello-service
, goodbye-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.