kubernetes之pod基本概念總結


1. 什么是pod

一些關於pod的表述很專業,例如

Pod 是可以在 Kubernetes 中創建和管理的、最小的可部署的計算單元

pod是kubernetes項目中的最小API對象

pod是kubernetes項目的原子調度單位

官方描述:https://kubernetes.io/zh/docs/concepts/workloads/pods/

2. 為什么需要pod

對於這些對pod概念的總結大多殊路同歸。

在理解概念前不妨先想一個問題:

明明有了容器,為什么還需要pod?

因為:

為了解決容器不足,或者說容器無法滿足需求。

確實是這樣,先分析一下容器的本質:

namespace做隔離

Cgroup做限制

rootfs做文件系統

三者相輔相成組成容器基本模型

但是,宏觀的來說,容器的本質是系統中的一個進程。只不過這個進程啟動時被附加了以上等等一下特殊的屬性。

所謂容器只是一個恰當的說法。

就如系統中的大多數進程來說,不是單個進程獨自工作,而是以“進程組”的方式“原則性”的組織在一起,互相協作,完成復雜任務。當然,它們之間也會共享一些資源,例如pid,namespace,存儲等等。

在實際開發和運維中也是隨處可見的這種問題,應用之間有深切的聯系和依賴。

比如說,我要將一個應用容器化,這個應用由負責各個功能的5個進程組成,這時候,問題來了。

正是容器的局限性:單進程模型

單進程不是指容器中只能運行一個進程,而是容器無法去管理多個進程

例如,容器中有pid=1的進程,還有一個pid=5的進程,當這個pid=5的進程異常退出時,后續的垃圾回收等處理工作又由誰去做呢?

所以,這個應用的5個模塊就必須分別制成5個容器,而且必須在同一個機器上運行。

隨之而來的又是一個問題:

​ 也就是容器調度問題,例如有兩個容器調度節點node1和node2,可用內存分別為5G和4.5G,

每個容器分1G內存。由於5個容器必須在一台機器,正常全部調度到node1剛剛好,沒有任何問題。

​ 但是,因為是以容器為單位調度,有這樣一些特殊情況。當前4個容器被調度到node2上時,空間只有0.5G,不足以運行最后一個容器,它有只能在node1運行,這就是以容器為調度單位的缺點。

當然也有解決方案:如Mesos中的資源囤積(resource hoarding),也就是所有調度任務都到達了才進行調度,也有谷歌Omega論文提出樂觀調度,就是先不管沖突,而是在沖突之后通過一系列回滾機制解決沖突。

但這些都沒有很完善的解決容器調度問題,但是在kubernetes中,這些問題都迎刃而解。

因為不在按照傳統思維的將容器作為調度單位

kubernetes中的項目調度器是統一按照pod的資源需求做調度計算

也就是開始總結的那句話: pod是kubernetes項目的原子調度單位

3. pod結構

如圖所示,一個pod包含了兩類容器:

  • 用戶容器
  • Pause容器,也常常被稱為“根容器”(貌似老版本叫做infra容器)

用戶容器好理解,但是Pause容器,也就是根容器,他是做什么用的呢?

pause容器主要為每個用戶容器提供以下功能:

①  PID命名空間:Pod中的不同應用程序可以看到其他應用程序的進程ID。

② 網絡命名空間:Pod中的多個容器能夠訪問同一個IP和端口范圍。

③ IPC命名空間:Pod中的多個容器能夠使用SystemV IPC或POSIX消息隊列進行通信。

④ UTS命名空間:Pod中的多個容器共享一個主機名;Volumes(共享存儲卷):

⑤ Pod中的各個容器可以訪問在Pod級別定義的Volumes。

4. 容器設計模式

考慮這樣一個問題,容器見的關系是一成不變的嗎?

舉一些例子:

  1. 在pod中的一些容器的啟動,必須依賴某一個正在運行的容器,也就是說這個容器必須比其他容器先啟動
  2. 在pod中的容器必須同時協作,也就是說所有容器必須並行執行
  3. 一個pod需要給外部的其他pod提供接口
  4. 外部訪問pod時,又怎樣確保響應報文的一致性
  5. ..........

常見容器設計模式:

Init(初始化)容器

Sidecar(邊車)容器

Adapter(適配器)容器

Ambassador(外交官)容器

關於容器設計模式可以參考論文:https://www.usenix.org/conference/hotcloud16/workshop-program/presentation/burns

5. pod實現原理

一定要明白一點:pod只是一個邏輯上的概念

因為kubernetes真正處理的還是宿主機操作系統上容器的Namespace和Cgroup,也就是說沒有所謂的pod邊界或隔離環境。

所以說,pod就是一組共享了某些資源的容器

在一個pod中所有容器是共享一個Network Namespace的,根據聲明的不同來實現不同的資源共享

但是容器間的復雜關系在容器上難以解決,所以kubernetes項目里,pod的實現借用了一個中間容器,也就是常常說的根容器(也叫pause容器或infra容器,現在好像都統稱pause容器,infra容器已經不再使用)。

在pod中,根容器永遠是第一個創建的容器,用戶后面定義的容器會加入進pod的Network Namespace,從而在視圖上容器都在pod里。

不妨在k8s中看看這個容器鏡像:

[root@master ~]# docker images | grep pause
registry.aliyuncs.com/google_containers/pause                     3.2        80d28bedfe5d   15 months ago   683kB

#當然,主機上有多少個pod就能docker ps 過濾看到多少pause容器

pause鏡像大小只有683k,它是由匯編語言寫的鏡像

在一個pod中的容器,他們的Namespace文件,是一樣的

也就意味着:

  • pod內的容器可以使用localhost進行通信
  • 根容器能看到的網絡資源,其他容器都能看到,也就是pod的網絡資源和pod內的容器共享
  • 一個pod有一個ip地址,和pod對應的Network namespace的ip一致
  • pod的生命周期只與根容器有關,與pod內的容器無關
  • 從pod里的容器的視角來說,它們的流量進出可以看做是通過根容器完成的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM