整体流程
APIServer接管到删除Pod的申请后:
- 首先,批改etcd中的状态;
而后,把删除pod的事件,告诉给kubelet和endpoint-controller;
- kubelet: 负责pod资源的删除;
- endpoint-controller: 负责endpoint资源的删除;
- 两个组件并行执行;
Kubelet解决pod敞开
kubelet敞开pod的时候,会敞开pod中的每一个容器;kubelet给容器肯定的工夫(TerminationGracePeriod)优雅的进行。
kubelet终止容器的过程:
- 执行preStop,期待它执行结束;
- 向容器的过程发送SIGTERM;
- 期待容器优雅的敞开或超时(terminationGracePeriod);
- 若敞开超时,则发送SIGKILL强制敞开;
endpoint-controller解决pod敞开
endpoint-controller接管到pod删除的告诉时,向APIServer发送申请,批改svc的endpoints对象,从pod所在svc中删除该pod的endpoint。
而后,APIServer告诉节点上的kube-proxy组件,kube-proxy会批改本机的iptables/ipvs规定,将该endpoint移除。
Kubelet和endpoint-controller并行执行的问题
kube-proxy可能因为过载解决申请变慢,会呈现:
kubelet曾经把容器删除,但kube-proxy还未更新iptables。
这种状况下,流量还会被散发到对应的endpoint,然而pod已删除,客户端返回"连贯回绝"之类的谬误。
目前的解决办法,在pod的preStop中sleep一段时间,期待kube-proxy更新iptables结束:
lifecycle: preStop: exec: command: [ "sh", "-c", "sleep 10" ]
参考
- kubernetes in action