场景一:停止kubelet并恢复
操作和现象
操作 |
节点上运行Pod后把kubelet进程停掉。 |
现象 |
node状态变为NotReady,不同类型的Pod情况不同。 |
Deployment |
在默认容忍配置的300s之后,旧Pod一直处于Terminating状态,创建新Pod。因为没有节点可以调度,所以Pod处于Pending状态。 |
StatefulSet |
Pod一直处于Terminating状态。 |
DaemonSet |
Pod一直处于Running状态。 |
操作 |
10分钟后,启动kubelet进程。 |
现象 |
node状态变为Ready,不同类型的Pod情况不同。 |
Deployment |
旧Pod被删除,新Pod处于Running状态。 |
StatefulSet |
Pod被删除后重建。 |
DaemonSet |
Pod不会被删除,Pod里面的容器会重新创建。 |
为什么StatefulSet Pod在node异常时没有重建?
在node controller中,除了daemonset pods外,都会调用delete pod api删除pod。
kubelet异常导致Pod Object一直无法从etcd中删除。
statefulset只会针对isFailed Pod(但现在Pod是Unkown状态)才会去delete Pod。
pkg/controller/statefulset/stateful_set_control.go
// delete and recreate failed pods
if isFailed(replicas[I]) {
ssc.recorder.Eventf(set, v1.EventTypeWarning, "RecreatingFailedPod",
"StatefulSetPlus %s/%s is recreating failed Pod %s",
set.Namespace,
set.Name,
replicas[I].Name)
if err := ssc.podControl.DeleteStatefulPlusPod(set, replicas[I]); err != nil {
return &status, err
}
if getPodRevision(replicas[I]) == currentRevision.Name {
status.CurrentReplicas—
}
if getPodRevision(replicas[I]) == updateRevision.Name {
status.UpdatedReplicas—
}
status.Replicas—
replicas[I] = newVersionedStatefulSetPlusPod(
currentSet,
updateSet,
currentRevision.Name,
updateRevision.Name,
i)
}
场景二:节点产生磁盘压力
kubelet默认驱逐条件
磁盘压力是nodefs.available
操作 |
拷贝大文件后产生磁盘压力。 |
现象 |
不同类型的Pod情况不同。 |
Deployment |
旧Pod处于Evicted状态,新Pod处于Pending。 |
StatefulSet |
新Pod处于Pending状态。 |
DaemonSet |
新Pod处于Evicted状态。 |
节点因磁盘压力而被打上了不可调度污点,但是node状态还是Ready。
针对磁盘压力,kubelet会回收临时卷、删除没有使用的容器和镜像,驱逐Pod。
操作 |
删除大文件后释放磁盘压力,重启kubelet(快点上报状态)。 |
现象 |
Pod恢复Running。 |