k8s-"节点控制器驱逐Pod"
1 查看node信息
# kubectl describe node <node-name>
注: Conditions-Ready-Status, 如果节点是健康的且已经就绪可以接受新的Pod。则节点Ready字段为 True。False表明了该节点不
健康,不能够接受新的Pod, Unknown表示节点不可达。
2 节点控制器驱逐Pod
(1) 节点控制器监控节点的健康状况。当节点变得不可触达时(例如,由于节点已停机,节点控制器不再收到来
自节点的心跳信号),节点控制器将节点API对象的 NodeStatus Condition 取值从 NodeReady 更新为 Unknown
;然后在等待 pod-eviction-timeout 时间后,将节点上的所有 Pod 从节点驱逐。
默认40秒未收到心跳,修改 NodeStatus Condition 为 Unknown;
默认 pod-eviction-timeout 为 5分钟
节点控制器每隔 --node-monitor-period 5秒检查一次节点的状态
(2) 大多数情况下,节点控制器限制了驱逐 Pod 的速率为 --node-eviction-rate (默认值是0.1)每秒,即节点控
制器每 10 秒驱逐 1 个 Pod。
(3) 如果 Ready 类型Condition 的 status 持续为 Unkown 或者 False 超过 pod-eviction-timeout(kube-controller
-manager的参数)所指定的时间,节点控制器(node controller)将对该节点上的所有 Pod 执行删除的调度动作。默认的 pod-eviction-timeout 时间是 5 分钟。某些情况下(例如,节点网络故障),apiserver 不能够与节点上的 kubelet 通信,删除 Pod 的指令不能下达到该节点的 kubelet 上,直到 apiserver 与节点的通信重新建立,指令才下达到节点。这意味着,虽然对 Pod 执行了删除的调度指令,但是这些 Pod 可能仍然在失联的节点上运行。
在 kubernetes v1.5 以前,节点控制器将从 apiserver 强制删除这些失联节点上的 Pod。在 v1.5 及以后的版本中,节点控制器将不会强制删除这些 Pod,直到已经确认他们已经停止运行为止。您可能会发现失联节点上的 Pod 仍然在运行(在该节点上执行 docker ps 命令可查看容器的运行状态),然而 apiserver 中,他们的状态已经变为 Terminating 或者 Unknown。如果 Kubernetes 不能通过node-manager 判断失联节点是否已经永久从集群中移除(例如,在虚拟机或物理机上自己部署 Kubernetes 的情况),集群管理员需要手工(通过 kubectl delete node your-node-name 命令)删除 apiserver 中的节点对象。此时,Kubernetes 将删除该节点上的所有Pod。
在Kubernetes v1.12 中,TaintNodesByCondition 特性进入 beta 阶段,此时 node lifecycle controller 将自动创建该 Condition 对应的 污点。相应地,调度器在选择合适的节点时,不再关注节点的 Condition,而是检查节点的污点和 Pod 的容忍。
(4) 最极端的情况是,集群中一个健康的节点都没有,此时节点控制器 master 节点的网络连接出现故障,并停
止所有的驱逐 Pod 的动作,直到某些连接得到恢复。
3 示例
(1) 查看pod,分布在k8s-node2节点上
(2) 停止k8s-node2主机
[root@k8s-node2 ~]# shutdown -h now
(4) 40s后节点状态变为unknown
[root@k8s-admin ~]# kubectl describe node k8s-node2
(5) 5m40s后,原k8s-node2节点上的pod被驱逐且状态变为Terminating,此时在k8s-node1节点上
启动了一个新的pod
(6) 启动k8s-node2节点,原k8s-node2节点上Terminating状态的pod被删除,只剩k8s-node1上的pod
# 查看k8s-node2节点状态
[root@k8s-admin ~]# kubectl describe node k8s-node2
# 查看当前pod分布节点