【转】Kubelet 重启导致宿主重启的经验总结

提要

线下集成测试时,尝试更新 Kubelet 的新版本。针对新增功能中支持 NBD,我们遇到 Kubelet 重启会导致宿主机重启的问题。最终问题定位至 rdb-nbd 进程异常退出导致死机。通过修改 KillMode 参数和 storageClass 配置,修复了问题。

问题描述

在新版本 Kubelet 中新增了支持 NBD 的相关功能,我们在线下测试集群中尝试更新 Kubelet 来研究其功能。

在 2018-02-23 15:46:56 时,我们通过发布系统灰度更新 kubelet 时,发现部署超时,最终导致部署失败,再次尝试部署,可以部署成功,登录已部署的宿主机查看,发现宿主机重启了,然后暂停余下部署。

紧接着,我们围绕 NDB 进行排查, 最后发现,只要挂载了 NBD 设备的宿主,只要重启 Kubelet 就会死机,然后经过手动测试该特性发现,如果杀死了 rbd-nbd map 的进程其实也会导致死机。

【转】Kubelet 重启导致宿主重启的经验总结_第1张图片

所以将问题定位至:

  1. 重启 Kubelet 为什么导致 rbd-nbd map 的进程也被退出了?
  2. Rbd-nbd map 的进程退出为什么导致死机?

Rbd-nbd 被动退出问题

Kubelet 服务是由 systemd 托管的,而 rbd-nbd map 进程是由 Kubelet 运行的,rbd-nbd map 进程则成为 Kubelet 的控制组内的进程了, 如下:

【转】Kubelet 重启导致宿主重启的经验总结_第2张图片

当停止 Kubelet 服务的时候,systemd 会首先给 Kubelet 发送杀死信号,然后会给其它进程也发杀死信号,导致问题 1 的发生,事后尝试完全把 rbd-nbd map 这个逻辑从 Kubelet 自身脱离出来,由外部服务来执行和托管,这应该也是 CSI 的思想,但是对于我们现在来说管理成本太高了, 那么还是从 systemd 入手查看,看能否做到杀死 Kubelet 时不给其它进程发杀死信号机制,果然有:

【转】Kubelet 重启导致宿主重启的经验总结_第3张图片

KillMode=XXX 可以设置执行 systemctl stop 时的姿势,比如: KillMode=process:If set to process, only the main process itself is killed,默认是 control-group。

其它姿势可以看 systemd.kill 手册:

死机问题

对于死机问题,第一时间是查日志,查日志有两个地方:

  1. /var/log/messages
  2. /var/crash

Messages 里没发现什么异常信息,直接查看 crash,发现有几次 crash,根据故障特点,查看重点信息:

【转】Kubelet 重启导致宿主重启的经验总结_第4张图片

从 Oops 信息查看貌似是触发了 ext4 文件系统的底层 BUG, 回想一下 kubelet 通过 storageclass 挂载 ceph 设备的流程,并没有指定 mount 到本地的文件系统类型,那么默认使用的就是 ext4, 所以,更新 storageclass 配置,增加 fsType 参数,并设置为 xfs,比如:

【转】Kubelet 重启导致宿主重启的经验总结_第5张图片

然后再重新测试整个创建容器,重启 Kubelet 服务流程,不存在 rbd-nbd 程序退出和宿主死机重启的问题了。

总结

对于上面的问题的解决方案, 目前看需要弹性云线上集群做如下修改:

  1. 优化 Kubelet 支持 NBD 的代码,使用最新的 patch;
  2. 修改 Kubelet 服务配置文件,增加 Killmode=process;
  3. 修改 storageClass 配置, 增加文件系统类型参数 fsType:xfs。

扩展思考

如果 rbd-nbd 被意外 Kill 掉,结果会怎么样呢?

经过测试发现,如果 rbd-nbd 被 Kill 掉,导致该容器的 ceph 盘读写错误 (IO Error),但是容器还正常运行,暂时没有恢复方案,所以需要加监控;针对 ceph 和 Kubernetes 的集成,需要更加详细的测试。

你可能感兴趣的:(【转】Kubelet 重启导致宿主重启的经验总结)