最近在作一个需求开发:根据请求后的不一样,nginx将请求分发到不一样的后端服务;须要修改kubernetes的ingress-nginx-controller的源码,调试的时候遇到了挺多问题,写出来,有须要的老铁能够参考。具体方案就不说了,只说一下nginx配置这一块。前端
首先贴出组件版本:ingress-nginx-controller的版本为0.9-beta.18,能够在github上找到开源的项目源码:java
nginx map配置根据请求头不一样分配流量到不一样后端服务nginx版本为:nginx version: nginx/1.13.7python
nginx.conf文件部分以下:nginx
http {
include /etc/nginx/conf.d/server-map.d/*-map.conf;
include /etc/nginx/conf.d/*-upstream.conf;
include /etc/nginx/conf.d/server-map.d/*-server.conf;
....
map_hash_bucket_size 64;
....
}复制代码
在/etc/nginx/conf.d/server-map.d/目录下的flow-ppp-map.conf:git
map $http_x_group_env $svc_upstream {
default zxl-test-splitflow-old-version;
~*old zxl-test-splitflow-old-version;
~*new zxl-test-splitflow-new-version;
}复制代码
flow-ppp-server.confgithub
server {
listen 8998;
server_name aa.hc.harmonycloud.cn;
location /testdemo/test {
proxy_pass http://$svc_upstream;
}
}复制代码
ingressgroup-upstream.conf面试
upstream zxl-test-splitflow-old-version {
server 10.168.173.29:8080 max_fails=0 fail_timeout=0;
}
upstream zxl-test-splitflow-new-version {
server 10.168.177.171:8080 max_fails=0 fail_timeout=0;
}复制代码
当nginx -tc /etc/nginx/nginx.conf测试配置正确与否时报错以下:正则表达式
Error: exit status 1
nginx: [emerg] "map_hash_bucket_size" directive is duplicate in /etc/nginx/nginx.conf:60
nginx: configuration file c test failed复制代码
这是由于首次调用map时会隐式设置maphashbucketsize,即在nginx中map后写maphashbucketsize至关于设置了两次maphashbucket_size,如:spring
http {
...
map $status $_status {
default 42;
}
map_hash_bucket_size 64;
...
}复制代码
所以能够在map以前设置它,以下所示。编程
http {
map_hash_bucket_size 64;
...
map $status $_status {
default 42;
}
...
}复制代码
因此include map配置也应该放到设置maphashbucket_size以后:
http {
...
map_hash_bucket_size 64;
...
include /etc/nginx/conf.d/server-map.d/*-map.conf;
include /etc/nginx/conf.d/*-upstream.conf;
include /etc/nginx/conf.d/server-map.d/*-server.conf;
}复制代码
经过上面的include三个配置文件,最终对nginx生效的配置应该是这样的:
http {
...
map_hash_bucket_size 64;
...
map $http_x_group_env $svc_upstream {
default zxl-test-splitflow-old-version;
~*old zxl-test-splitflow-old-version;
~*new zxl-test-splitflow-new-version;
}
upstream zxl-test-splitflow-old-version {
server 10.168.173.29:8080 max_fails=0 fail_timeout=0;
}
upstream zxl-test-splitflow-new-version {
server 10.168.177.171:8080 max_fails=0 fail_timeout=0;
}
server {
listen 8998;
server_name aa.hc.harmonycloud.cn;
location /testdemo/test {
proxy_pass http://$svc_upstream;
}
}
}复制代码
当在电脑上hosts文件里配置了aa.hc.harmonycloud.cn域名解析后,访问http://aa.hc.harmonycloud.cn:8998/testdemo/test时(即server的servername和listen、location的配置),nginx将会把请求转发到http://$svcupstream,这个$svc_upstream具体是什么,就是经过map配置来赋值的。这里map配置以下:
map $http_x_group_env $svc_upstream {
default zxl-test-splitflow-old-version;
~*old zxl-test-splitflow-old-version;
~*new zxl-test-splitflow-new-version;
}复制代码
其中$httpxgroupenv能够是nginx内置变量,也能够是自定义的header的key、请求参数名;$svcupstream即为自定义变量名。这里的配置含义为:当请求头里的x-group-env的值old时,$svcupstream被赋值为zxl-test-splitflow-old-version;当请求头里的x-group-env的值new时,$svcupstream被赋值为zxl-test-splitflow-new-version;默认赋值为zxl-test-splitflow-old-version;(其中正则表达式若是以 “~” 开头,表示这个正则表达式对大小写敏感。以 “~*”开头,表示这个正则表达式对大小写不敏感)。而zxl-test-splitflow-new-version和zxl-test-splitflow-old-version表示两个upstream名称。
所以nginx将会把请求转发到http://$svcupstream,这里的$svcupstream会被替换为upstream的名称,最终将获得upstream中的后端服务IP和Port。
注意:若是咱们自定义header为X-Real-IP,经过第二个nginx获取该header时须要这样:$httpxrealip; (一概采用小写,并且前面多了个http,且中间用_替换)
当请求头里加x-group-env为new时,访问后端打印出的是I am new version
当请求头里加x-group-env为old时,访问后端打印出的是I am old version
最终经过请求头不一样实现了将流量分配到不一样的后端服务。
将请求头的key变为X-Group-Env,value变为OLD或者NEW也不要紧:
本公众号免费提供csdn下载服务,海量IT学习资源,若是你准备入IT坑,励志成为优秀的程序猿,那么这些资源很适合你,包括但不限于java、go、python、springcloud、elk、嵌入式 、大数据、面试资料、前端 等资源。同时咱们组建了一个技术交流群,里面有不少大佬,会不定时分享技术文章,若是你想来一块儿学习提升,能够公众号后台回复【2】,免费邀请加技术交流群互相学习提升,会不按期分享编程IT相关资源。
扫码关注,精彩内容第一时间推给你