背景
最近遇到一個問題,線上老集羣下線時,node節點全部下線,只剩下ingress的節點,流量已全部切走,理論上應該沒什麼請求量,但ingress經常負載飆高導致容器掛掉。
分析過程
出問題的時候,可以看到nginx error.log 裏面有很多 connection refused 的請求
2020/05/13 03:39:02 [error] 587#587: *5038285 connect() failed (111: Connection refused) while connecting to upstream, client:192.168.231.2 server: _, request: "POST /RPC2 HTTP/1.1", upstream: "http://127.0.0.1:8181/RPC2", host: "1.1.1.1:80"
統計發現請求均來自192.168.231.2 這個IP,經確認,這個IP是我們安全團隊漏洞掃描機器IP,也就是說請求是安全團隊漏洞掃描機器發出來的
ingress 終端運行日誌裏面發現default-http-backend 找不到active endpoints 的日誌,如下所示
W0513 07:26:38.211186 7 controller.go:353] service kube-system/default-http-backend does not have any active endpoints
問題復現
正常情況下,如果nginx 後端upstream 不存在時,會立即返回502 並退出
root@web-02:~ # curl http://test.abc.com -x"127.0.0.1:80" -I HTTP/1.1 502 Bad Gateway
而ingress 中,由於default backend 的存在,如果訪問一個不存在server_name,請求就會丟給ingress default-backend 這個handler 處理
root@ubuntu:~ # curl http://testnotfound.abc.com/test.html -x "127.0.0.1:80" default backend - 404
default backend 不存在的情況下,curl 訪問ingress 會不斷重試陷入無限循環(直到我們自己執行ctrl+c 終端curl請求才會停止)
ingress error.log 裏面可以看到不斷有新的請求進來
這也是爲什麼nginx 單個cpu 被打爆而其他cpu 相對空閒的原因,相當於客戶端跟nginx建了個長連接(同一個客戶端,源端口不變),不斷髮起請求
爲default backend 容器加上污點容忍,讓default backend 容器飄到ingress controller機器,正常調度後機器CPU負載恢復正常
root@ubuntu:~# kubectl -n kube-system edit deployment default-http-backend ... tolerations: - effect: NoSchedule key: node-role.kubernetes.io/ingress operator: Equal value: "true" ... root@ubuntu:/home/wuguihong1# kubectl -n kube-system get pod|grep default default-http-backend-5b6975cbf8-xthpv 1/1 Running 0 15s [root@ubuntu:~]$ curl http://10.70.2.190:30000/test default backend - 404
思考
觸發需要2個條件,default backend 實例不存在 + 隨機訪問一個不存在的server_name (能進入default backend邏輯即可)
如果線上環境上default backend 容器掛掉,會不會同樣觸發該問題導致ingress機器單CPU 100% 問題?(待驗證)