1. 问题
测试环境中某个节点NotReady了,查看节点信息,发现kubelet出错无法向API Server注册节点。
# kubectl get node
# kubectl describe node 10.0.0.166
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
MemoryPressure Unknown Mon, 25 May 2020 16:26:43 +0800 Mon, 25 May 2020 16:27:59 +0800 NodeStatusUnknown Kubelet stopped posting node status.
因为node节点使用systemd对kubelet进程进行管理,发现 kubelet 无法正常启动,表现如下:
# systemctl status kubelet
kubelet.service - Kubernetes Kubelet Server
Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)
Active: failed (Result: start-limit) since Mon 2020-05-25 16:28:33 CST; 24h ago
Docs: https://github.com/GoogleCloudPlatform/kubernetes
Main PID: 12866 (code=exited, status=255)
# 使用 journalctl _PID=<PID> 来输出systemd管理下的进程日志
# journalctl _PID=12866 | vim -
-- Logs begin at Mon 2020-05-25 16:27:55 CST. --
May 25 16:28:32 VM-46765c59-4e9d-4731-b658-2b0c1d5bc49e-002 kubelet[2866]: F0525 04:28:32.821839 2866 server.go:273] failed to run Kubelet: Running with swap on is not supported, please disable swap! or set --fail-swap-on flag to false. /proc/swaps contained: [Filename Type Size Used Priority /dev/dm-1 partition 2097148 0 -2]
May 25 16:28:32 VM-46765c59-4e9d-4731-b658-2b0c1d5bc49e-002 systemd[1]: kubelet.service: main process exited, code=exited, status=255/n/a
May 25 16:28:32 VM-46765c59-4e9d-4731-b658-2b0c1d5bc49e-002 systemd[1]: Unit kubelet.service entered failed state.
运行检查,发现Swap没有被关闭。
# cat /proc/swaps
Filename Type Size Used Priority
/dev/dm-1 partition 2097148 0 -2
# free -m
total used free shared buff/cache available
Mem: 64247 7431 53662 12 3153 56284
Swap: xx xx xx
2. 解决方法
// 关闭Swap,机器重启后不生效
# swapoff -a
// 永久关闭Swap,注释掉swap那一行
# vim /etc/fstab
#/dev/mapper/centos-swap swap swap defaults 0 0
// 查看Swap
# free -m
# cat /proc/swaps
在Kubernetes集群master和nodes上禁用Swap后,运行下面命令重启kubelet
# systemctl daemon-reload
# systemctl restart kubelet
再运行检查Pod运行正常。
# kubectl get node
# kubectl get pod --all-namespaces
3. kubelet的启动限制 —— swap
为什么 swap 打开对 kubelet 来说会是一个需要直接退出进程的错误呢?参考 Why disable swap on kubernetes和 Kubelet needs to allow configuration of container memory-swap #7294,得出基本知识总结:
-
一开始大家在讨论的是,如果容许 Pod 使用 Swap,应该怎么去衡量默认的 Swap 设置,以及调度器应该如何根据 Swap 来进行调度?
-
讨论了一段时间后,发现支持 Swap 很复杂。。。总之就是很复杂。一位大佬站出来说,真的有需要用到 Swap 的场景么?
-
然后大家就开始批判起 Swap 来了,Swap 带来各种性能上的不确定性啦,而且也找不到哪些场景一定要用 Swap 啦,经过大家高兴地一致决定,Swap 这个东西真的是有害而无利,而且要用起来还复杂,就是不用它好了(K8S 1.5版本)。
-
然后如果有人想用?一开始还是支持通过参数配置使用的,后来发现一个不推荐的用法,有人非得用,代码上各种坑,还不如大家一起坚决不用好了。
-
然后到了1.8后就是默认不用了,除非你强制打开,官方强烈不推荐,踩坑自己负责。
看 Issue 主要是觉得这个过程实在是一个很典型的,功能要不要的讨论,说来说去,没有明确的用户场景,就不要把一个事情搞复杂的哲学很重要。
- kubelet启动参数–fail-swap-on含义
这个flag表示为:Makes the Kubelet fail to start if swap is enabled on the node。也就是说如果为true(默认值)就要求必须要关闭swap,false是表示即使宿主开启了swap,kubelet也是可以成功启动,但是pod是允许使用swap了,这部分代码因为经常出问题,所以直接swap在宿主上禁用会比较好。
4. 参考文章
https://www.jianshu.com/p/6f3268ce642f
https://blog.csdn.net/zstack_org/article/details/56274966
https://blog.csdn.net/nklinsirui/article/details/80855415