Kubernetes 調度器是如何工作的
Kubernetes 已經成為容器和容器化工作負載的標準編排引擎。它提供一個跨公有雲和私有雲環境的通用和開源的抽象層。
對於那些已經熟悉 Kuberbetes 及其組件的人,他們的討論通常圍繞著如何盡量發揮 Kuberbetes 的功能。但當你剛剛開始學習 Kubernetes 時,嘗試在生產環境中使用前,明智的做法是從一些關於 Kubernetes 相關組件(包括 Kubernetes 調度器) 開始學習,如下抽象視圖中所示:
Kubernetes 也分為控制平面和工作節點:
- 控制平面: 也稱為主控,負責對集群做出全局決策,以及檢測和響應集群事件。控制平面組件包括:
- etcd
- kube-apiserver
- kube-controller-manager
- 調度器
- 工作節點: 也稱節點,這些節點是工作負載所在的位置。它始終和主控聯繫,以獲取工作負載運行所需的信息,並與集群外部進行通訊和連接。工作節點組件包括:
- kubelet
- kube-proxy
- CRI
我希望這個背景信息可以幫助你理解 Kubernetes 組件是如何關聯在一起的。
Kubernetes 調度器是如何工作的
Kubernetes 吊艙 由一個或多個容器組成組成,共享存儲和網路資源。Kubernetes 調度器的任務是確保每個吊艙分配到一個節點上運行。
(LCTT 譯註:容器技術領域大量使用了航海比喻,pod 一詞,意為「豆莢」,在航海領域指「吊艙」 —— 均指盛裝多個物品的容器。常不翻譯,考慮前後文,可譯做「吊艙」。)
在更高層面下,Kubernetes 調度器的工作方式是這樣的:
- 每個需要被調度的吊艙都需要加入到隊列
- 新的吊艙被創建後,它們也會加入到隊列
- 調度器持續地從隊列中取出吊艙並對其進行調度
調度器源碼(scheduler.go
)很大,約 9000 行,且相當複雜,但解決了重要問題:
等待/監視吊艙創建的代碼
監視吊艙創建的代碼始於 scheduler.go
的 8970 行,它持續等待新的吊艙:
// Run begins watching and scheduling. It waits for cache to be synced, then starts a goroutine and returns immediately.
func (sched *Scheduler) Run() {
if !sched.config.WaitForCacheSync() {
return
}
go wait.Until(sched.scheduleOne, 0, sched.config.StopEverything)
負責對吊艙進行排隊的代碼
負責對吊艙進行排隊的功能是:
// queue for pods that need scheduling
podQueue *cache.FIFO
負責對吊艙進行排隊的代碼始於 scheduler.go
的 7360 行。當事件處理程序觸發,表明新的吊艙顯示可用時,這段代碼將新的吊艙加入隊列中:
func (f *ConfigFactory) getNextPod() *v1.Pod {
for {
pod := cache.Pop(f.podQueue).(*v1.Pod)
if f.ResponsibleForPod(pod) {
glog.V(4).Infof("About to try and schedule pod %v", pod.Name)
return pod
}
}
}
處理錯誤代碼
在吊艙調度中不可避免會遇到調度錯誤。以下代碼是處理調度程序錯誤的方法。它監聽 podInformer
然後拋出一個錯誤,提示此吊艙尚未調度並被終止:
// scheduled pod cache
podInformer.Informer().AddEventHandler(
cache.FilteringResourceEventHandler{
FilterFunc: func(obj interface{}) bool {
switch t := obj.(type) {
case *v1.Pod:
return assignedNonTerminatedPod(t)
default:
runtime.HandleError(fmt.Errorf("unable to handle object in %T: %T", c, obj))
return false
}
},
換句話說,Kubernetes 調度器負責如下:
- 將新創建的吊艙調度至具有足夠空間的節點上,以滿足吊艙的資源需求。
- 監聽 kube-apiserver 和控制器是否創建新的吊艙,然後調度它至集群內一個可用的節點。
- 監聽未調度的吊艙,並使用
/binding
子資源 API 將吊艙綁定至節點。
例如,假設正在部署一個需要 1 GB 內存和雙核 CPU 的應用。因此創建應用吊艙的節點上需有足夠資源可用,然後調度器會持續運行監聽是否有吊艙需要調度。
了解更多
要使 Kubernetes 集群工作,你需要使以上所有組件一起同步運行。調度器有一段複雜的的代碼,但 Kubernetes 是一個很棒的軟體,目前它仍是我們在討論或採用雲原生應用程序時的首選。
學習 Kubernetes 需要精力和時間,但是將其作為你的專業技能之一能為你的職業生涯帶來優勢和回報。有很多很好的學習資源可供使用,而且 官方文檔 也很棒。如果你有興趣了解更多,建議從以下內容開始:
你喜歡的 Kubernetes 學習方法是什麼?請在評論中分享吧。
via: https://opensource.com/article/20/11/kubernetes-scheduler
作者:Mike Calizo 選題:lujun9972 譯者:MZqk 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive