背景html
最近遇到一个问题,线上老集群下线时,node节点所有下线,只剩下ingress的节点,流量已所有切走,理论上应该没什么请求量,但ingress常常负载飙高致使容器挂掉。node
分析过程nginx
出问题的时候,能够看到nginx error.log 里面有不少 connection refused 的请求web
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,也就是说请求是安全团队漏洞扫描机器发出来的ubuntu
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 并退出bash
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 处理 curl
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请求才会中止)ide
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% 问题?(待验证)