Kubernetes項目原子調度單位Pod

jodkreaper 發佈 2024-01-19T09:24:13.464691+00:00

在Kubernetes的API對象中,pod是最小的對象,它是Kubernetes項目的原子調度單位。怎麼理解Pod呢,我們知道容器的本質就是進程(可以看作是雲計算系統的進程),那麼kubernetes相當於作業系統。

在kubernetes的API對象中,pod是最小的對象,它是Kubernetes項目的原子調度單位。

怎麼理解Pod呢,我們知道容器的本質就是進程(可以看作是雲計算系統的進程),那麼kubernetes相當於作業系統。在作業系統里,進程(linux作業系統語境下的線程)並不是孤立獨自運行的,而是以進程組的方式組織在一起,Kubernetes項目所做的就是將「進程組」的概念映射到容器技術中,Pod就是對應的進程組。Kubernetes項目的調度器會統一按照Pod所需資源進行計算。

Pod的意義何在?為什麼需要Pod的最重要原因就是:容器設計模式

Pod實現原理

首先我們要知道Pod它只是一個邏輯概念,Kubernetes真正處理的還是宿主機作業系統上的Namespace和Cgroups。Pod其實是一組共享了某些資源(同一個 Network Namespace,並且可以聲明共享同一個 Volume)的容器。

在 Kubernetes 項目里,Pod 的實現需要使用一個中間容器,這個容器叫作 Infra 容器。在這個 Pod 中,Infra 容器永遠都是第一個被創建的容器,而其他用戶定義的容器,則通過 Join Network Namespace 的方式,與 Infra 容器關聯在一起:

如上圖所示,這個 Pod 里有兩個用戶容器 A 和 B,還有一個 Infra 容器,在 Kubernetes 項目里,Infra 容器一定要占用極少的資源,所以它使用的是一個非常特殊的鏡像,叫作:k8s.gcr.io/pause。這個鏡像是一個用彙編語言編寫的、永遠處於「暫停」狀態的容器,解壓後的大小也只有 100~200 KB 左右。

而在 Infra 容器「Hold 住」Network Namespace 後,用戶容器就可以加入到 Infra 容器的 Network Namespace 當中了。所以,如果你查看這些容器在宿主機上的 Namespace 文件,它們指向的值一定是完全一樣的。這就意味著,對於Pod里的容器A和B來說:

1、它們可以直接使用 localhost 進行通信

2、它們看到的網絡設備跟 Infra 容器看到的完全一樣

3、一個 Pod 只有一個 IP 地址,也就是這個 Pod 的 Network Namespace 對應的 IP 地址

4、其他的所有網絡資源,都是一個 Pod 一份,並且被該 Pod 中的所有容器共享

5、Pod 的生命周期只跟 Infra 容器一致,而與容器 A 和 B 無關

注意,每個用戶容器沒有網絡配置主權,主權由更上層的Pod進行負責,所以開發一個網絡插件,要考慮的是Pod層面如何置這個 Pod 的 Network Namespace

同理,共享Volume就簡單多了,Kubernetes 項目只要把所有 Volume 的定義都設計在 Pod 層級即可。這樣,一個 Volume 對應的宿主機目錄對於 Pod 來說就只有一個,Pod 里的容器只要聲明掛載這個 Volume,就一定可以共享這個 Volume 對應的宿主機目錄。

知道了Pod的實現原理,上面提到的容器設計模式就很好理解了。Pod這種「超親密關係」容器的設計思想,實際上就是希望用戶想在一個容器里跑多個功能不相關的應用時,應該優先考慮它們是不是更應該被描述成一個Pod里的多個容器。

容器設計模式論文:

https://www.usenix.org/conference/hotcloud16/workshop-program/presentation/burns

關鍵字: