k8s 自身原理 2
前面我們說(shuō)到 K8S 的基本原理和涉及的四大組件,分享了前兩個(gè)組件 etcd 和 ApiServer
這一次我們接著分享一波:
調(diào)度器 ?scheduler
控制器管理器 controller manager
調(diào)度器 scheduler
調(diào)度器,見(jiàn)名知意,用于調(diào)度 k8s 資源的,那么這個(gè)調(diào)度器具體主要是調(diào)度啥資源呢?
實(shí)際上看我們 k8s 中運(yùn)行的一個(gè)一個(gè)的 pod,這些 pod 在我們創(chuàng)建的時(shí)候,還記得我們有分享過(guò)是可以指定即將要生成的 pod 默認(rèn)被調(diào)度了指定節(jié)點(diǎn)嗎?
一般情況下,我們也沒(méi)有去刻意指定 pod 要調(diào)度到哪個(gè)節(jié)點(diǎn),但是最終 pod 一定會(huì)被調(diào)度到集群中的某一個(gè)節(jié)點(diǎn)
實(shí)際上,這就是調(diào)度器在起作用了,沒(méi)錯(cuò),調(diào)度器就是調(diào)度 pod 資源到對(duì)應(yīng)的節(jié)點(diǎn)上
咱們的調(diào)度器也是利用了 API 服務(wù)器的監(jiān)聽(tīng)機(jī)制來(lái)新創(chuàng)建 pod 資源的,創(chuàng)建好的 pod 資源,會(huì)將其調(diào)度到資源充足,甚至沒(méi)有 pod 的節(jié)點(diǎn)上
那么你是否會(huì)認(rèn)為是調(diào)度器直接控制節(jié)點(diǎn)來(lái)運(yùn)行指定的 pod?

nonono,并不是這樣的,前面我們有說(shuō)到過(guò)基本上很多的組件都是通過(guò) ApiServer 來(lái)進(jìn)行處理的
調(diào)度器在這里也不例外,
這里的是調(diào)度器是通過(guò) ApiServer 來(lái)更新 pod 的定義,然后 ApiServer 再去通知 Kubelet 這個(gè) pod 已經(jīng)被調(diào)度器調(diào)度過(guò)了,這個(gè)時(shí)候,實(shí)際對(duì)應(yīng)節(jié)點(diǎn)上的 Kubelet 發(fā)現(xiàn)自己節(jié)點(diǎn)上有 pod 被調(diào)度過(guò)來(lái),那么 kubelet 就會(huì)創(chuàng)建并且運(yùn)行 pod 中的容器
那么 k8s 默認(rèn)是如何調(diào)度 pod 的?總有一個(gè)優(yōu)先級(jí)吧
是的沒(méi)錯(cuò),總會(huì)有一定的規(guī)則,咱們畫(huà)個(gè)圖來(lái)感受一下:

例如一開(kāi)始集群中有 4 個(gè)節(jié)點(diǎn),在運(yùn)行過(guò)程中,節(jié)點(diǎn) 2 和 節(jié)點(diǎn) 3 變?yōu)椴豢捎昧耍酉聛?lái),若有新的 pod 需要調(diào)度,那么調(diào)度器會(huì)從可用的 2 個(gè)節(jié)點(diǎn)里面選擇一個(gè)最優(yōu)的節(jié)點(diǎn),
例如磁盤(pán),內(nèi)存空間較大,或者 pod 資源個(gè)數(shù)較少的,會(huì)按照綜合優(yōu)先級(jí)遞減排序,
例如就會(huì)生成 pod 調(diào)度到節(jié)點(diǎn) 4
那么問(wèn)題就來(lái)了,k8s 是如何找到滿足需求的可用節(jié)點(diǎn)呢?
當(dāng)然 k8s 找到可用節(jié)點(diǎn)的條件也是不少了,不是隨便一個(gè)節(jié)點(diǎn)就可以接得住的,例如 k8s 會(huì)檢查這些條件
節(jié)點(diǎn)的資源是否被耗盡了
pod 是否設(shè)置了一定要 / 一定不要 調(diào)度到某一個(gè)節(jié)點(diǎn)上
如果這個(gè) pod 需要綁定主機(jī)的端口,那么該節(jié)點(diǎn)的端口是否被占用了
節(jié)點(diǎn)可以滿足創(chuàng)建 pod 對(duì)應(yīng)硬件資源的要求嗎
該節(jié)點(diǎn)上有沒(méi)有和我們即將要?jiǎng)?chuàng)建的 pod 參數(shù)和規(guī)格一致的標(biāo)簽?zāi)?/p>
pod 若需要特定的卷,該節(jié)點(diǎn)支持嗎
… 等等
以上的條件都必須要滿足,才有機(jī)會(huì)將 pod 調(diào)度到這個(gè)節(jié)點(diǎn)上來(lái)
我們是否可以設(shè)置 pod 全部集中在一個(gè)節(jié)點(diǎn),或者分散到多個(gè)節(jié)點(diǎn)中去呢?
實(shí)際上我們知道管理 pod 的資源是 RS / RC,一般情況下 他們會(huì)盡可能的將 pod 分散到不同的節(jié)點(diǎn)上面,但是也不能保證每一次都是這樣的
如果我們自己有需求,可以在 pod 模板中設(shè)置 pod 的親緣性 和 非親緣性來(lái)設(shè)置定,pod 調(diào)度到哪些符合要求的節(jié)點(diǎn)上去
總的來(lái)說(shuō),pod 分散到不同的節(jié)點(diǎn)可以降低風(fēng)險(xiǎn),增強(qiáng)健壯性,若其中一個(gè)節(jié)點(diǎn)掛掉,并不會(huì)應(yīng) pod 提供的服務(wù)
之前說(shuō)到 etcd ,ApiServer 都可以是多個(gè)的,那么這里的調(diào)度器仍然可以是多個(gè),若是真的只有一個(gè)調(diào)度器,服務(wù)多了之后他也扛不住嘞
我們也可以看到 kube-system 命名空間中

這些核心組件都是以 pod 的方式運(yùn)行的,如果我們需要多個(gè) scheduler,那么就多創(chuàng)建幾個(gè)就好了
但是我們?cè)趧?chuàng)建 pod 的時(shí)候,如果沒(méi)有指定使用哪一個(gè)調(diào)度器去調(diào)度的話,那么 k8s 中會(huì)使用默認(rèn)的調(diào)度器,如果我們有需求,實(shí)際可以在 pod 模板中使用 shedulerName 關(guān)鍵字來(lái)指定調(diào)度器的名字
控制器管理器 controller manager
控制器管理器 controller manager 見(jiàn)名知意,他是一個(gè)管理器 manager,管理的對(duì)象是控制器 controller
Replication 管理器,我們可以理解為資源管理器,也就是我們之前學(xué)過(guò)的 RC ,ReplicationController
控制器的話就比較多了,之前我們學(xué)過(guò)的大部分資源,都有對(duì)應(yīng)的控制器進(jìn)行管控,例如:
Node 控制器
Service 控制器
Endpoints 控制器
Namespace 控制器
ReplicaSet 控制器
DaemonSet 控制器
Job 控制器
Deployment 控制器
StatefulSet 控制器
PersistentVolume 控制器
為啥需要控制器管理器?
之前分享的各個(gè)組件中,他們就好像只管好自己就可以獨(dú)善其身了,總得有一個(gè)角色為大家負(fù)重前行吧?
比如說(shuō), ApiServer 只去和 etcd 交互,然后通知監(jiān)聽(tīng)的客戶(hù)端有變更 , 調(diào)度器 Scheduler 又僅僅是給 pod 分配節(jié)點(diǎn)
那么對(duì)于資源的擴(kuò)縮容,以及資源的期望狀態(tài),又誰(shuí)來(lái)進(jìn)行監(jiān)聽(tīng)和處理呢?
那就得 控制器管理器了
那么我們上述的控制器主要是干啥?
首先通過(guò)控制器的名字,我們應(yīng)該是知道這些控制器主要是控制自己對(duì)應(yīng)資源的狀態(tài)的
然而不僅僅是這一點(diǎn)哦,控制器做的事情就稍微雜一點(diǎn),綜合能力比較強(qiáng)
例如:
控制器會(huì)監(jiān)聽(tīng) ApiServer 資源變更
執(zhí)行相應(yīng)的操作,例如創(chuàng)建,編輯,刪除,查看等等
這里的控制器也是不會(huì)相互通信的,都是和 ApiServer 交互,可以理解為 控制器一直在做滿足別人期望的事情,是一個(gè)調(diào)和的角色
例如,我們將期望的副本數(shù),改變了,那么控制器便會(huì)去處理,直到滿足期望后,將最新的狀態(tài)寫(xiě)入資源的 status
那么 Replication 管理器又是何方神圣?
剛才有說(shuō)到他是管理控制器的,控制器又那么多,可以把他看做控制器的管家吧
官方定義,啟動(dòng) ReplicationController 資源的控制器叫做 Replication 管理器
那么對(duì)于 RC 的行為我們應(yīng)該心里都有數(shù)吧,當(dāng)修改了 RC 的副本數(shù)之后,RC 回去調(diào)和 pod 的數(shù)量
這個(gè)實(shí)際動(dòng)作,其實(shí)是 Replication 管理器 這個(gè)幕后大佬做的
之前我們說(shuō)到 RC 的時(shí)候,當(dāng)我們修改這個(gè)副本數(shù),大家是否會(huì)認(rèn)為, k8s 中會(huì)有一個(gè)輪詢(xún)機(jī)制,當(dāng)獲取到 RC 的副本變化的時(shí)候,會(huì)去滿足期望?
實(shí)際上也是和 ApiServer 那一塊分享的類(lèi)似,此處也是用到了監(jiān)聽(tīng)機(jī)制,控制器會(huì)通過(guò)監(jiān)聽(tīng)機(jī)制訂閱可能會(huì)影響期望副本數(shù)的變更事件
若有變更事情時(shí),則會(huì)做出相應(yīng)動(dòng)作
RC 會(huì)實(shí)際去運(yùn)行 pod 嗎?
看到這里,是否還會(huì)有疑問(wèn),既然 RC 會(huì)去滿足期望,那么是 RC 直接去運(yùn)行的 pod 嗎?
并不是的
當(dāng)出現(xiàn)當(dāng)前數(shù)量和期望副本數(shù)量不一致的時(shí)候, RC 回去創(chuàng)建新的 pod 清單,并發(fā)布到 APiServer 上,最終會(huì)讓調(diào)度器和節(jié)點(diǎn)上的 Kubelet 來(lái)調(diào)度 pod 并運(yùn)行 pod
管理器管理那么多的控制器,肯定有一個(gè)統(tǒng)一管理資源的管理流程的,具體的簡(jiǎn)單流程如下:

簡(jiǎn)單來(lái)說(shuō),就是 Replication 管理器會(huì)監(jiān)聽(tīng)具體的資源,然后通過(guò) ApiServer 來(lái)操作對(duì)應(yīng)的資源對(duì)象,最終達(dá)到更新的目的
當(dāng)然,其他控制器也是這樣的,都是監(jiān)聽(tīng)資源,通過(guò) ApiServer 進(jìn)行更新資源
每一種控制器,實(shí)際上我們?cè)诜窒淼狡鋵?duì)應(yīng)資源的時(shí)候,基本都有分享到他們的行為,這里就不再重復(fù)了
今天就到這里,學(xué)習(xí)所得,若有偏差,還請(qǐng)斧正
歡迎點(diǎn)贊,關(guān)注,收藏
朋友們,你的支持和鼓勵(lì),是我堅(jiān)持分享,提高質(zhì)量的動(dòng)力

好了,本次就到這里
技術(shù)是開(kāi)放的,我們的心態(tài),更應(yīng)是開(kāi)放的。擁抱變化,向陽(yáng)而生,努力向前行。
我是阿兵云原生,歡迎點(diǎn)贊關(guān)注收藏,下次見(jiàn)~