我的请求通过Cloudflare代理,Cloudflare根据IP地址在http标头中设置一个指示国家/地区的标头。我想根据Nginx入口控制器中的这个头,用特定的路径重定向请求。我该怎么做?
当前nginx-ingress
的Ingress
资源定义不支持基于标头的路由
我找到了一个解决方法,通过其标头路由请求(我已经包括了以下步骤(,并添加了以下注释:
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($http_LocationHeader = "PL") { proxy_pass http://goodbye-service.default.svc.cluster.local:5678; }
其他可能的解决方案/解决方案:
- 使用
Traefik
:Docs.traefik.io:路由:路由器 - 使用
Ambassador
:Getambassador.io:Docs:Using:Headers - 使用
Istio
:Istio.io:流量管理:请求路由 - 将流量从
nginx-ingress
路由到nginx pod/deployment/daemonset,其中包含基于标头的路由逻辑:Stackloverflow.com:如何使用nginx ingress控制器拥有标头路由逻辑(答案下的最后一条评论(
作为解决方法:
假设(例如(:
- 共有2个部署:
hello
、goodbye
- 两者都与其服务关联,名称分别为:
hello-service
、goodbye-service
Ingress
资源将以hello
应始终应答的方式进行配置,但添加configuration-snippet
后,流量将重定向到goodbye
。
本次部署的响应:
| hello | goodbye |
|----------------|----------------|
| Hello, world! | Hello, world! |
| Version: 2.0.0 | Version: 1.0.0 | # notice the version
附带服务的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
要获得goodbye
部署,请将hello
替换为goodbye
,并将映像版本更改为1.0
。
通过标头重新路由请求的入口定义如下:
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
默认情况下,该没有configuration-snippet
的入口定义将始终将业务路由到hello-service
,然后路由到hello
吊舱。通过添加:
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($http_LocationHeader = "PL") { proxy_pass http://goodbye-service.default.svc.cluster.local:5678; }
它将检查名为CCD_ 23的报头是否存在以及它是否匹配CCD_。如果它这样做了,它将通过它的DNS名称向goodbye-service
发送请求。
专注于:
http://goodbye-service.default.svc.cluster.local:5678
http://service_name.namespace.svc.cluster.local:port
(没有值的dns名称(
应用此Ingress
资源后,您应该能够使用LocationHeader=PL
发送请求(例如使用Postman(并获得响应:
Hello, world!
Version: 1.0.0
Hostname: goodbye-5758448754-wr64c
当我尝试使用
map
指令时,我收到了以下消息:
nginx: [emerg] "map" directive is not allowed here in /tmp/nginx-OMMITED