最近在作一個需求開發:根據請求後的不一樣,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相關資源。
掃碼關注,精彩內容第一時間推給你