kubelet 介紹
一、kubelet簡介
kubelet 的主要功能就是定時從某個地方獲取節點上 pod/container 的期望狀態(運行什么容器、運行的副本數量、網絡或者存儲如何配置等等),並調用對應的容器平台接口達到這個狀態。
之所以有pod的概覽,即給容器提供這一層封裝,主要是因為容器推薦的用法是里面只運行一個進程,而一般情況下某個應用都由多個組件構成的。
比較經典的一張圖:
Kubelet組件運行在Node節點上,維持運行中的Pods以及提供kubernetes運行時環境,主要完成以下使命:
1.監視分配給該Node節點的pods
2.掛載pod所需要的volumes
3.下載pod的secret
4.通過docker/rkt來運行pod中的容器
5.調用cni接口為pod創建ip、路由
6.周期的執行pod中為容器定義的liveness探針
7.上報pod的狀態給系統的其他組件
8.上報Node的狀態
二、kubelet功能模塊
在 v1.12 中,kubelet 組件有18個主要的 manager(kubernetes/pkg/kubelet/kubelet.go):
certificateManager
cgroupManager
containerManager
cpuManager
nodeContainerManager
configmapManager
containerReferenceManager
evictionManager
nvidiaGpuManager
imageGCManager
kuberuntimeManager
hostportManager
podManager
proberManager
secretManager
statusManager
volumeManager
tokenManager
比較好的一張圖:
整個kubelet可以按照上圖所示的模塊進行划分,模塊之間相互配合完成Kubelet的所有功能.下面對上圖中的模塊進行簡要的介紹.
Kubelet對外暴露的端口,通過該端口可以獲取到kubelet的狀態
10250 kubelet API –kublet暴露出來的端口,通過該端口可以訪問獲取node資源以及狀態,另外可以配合kubelet的啟動參數contention-profiling enable-debugging-handlers來提供了用於調試和profiling的api。
4194 cAdvisor –kublet通過該端口可以獲取到本node節點的環境信息以及node上運行的容器的狀態等內容
10255 readonly API –kubelet暴露出來的只讀端口,訪問該端口不需要認證和鑒權,該http server提供查詢資源以及狀態的能力.
10248 /healthz –kubelet健康檢查,通過訪問該url可以判斷Kubelet是否正常work, 通過kubelet的啟動參數–healthz-port –healthz-bind-address來指定監聽的地址和端口.
核心功能模塊
PLEG
PLEG全稱為PodLifecycleEvent,PLEG會一直調用container runtime獲取本節點的pods,之后比較本模塊中之前緩存的pods信息,比較最新的pods中的容器的狀態是否發生改變,當狀態發生切換的時候,生成一個eventRecord事件,輸出到eventChannel中。syncPod模塊會接收到eventChannel中的event事件,來觸發pod同步處理過程,調用contaiener runtime來重建pod,保證pod工作正常.
cAdvisor
cAdvisor集成在kubelet中,起到收集本Node的節點和啟動的容器的監控的信息,啟動一個Http Server服務器,對外接收rest api請求.cAvisor模塊對外提供了interface接口,可以通過interface接口獲取到node節點信息,本地文件系統的狀態等信息,該接口被imageManager,OOMWatcher,containerManager等所使用
GPUManager
對於Node上可使用的GPU的管理,當前版本需要在kubelet啟動參數中指定feature-gates中添加Accelerators=true,並且需要才用runtime=Docker的情況下才能支持使用GPU,並且當前只支持NvidiaGPU,GPUManager主要需要實現interface定義的Start()/Capacity()/AllocateGPU()三個函數
OOMWatcher
系統OOM的監聽器,將會與cadvisor模塊之間建立SystemOOM,通過Watch方式從cadvisor那里收到的OOM信號,並發生相關事件
ProbeManager
探針管理,依賴於statusManager,livenessManager,containerRefManager,實現Pod的健康檢查的功能.當前支持兩種類型的探針:LivenessProbe和ReadinessProbe,
LivenessProbe:用於判斷容器是否存活,如果探測到容器不健康,則kubelet將殺掉該容器,並根據容器的重啟策略做相應的處理
ReadinessProbe: 用於判斷容器是否啟動完成
探針有三種實現方式
execprobe:在容器內部執行一個命令,如果命令返回碼為0,則表明容器健康
tcprobe:通過容器的IP地址和端口號執行TCP檢查,如果能夠建立TCP連接,則表明容器健康
httprobe:通過容器的IP地址,端口號以及路徑調用http Get方法,如果響應status>=200 && status<=400的時候,則認為容器狀態健康
StatusManager
該模塊負責pod里面的容器的狀態,接受從其它模塊發送過來的pod狀態改變的事件,進行處理,並更新到kube-apiserver中.
Container/RefManager
容器引用的管理,相對簡單的Manager,通過定義map來實現了containerID與v1.ObjectReferece容器引用的映射.
EvictionManager
evictManager當node的節點資源不足的時候,達到了配置的evict的策略,將會從node上驅趕pod,來保證node節點的穩定性.可以通過kubelet啟動參數來決定evict的策略.另外當node的內存以及disk資源達到evict的策略的時候會生成對應的node狀態記錄.
ImageGC
imageGC負責Node節點的鏡像回收,當本地的存放鏡像的本地磁盤空間達到某閾值的時候,會觸發鏡像的回收,刪除掉不被pod所使用的鏡像.回收鏡像的閾值可以通過kubelet的啟動參數來設置.
ContainerGC
containerGC負責NOde節點上的dead狀態的container,自動清理掉node上殘留的容器.具體的GC操作由runtime來實現.
ImageManager
調用kubecontainer.ImageService提供的PullImage/GetImageRef/ListImages/RemoveImage/ImageStates的方法來保證pod運行所需要的鏡像,主要是為了kubelet支持cni.
VolumeManager
負責node節點上pod所使用的volume的管理.主要涉及如下功能
Volume狀態的同步,模塊中會啟動gorountine去獲取當前node上volume的狀態信息以及期望的volume的狀態信息,會去周期性的sync volume的狀態,另外volume與pod的生命周期關聯,pod的創建刪除過程中volume的attach/detach流程.更重要的是kubernetes支持多種存儲的插件,kubelet如何調用這些存儲插件提供的interface.涉及的內容較多,更加詳細的信息可以看kubernetes中volume相關的代碼和文檔.
containerManager
負責node節點上運行的容器的cgroup配置信息,kubelet啟動參數如果指定–cgroupPerQos的時候,kubelet會啟動gorountie來周期性的更新pod的cgroup信息,維持其正確.實現了pod的Guaranteed/BestEffort/Burstable(BestEffort:POD中的所有容器都沒有指定CPU和內存的requests和limits,默認為0,Burstable:POD中只要有一個容器,這個容器requests和limits的設置同其他容器設置的不一致,requests < limits, Guaranteed:POD中所有容器都必須統一設置了limits,並且設置參數都一致,如果有一個容器要設置requests,那么所有容器都要設置,並設置參數同limits一致,requests = limits. )三種級別的Qos,通過配置kubelet可以有效的保證了當有大量pod在node上運行時,保證node節點的穩定性.
runtimeManager
containerRuntime負責kubelet與不同的runtime實現進行對接,實現對於底層container的操作,初始化之后得到的runtime實例將會被之前描述的組件所使用.
當前可以通過kubelet的啟動參數–container-runtime來定義是使用docker還是rkt.runtime需要實現的接口定義在src/k8s.io/kubernetes/pkg/kubelet/apis/cri/services.go文件里面
podManager
podManager提供了接口來存儲和訪問pod的信息,維持static pod和mirror pods的關系,提供的接口如下所示
跟其他Manager之間的關系,podManager會被statusManager/volumeManager/runtimeManager所調用,並且podManager的接口處理流程里面同樣會調用secretManager以及configMapManager.
三、Cgroups介紹
Cgroups是control groups的縮寫,是Linux內核提供的一種可以限制、記錄、隔離進程組(process groups)所使用的物理資源(如:cpu,memory,IO等等)的機制。跟容器相關的功能主要涉及以下
· 限制進程組可以使用的資源數量(Resource limiting)。比如:memory子系統可以為進程組設定一個memory使用上限,一旦進程組使用的內存達到限額再申請內存,就會出發OOM(out of memory)。
· 進程組的優先級控制(Prioritization)。比如:可以使用cpu子系統為某個進程組分配特定cpu share。
· 記錄進程組使用的資源數量(Accounting)。比如:可以使用cpuacct子系統記錄某個進程組使用的cpu時間。
· 進程組隔離(Isolation)。比如:使用ns子系統可以使不同的進程組使用不同的namespace,以達到隔離的目的,不同的進程組有各自的進程、網絡、文件系統掛載空間。
Limits/request
Request: 容器使用的最小資源需求,作為容器調度時資源分配的判斷依賴。只有當節點上可分配資源量>=容器資源請求數時才允許將容器調度到該節點。但Request參數不限制容器的最大可使用資源。
Limit: 容器能使用資源的資源的最大值,設置為0表示使用資源無上限。
當前可以設置的有memory/cpu, kubernetes版本增加了localStorage在1.8版本中的策略.
Pod Qos
Qos服務質量分成三個級別
BestEffort、Burstable、Guaranteed
Kuberntes管理的node資源中cpu為可壓縮資源,當node上運行的pod cpu負載較高的時候,出現資源搶占,會根據設置的limit值來分配時間片.Kubernetes管理的node資源memory/disk是不可壓縮資源,當出現資源搶占的時候,會killer方式來釋放pod所占用的內存以及disk資源.當非可壓縮資源出現不足的時候,kill掉pods的Qos優先級比較低的pods.通過OOM score來實現,Guaranteed pod,OOM_ADJ設置為-998, BestEffort 設置的OOM_ADJ為1000, Burstable級別的POD設置為2-999.
Evict策略
當系統資源不足的時候,kubelet會通過evict策略來驅逐本節點的pod來使得node節點的負載不是很高, 保證系統組件的穩定性.
當前支持的驅逐信號Eviction Signal為
memory.available
nodefs.available
nodefs.inodesFree
imagefs.available
imagefs.inodesFree
四、節點資源介紹
Node Capacity - 已經作為NodeStatus.Capacity提供,這是從節點實例讀取的總容量,並假定為常量。
System-Reserved- 為未由Kubernetes管理的流程預留計算資源。目前,這涵蓋了/系統原始容器中集中的所有進程。
Kubelet Allocatable - 計算可用於調度的資源(包括計划和非計划資源)。這個價值是這個提案的重點。
Kube-Reserved - 為諸如docker守護進程,kubelet,kube代理等的Kubernetes組件預留的計算資源。
可分配的資源數據將由Kubelet計算並報告給API服務器。它被定義為:
[Allocatable] = [Node Capacity] - [Kube-Reserved] – [System-Reserved] – [Hard-Eviction-Threshold]
其中Kube-Reserved、System-Reserved和Hard-Eviction-Threshold可以看kubelet的配置信息。
調度pod時,調度程序將使用Allocatable代替Capacity,Kubelet將在執行准入檢查Admission checks時使用它。
五、靜態static pod
靜態POD直接由某個節點上的kubelet程序進行管理,不需要api server介入,靜態POD也不需要關聯任何RC,完全是由kubelet程序來監控,當kubelet發現靜態POD停止掉的時候,重新啟動靜態POD。
EvictManager模塊在系統資源緊張的時候, 根據pod的Qos以及pod使用的資源會選擇本節點的pod killer,來釋放資源, 但是靜態pod被killer之后,並不會發生重啟的現象, 設置pod的yaml中定義加入如下內容,
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ''
並且kubelet的啟動參數打開feature gateway(–feature-gates=ExperimentalCriticalPodAnnotation=true).
參考:
全部參數:http://blog.sina.com.cn/s/blog_3f12afd00102z5f9.html
https://www.cnblogs.com/heboxiang/p/12180291.html