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

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

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

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

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

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