整体流程

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" ]

参考

  1. kubernetes in action