问题太简单,就不分节了。
该问题源于IPVS模式下的两个内核参数,在K8s中,如果kube-proxy使用了IPVS模式,则Service的本质为IPVS规则。而IPVS的默认规则是当Real Server不可用时,暂时不断靠客户端到Virtual Server的连接,并将客户端在期间发送的所有包丢掉,这就造成了在K8s中,如果在IPVS模式下尝试对一个没有Endpoint的Service发起连接,这个连接就会被长时间挂起,客户端既得不到成功的回应,也不会得到失败的回应,只能自己在到达超时值时主动断开连接。
为了解决这个问题,请手动配置以下两个内核参数,这两个参数设置IPVS的Virtual Server在发现没有Real Server时主动断开并拒绝所有客户端发来的连接请求。
echo """
net.ipv4.vs.expire_nodest_conn = 1
net.ipv4.vs.expire_quiescent_template = 1
""" > /etc/sysctl.conf
sysctl -p
该问题已经在kubernetes 1.13.0中修复,修复版本后的k8s会主动设置该参数。详情请见kubernetes/kubernetes#71834