kubelet啟動流程


kubelet 主要功能: 

  • pod 管理:kubelet 定期從所監聽的數據源獲取節點上 pod/container 的期望狀態(運行什么容器、運行的副本數量、網絡或者存儲如何配置等等),並調用對應的容器平台接口達到這個狀態。

  • 容器健康檢查:kubelet 創建了容器之后還要查看容器是否正常運行,如果容器運行出錯,就要根據 pod 設置的重啟策略進行處理。

  • 容器監控:kubelet 會監控所在節點的資源使用情況,並定時向 master 報告,資源使用數據都是通過 cAdvisor 獲取的。知道整個集群所有節點的資源情況,對於 pod 的調度和正常運行至關重要

kubelet 組件中的模塊

 

 

 

  • 1、PLEG(Pod Lifecycle Event Generator) PLEG 是 kubelet 的核心模塊,PLEG 會一直調用 container runtime 獲取本節點 containers/sandboxes 的信息,並與自身維護的 pods cache 信息進行對比,生成對應的 PodLifecycleEvent,然后輸出到 eventChannel 中,通過 eventChannel 發送到 kubelet syncLoop 進行消費,然后由 kubelet syncPod 來觸發 pod 同步處理過程,最終達到用戶的期望狀態。

  • 2、cAdvisor cAdvisor(https://github.com/google/cadvisor)是 google 開發的容器監控工具,集成在 kubelet 中,起到收集本節點和容器的監控信息,大部分公司對容器的監控數據都是從 cAdvisor 中獲取的 ,cAvisor 模塊對外提供了 interface 接口,該接口也被 imageManager,OOMWatcher,containerManager 等所使用。

  • 3、OOMWatcher 系統 OOM 的監聽器,會與 cadvisor 模塊之間建立 SystemOOM,通過 Watch方式從 cadvisor 那里收到的 OOM 信號,並產生相關事件。

  • 4、probeManager probeManager 依賴於 statusManager,livenessManager,containerRefManager,會定時去監控 pod 中容器的健康狀況,當前支持兩種類型的探針:livenessProbe 和readinessProbe。 livenessProbe:用於判斷容器是否存活,如果探測失敗,kubelet 會 kill 掉該容器,並根據容器的重啟策略做相應的處理。 readinessProbe:用於判斷容器是否啟動完成,將探測成功的容器加入到該 pod 所在 service 的 endpoints 中,反之則移除。readinessProbe 和 livenessProbe 有三種實現方式:http、tcp 以及 cmd。

  • 5、statusManager statusManager 負責維護狀態信息,並把 pod 狀態更新到 apiserver,但是它並不負責監控 pod 狀態的變化,而是提供對應的接口供其他組件調用,比如 probeManager。

  • 6、containerRefManager 容器引用的管理,相對簡單的Manager,用來報告容器的創建,失敗等事件,通過定義 map 來實現了 containerID 與 v1.ObjectReferece 容器引用的映射。

  • 7、evictionManager 當節點的內存、磁盤或 inode 等資源不足時,達到了配置的 evict 策略, node 會變為 pressure 狀態,此時 kubelet 會按照 qosClass 順序來驅趕 pod,以此來保證節點的穩定性。可以通過配置 kubelet 啟動參數 --eviction-hard= 來決定 evict 的策略值。

  • 8、imageGC imageGC 負責 node 節點的鏡像回收,當本地的存放鏡像的本地磁盤空間達到某閾值的時候,會觸發鏡像的回收,刪除掉不被 pod 所使用的鏡像,回收鏡像的閾值可以通過 kubelet 的啟動參數 --image-gc-high-threshold 和 --image-gc-low-threshold 來設置。

  • 9、containerGC containerGC 負責清理 node 節點上已消亡的 container,具體的 GC 操作由runtime 來實現。

  • 10、imageManager 調用 kubecontainer 提供的PullImage/GetImageRef/ListImages/RemoveImage/ImageStates 方法來保證pod 運行所需要的鏡像。

  • 11、volumeManager 負責 node 節點上 pod 所使用 volume 的管理,volume 與 pod 的生命周期關聯,負責 pod 創建刪除過程中 volume 的 mount/umount/attach/detach 流程,kubernetes 采用 volume Plugins 的方式,實現存儲卷的掛載等操作,內置幾十種存儲插件。

  • 12、containerManager 負責 node 節點上運行的容器的 cgroup 配置信息,kubelet 啟動參數如果指定 --cgroups-per-qos 的時候,kubelet 會啟動 goroutine 來周期性的更新 pod 的 cgroup 信息,維護其正確性,該參數默認為 true,實現了 pod 的Guaranteed/BestEffort/Burstable 三種級別的 Qos。

  • 13、runtimeManager containerRuntime 負責 kubelet 與不同的 runtime 實現進行對接,實現對於底層 container 的操作,初始化之后得到的 runtime 實例將會被之前描述的組件所使用。可以通過 kubelet 的啟動參數 --container-runtime 來定義是使用docker 還是 rkt,默認是 docker

  • 14、podManager podManager 提供了接口來存儲和訪問 pod 的信息,維持 static pod 和 mirror pods 的關系,podManager 會被statusManager/volumeManager/runtimeManager 所調用,podManager 的接口處理流程里面會調用 secretManager 以及 configMapManager

 

kubelet啟動流程

  首先從 kubelet 的 main 函數開始,其中調用的 NewKubeletCommand 方法主要負責獲取配置文件中的參數,校驗參數以及為參數設置默認值。主要邏輯為:

  • 1、解析命令行參數;
  • 2、為 kubelet 初始化 feature gates 參數;
  • 3、加載 kubelet 配置文件;
  • 4、校驗配置文件中的參數;
  • 5、檢查 kubelet 是否啟用動態配置功能;
  • 6、初始化 kubeletDeps,kubeletDeps 包含 kubelet 運行所必須的配置,是為了實現 dependency injection,其目的是為了把 kubelet 依賴的組件對象作為參數傳進來,這樣可以控制 kubelet 的行為;
  • 7、調用 Run 方法; 

  Run

  該方法中僅僅調用 run 方法執行后面的啟動邏輯。

  run 方法中主要是為 kubelet 的啟動做一些基本的配置及檢查工作,主要邏輯為:

  • 1、為 kubelet 設置默認的 FeatureGates,kubelet 所有的 FeatureGates 可以通過命令參數查看,k8s 中處於 Alpha 狀態的 FeatureGates 在組件啟動時默認關閉,處於 Beta 和 GA 狀態的默認開啟;
  • 2、校驗 kubelet 的參數;
  • 3、嘗試獲取 kubelet 的 lock file,需要在 kubelet 啟動時指定 --exit-on-lock-contention 和 --lock-file,該功能處於 Alpha 版本默認為關閉狀態;
  • 4、將當前的配置文件注冊到 http server /configz URL 中;
  • 5、檢查 kubelet 啟動模式是否為 standalone 模式,此模式下不會和 apiserver 交互,主要用於 kubelet 的調試;
  • 6、初始化 kubeDeps,kubeDeps 中包含 kubelet 的一些依賴,主要有 KubeClientEventClientHeartbeatClientAuthcadvisorContainerManager
  • 7、檢查是否以 root 用戶啟動;
  • 8、為進程設置 oom 分數,默認為 -999,分數范圍為 [-1000, 1000],越小越不容易被 kill 掉;
  • 9、調用 RunKubelet 方法;
  • 10、檢查 kubelet 是否啟動了動態配置功能;
  • 11、啟動 Healthz http server;
  • 12、如果使用 systemd 啟動,通知 systemd kubelet 已經啟動;

RunKubelet

  RunKubelet 中主要調用了 createAndInitKubelet 方法執行 kubelet 組件的初始化,然后調用 startKubelet 啟動 kubelet 中的組件。

createAndInitKubelet

  createAndInitKubelet 中主要調用了三個方法來完成 kubelet 的初始化:

  • kubelet.NewMainKubelet:實例化 kubelet 對象,並對 kubelet 依賴的所有模塊進行初始化;
  • k.BirthCry:向 apiserver 發送一條 kubelet 啟動了的 event;
  • k.StartGarbageCollection:啟動垃圾回收服務,回收 container 和 images;
kubelet.NewMainKubelet

  NewMainKubelet 是初始化 kubelet 的一個方法,主要邏輯為:

  • 1、初始化 PodConfig 即監聽 pod 元數據的來源(file,http,apiserver),將不同 source 的 pod configuration 合並到一個結構中;
  • 2、初始化 containerGCPolicy、imageGCPolicy、evictionConfig 配置;
  • 3、啟動 serviceInformer 和 nodeInformer;
  • 4、初始化 containerRefManageroomWatcher
  • 5、初始化 kubelet 對象;
  • 6、初始化 secretManagerconfigMapManager
  • 7、初始化 livenessManagerpodManagerstatusManagerresourceAnalyzer
  • 8、調用 kuberuntime.NewKubeGenericRuntimeManager 初始化 containerRuntime
  • 9、初始化 pleg
  • 10、初始化 containerGCcontainerDeletorimageManagercontainerLogManager
  • 11、初始化 serverCertificateManagerprobeManagertokenManagervolumePluginMgrpluginManagervolumeManager
  • 12、初始化 workQueuepodWorkersevictionManager
  • 13、最后注冊相關模塊的 handler;

  NewMainKubelet 中對 kubelet 依賴的所有模塊進行了初始化,每個模塊對應的功能在上篇文章“kubelet 架構淺析”有介紹

  在startKubelet 中通過調用 k.Run 來啟動 kubelet 中的所有模塊以及主流程,然后啟動 kubelet 所需要的 http server,在 v1.16 中,kubelet 默認僅啟動健康檢查端口 10248 和 kubelet server 的端口 10250

此處總結一下 kubelet 啟動邏輯中的調用關系如下所示:

                                                                                  |--> NewMainKubelet
                                                                                  |
                                                      |--> createAndInitKubelet --|--> BirthCry
                                                      |                           |
                                    |--> RunKubelet --|                           |--> StartGarbageCollection
                                    |                 |
                                    |                  |--> startKubelet --> k.Run
                                    |
NewKubeletCommand --> Run --> run --|--> http.ListenAndServe
                                    |
                                    |--> daemon.SdNotify

Run

Run 方法是啟動 kubelet 的核心方法,其中會啟動 kubelet 的依賴模塊以及主循環邏輯,該方法的主要邏輯為:

  • 1、注冊 logServer;
  • 2、判斷是否需要啟動 cloud provider sync manager;
  • 3、調用 kl.initializeModules 首先啟動不依賴 container runtime 的一些模塊;
  • 4、啟動 volume manager
  • 5、執行 kl.syncNodeStatus 定時同步 Node 狀態;
  • 6、調用 kl.fastStatusUpdateOnce 更新容器運行時啟動時間以及執行首次狀態同步;
  • 7、判斷是否啟用 NodeLease 機制;
  • 8、執行 kl.updateRuntimeUp 定時更新 Runtime 狀態;
  • 9、執行 kl.syncNetworkUtil 定時同步 iptables 規則;
  • 10、執行 kl.podKiller 定時清理異常 pod,當 pod 沒有被 podworker 正確處理的時候,啟動一個goroutine 負責 kill 掉 pod;
  • 11、啟動 statusManager
  • 12、啟動 probeManager
  • 13、啟動 runtimeClassManager
  • 14、啟動 pleg
  • 15、調用 kl.syncLoop 監聽 pod 變化;

在 Run 方法中主要調用了兩個方法 kl.initializeModules 和 kl.fastStatusUpdateOnce 來完成啟動前的一些初始化,在初始化完所有的模塊后會啟動主循環

initializeModules

initializeModules 中啟動的模塊是不依賴於 container runtime 的,並且不依賴於尚未初始化的模塊,其主要邏輯為:

  • 1、調用 kl.setupDataDirs 創建 kubelet 所需要的文件目錄;
  • 2、創建 ContainerLogsDir /var/log/containers
  • 3、啟動 imageManager,image gc 的功能已經在 RunKubelet 中啟動了,此處主要是監控 image 的變化;
  • 4、啟動 certificateManager,負責證書更新;
  • 5、啟動 oomWatcher,監聽 oom 並記錄事件;
  • 6、啟動 resourceAnalyzer

fastStatusUpdateOnce

fastStatusUpdateOnce 會不斷嘗試更新 pod CIDR,一旦更新成功會立即執行updateRuntimeUpsyncNodeStatus來進行運行時的更新和節點狀態更新。此方法只在 kubelet 啟動時執行一次,目的是為了通過更新 pod CIDR,減少節點達到 ready 狀態的時延,盡可能快的進行 runtime update 和 node status update

updateRuntimeUp

updateRuntimeUp 方法在容器運行時首次啟動過程中初始化運行時依賴的模塊,並在 kubelet 的runtimeState中更新容器運行時的啟動時間。updateRuntimeUp 方法首先檢查 network 以及 runtime 是否處於 ready 狀態,如果 network 以及 runtime 都處於 ready 狀態,然后調用 initializeRuntimeDependentModules 初始化 runtime 的依賴模塊,包括 cadvisorcontainerManagerevictionManagercontainerLogManagerpluginManage

initializeRuntimeDependentModules

該方法的主要邏輯為:

  • 1、啟動 cadvisor
  • 2、獲取 CgroupStats;
  • 3、啟動 containerManagerevictionManagercontainerLogManager
  • 4、將 CSI Driver 和 Device Manager 注冊到 pluginManager,然后啟動 pluginManager

小結

在 Run 方法中可以看到,會直接調用 kl.syncNodeStatus和 kl.updateRuntimeUp,但在 kl.fastStatusUpdateOnce 中也調用了這兩個方法,而在 kl.fastStatusUpdateOnce 中僅執行一次,在 Run 方法中會定期執行。在kl.fastStatusUpdateOnce 中調用的目的就是當 kubelet 首次啟動時盡可能快的進行 runtime update 和 node status update,減少節點達到 ready 狀態的時延。而在 kl.updateRuntimeUp 中調用的初始化 runtime 依賴模塊的方法 kl.initializeRuntimeDependentModules 通過 sync.Once 調用僅僅會被執行一次。

syncLoop

syncLoop 是 kubelet 的主循環方法,它從不同的管道(file,http,apiserver)監聽 pod 的變化,並把它們匯聚起來。當有新的變化發生時,它會調用對應的函數,保證 pod 處於期望的狀態。

syncLoop 中首先定義了一個 syncTicker 和 housekeepingTicker,即使沒有需要更新的 pod 配置,kubelet 也會定時去做同步和清理 pod 的工作。然后在 for 循環中一直調用 syncLoopIteration,如果在每次循環過程中出現錯誤時,kubelet 會記錄到 runtimeState 中,遇到錯誤就等待 5 秒中繼續循環

syncLoopIteration

syncLoopIteration 方法會監聽多個 channel,當發現任何一個 channel 有數據就交給 handler 去處理,在 handler 中通過調用 dispatchWork 分發任務。它會從以下幾個 channel 中獲取消息:

  • 1、configCh:該信息源由 kubeDeps 對象中的 PodConfig 子模塊提供,該模塊將同時 watch 3 個不同來源的 pod 信息的變化(file,http,apiserver),一旦某個來源的 pod 信息發生了更新(創建/更新/刪除),這個 channel 中就會出現被更新的 pod 信息和更新的具體操作;
  • 2、syncCh:定時器,每隔一秒去同步最新保存的 pod 狀態;
  • 3、houseKeepingCh:housekeeping 事件的通道,做 pod 清理工作;
  • 4、plegCh:該信息源由 kubelet 對象中的 pleg 子模塊提供,該模塊主要用於周期性地向 container runtime 查詢當前所有容器的狀態,如果狀態發生變化,則這個 channel 產生事件;
  • 5、liveness Manager:健康檢查模塊發現某個 pod 異常時,kubelet 將根據 pod 的 restartPolicy 自動執行正確的操作;

 

 

 

 

 

 

 

 

  • 添加到短語集
     
    • 沒有此單詞集:南非科薩語 -> ...
       
    • 創建新的單詞集...
  • 拷貝
  • 添加到短語集
     
    • 沒有此單詞集:英語 -> ...
       
    • 創建新的單詞集...
  • 拷貝
  • 添加到短語集
     
    • 沒有此單詞集:南非科薩語 -> ...
       
    • 創建新的單詞集...
  • 拷貝
  • 添加到短語集
     
    • 沒有此單詞集:中文(簡體) -> ...
       
    • 創建新的單詞集...
  • 拷貝
  • 添加到短語集
     
    • 沒有此單詞集:南非科薩語 -> ...
       
    • 創建新的單詞集...
  • 拷貝
  • 添加到短語集
     
    • 沒有此單詞集:英語 -> ...
       
    • 創建新的單詞集...
  • 拷貝
  • 添加到短語集
     
    • 沒有此單詞集:英語 -> ...
       
    • 創建新的單詞集...
  • 拷貝
  • 添加到短語集
     
    • 沒有此單詞集:英語 -> ...
       
    • 創建新的單詞集...
  • 拷貝
  • 添加到短語集
     
    • 沒有此單詞集:英語 -> ...
       
    • 創建新的單詞集...
  • 拷貝


免責聲明!

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



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