k8s_kubelet啟動時必須關閉swap_轉


轉自:Kubernetes 設計分析: 為什么 kubelet 運行時不能打開 swap?

問題背景

在我自己的測試環境里,使用 kubeadm 來創建 k8s 集群,而我們知道 kubeadm 運行機制首先要求控制節點(簡稱 kmaster)上的 kubelet 需要先啟動。

測試環境使用 systemd 對進程進行管理。

測試環境重啟后,發現 kubelet 無法正常啟動,表現如下:

root@kmaster135:~# systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
   Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled)
  Drop-In: /etc/systemd/system/kubelet.service.d
           └─10-kubeadm.conf
   Active: activating (auto-restart) (Result: exit-code) since Sun 2019-04-07 22:06:29 PDT; 295ms ago
     Docs: https://kubernetes.io/docs/home/
  Process: 19593 ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_
 Main PID: 19593 (code=exited, status=255)

Apr 07 22:06:29 kmaster135 systemd[1]: kubelet.service: Main process exited, code=exited, status=255/n/a
Apr 07 22:06:29 kmaster135 systemd[1]: kubelet.service: Unit entered failed state.
Apr 07 22:06:29 kmaster135 systemd[1]: kubelet.service: Failed with result 'exit-code'.

過程記錄

kubelet 拉起實驗

可以看到啟動命令失敗,而失敗的具體原因,我們需要查看對應的進程日志,參考: 如何使用Journalctl查看並操作Systemd日志
,學習到可以使用journalctl _PID=<PID> 來查看對應進程的日志,在上面可以看到 kubelet 在最近一次重啟失敗的主進程 PID 是 19593。

root@kmaster135:~# journalctl _PID=19593 | vim -

-- Logs begin at Sun 2019-04-07 20:03:02 PDT, end at Sun 2019-04-07 22:08:53 PDT. --
Apr 07 22:06:29 kmaster135 kubelet[19593]: Flag --cgroup-driver has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.
Apr 07 22:06:29 kmaster135 kubelet[19593]: Flag --cgroup-driver has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.
Apr 07 22:06:29 kmaster135 kubelet[19593]: I0407 22:06:29.445241   19593 server.go:408] Version: v1.12.3
Apr 07 22:06:29 kmaster135 kubelet[19593]: I0407 22:06:29.445739   19593 plugins.go:99] No cloud provider specified.
Apr 07 22:06:29 kmaster135 kubelet[19593]: I0407 22:06:29.449904   19593 certificate_store.go:131] Loading cert/key pair from "/var/lib/kubelet/pki/kubelet-client-current.pem".
Apr 07 22:06:29 kmaster135 kubelet[19593]: I0407 22:06:29.502617   19593 server.go:667] --cgroups-per-qos enabled, but --cgroup-root was not specified.  defaulting to /
Apr 07 22:06:29 kmaster135 kubelet[19593]: F0407 22:06:29.503369   19593 server.go:262] 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/sda5                               partition        998396        0        -1]

重定向標准輸出到 vim 是為了避免屏幕顯示時被截斷,沒有自動換行,不是關鍵點。

根據 Fatal 級別的日志

Apr 07 22:06:29 kmaster135 kubelet[19593]: F0407 22:06:29.503369 19593 server.go:262] failed to run Kubelet: Running with swap on is not supported, please disable swap! or set --fail-swap-on flag to false.

可以看出來是因為開啟了 swap,而 kubelet 在 1.8 版本以后強制要求 swap 必須關閉。

我之前是通過 swapoff -a命令來關閉 swap 的,看來沒有被固化。

root@kmaster135:~# free
              total        used        free      shared  buff/cache   available
Mem:         997616       97500      519460       10784      380656      713456
Swap:        998396           0      998396

先來測試一下,關閉 swap 后能否正常,再來考慮固化的問題。

root@kmaster135:~# swapoff -a
root@kmaster135:~# free
              total        used        free      shared  buff/cache   available
Mem:         997616       97180      519904       10784      380532      713992
Swap:             0           0           0

看起來沒有直接退出了:

root@kmaster135:~# systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
   Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled)
  Drop-In: /etc/systemd/system/kubelet.service.d
           └─10-kubeadm.conf
   Active: active (running) since Sun 2019-04-07 22:14:10 PDT; 46s ago
     Docs: https://kubernetes.io/docs/home/
 Main PID: 20719 (kubelet)
    Tasks: 16
   Memory: 50.6M
      CPU: 3.764s
   CGroup: /system.slice/kubelet.service
           └─20719 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubecon

