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