1 背景
最近升级了一版 kubelet,修复因 kubelet 删除 Pod 慢导致平台删除集群超时的问题。在灰度 redis 隔离集群的时候,发现升级 kubelet 并重启服务后,少量宿主状态变成了 NotReady,并且回滚 kubelet 至之前版本,宿主状态仍然是 NotReady。查看宿主状态时提示 ‘container runtime is down’ ,根据经验,此时一般就是容器运行时出了问题。弹性云使用的容器运行时是 docker,我们就去检查 docker 的状态,检测结果如下:
docker ps
查看所有容器状态,执行正常docker inspect
查看某一容器详细状态,执行阻塞
典型的 docker hang
死行为。因为我们最近在升级 docker 版本,存量宿主 docker 的版本为 1.13.1,并且在逐步升级至 18.06.3,新宿主的 docker 版本都是 18.06.3。docker hang
死问题在 1.13.1 版本上表现得更彻底,在执行 docker ps
的时候就已经 hang 死了,一旦某个容器出了问题,docker 就处于无响应状态;而 docker 18.06.3 做了一点小小的优化,在执行 docker ps 时去掉了针对容器级别的加锁操作,但是 docker inspect
依然会加容器锁,因此某一个容器出现问题,并不会造成 docker 服务不可响应,受影响的也仅仅是该容器,无法执行任何操作。
至于为什么以 docker ps
与 docker inspect
为指标检查 docker 状态,因为 kubelet 就是依赖这两个 docker API 获取容器状态。
所以,现在问题有二:
docker hang
死的根因是什么?docker hang
死时,为什么重启 kubelet,会导致宿主状态变为 NotReady?