Apr 07 22:14:43 kmaster135 kubelet[20719]: W0407 22:14:43.334707   20719 cni.go:293] CNI failed to retrieve
Apr 07 22:14:43 kmaster135 kubelet[20719]: E0407 22:14:43.695545   20719 cni.go:310] Error adding network:
Apr 07 22:14:43 kmaster135 kubelet[20719]: E0407 22:14:43.696050   20719 cni.go:278] Error while adding to
Apr 07 22:14:43 kmaster135 kubelet[20719]: E0407 22:14:43.827405   20719 remote_runtime.go:96] RunPodSandbo
Apr 07 22:14:43 kmaster135 kubelet[20719]: E0407 22:14:43.827475   20719 kuberuntime_sandbox.go:65] CreateP
Apr 07 22:14:43 kmaster135 kubelet[20719]: E0407 22:14:43.827498   20719 kuberuntime_manager.go:657] create
Apr 07 22:14:43 kmaster135 kubelet[20719]: E0407 22:14:43.827576   20719 pod_workers.go:186] Error syncing
Apr 07 22:14:44 kmaster135 kubelet[20719]: W0407 22:14:44.342386   20719 docker_sandbox.go:375] failed to r
Apr 07 22:14:44 kmaster135 kubelet[20719]: W0407 22:14:44.351209   20719 pod_container_deletor.go:75] Conta
Apr 07 22:14:44 kmaster135 kubelet[20719]: W0407 22:14:44.354070   20719 cni.go:293] CNI failed to retrieve

雖然還是有一些報錯,按照上面的邏輯進一步排查可以發現是初始化階段的報錯,集群很快恢復了正常。

root@kmaster135:~# kubectl get cs
NAME                 STATUS    MESSAGE              ERROR
scheduler            Healthy   ok
controller-manager   Healthy   ok
etcd-0               Healthy   {"health": "true"}
root@kmaster135:~# kubectl get nodes
NAME         STATUS   ROLES    AGE   VERSION
dnode136     Ready    <none>   12d   v1.12.3
dnode137     Ready    <none>   12d   v1.12.3
kmaster135   Ready    master   12d   v1.12.3
root@kmaster135:~# kubectl get pods
NAME                          READY   STATUS             RESTARTS   AGE
hello-world-6897d55fb-2crbf   1/1     Running            1          12d
hello-world-6897d55fb-ssc28   1/1     Running            1          12d
hello-world-6897d55fb-txg5j   1/1     Running            1          12d

swapoff 固化

kubelet 問題看起來解決了,接下來要解決 swap 設置如何固化的問題,參考 How do I disable swap?, 配置 /etc/fstab

root@kmaster135:~# cat /etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# / was on /dev/sda1 during installation
UUID=aac6ee1b-f945-473b-8222-4be8c11e4822 /               ext4    errors=remount-ro 0       1
# swap was on /dev/sda5 during installation
UUID=d36ffe9b-676a-419a-b6fb-b95dc12d93ac none            swap    sw              0       0
...

注釋掉最下面的UUID=d36ffe9b-676a-419a-b6fb-b95dc12d93ac這一行就可以了。

swap & kubelet

進一步了解一下,為什么 swap 打開對 kubelet 來說會是一個需要直接退出進程的錯誤呢??

參考 Why disable swap on kubernetesKubelet needs to allow configuration of container memory-swap #7294, 得出基本的知識總結:

  1. 一開始大家在討論的是,如果容許 Pod 使用 Swap,應該怎么去衡量默認的 Swap 設置,以及調度器應該如何根據 Swap 來進行調度?
  2. 討論了一段時間后,發現支持 Swap 很復雜。。。總之就是很復雜。一位大佬站出來說,真的有需要用到 Swap 的場景么?
  3. 然后大家就開始批判起 Swap 來了,Swap 帶來各種性能上的不確定性啦,而且也找不到哪些場景一定要用 Swap 啦,經過大家高興地一致決定,Swap 這個東西真的是有害而無利,而且要用起來還復雜,就是不用它好了(K8S 1.5版本)。
  4. 然后如果有人想用?一開始還是支持通過參數配置使用的,后來發現一個不推薦的用法,有人非得用,代碼上各種坑,還不如大家一起堅決不用好了。
  5. 然后到了1.8后就是默認不用了,除非你強制打開,官方強烈不推薦,踩坑自己負責。

看 Issue 主要是覺得這個過程實在是一個很典型的,功能要不要的討論,說來說去,沒有明確的用戶場景,就不要把一個事情搞復雜的哲學很重要。

更新--fail-swap-on flag含義

這個flag表示為:Makes the Kubelet fail to start if swap is enabled on the node.

也就是說如果為true(默認值)就要求必須要關閉swap,false是表示即使宿主開啟了swap,kubelet也是可以成功啟動,但是pod是允許使用swap了,這部分代碼因為經常出問題,所以直接swap在宿主上禁用會比較好。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM