[k8s]深度解析pod對象

深入解析pod對象

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

在未來雲計算系統中,容器是進程,容器鏡像是安裝包,Kubernetes是操作系統,而 Pod 則是進程組

pod只是一個邏輯概念,Kubernetes 真正處理的,還是宿主機操作系統上 Linux 容器的 Namespace 和 Cgroups,而並不存在一個所謂的 Pod 的邊界或者隔離環境。

Pod,其實是一組共享了某些資源的容器。Pod 裏的所有容器,共享的是同一個 Network Namespace,並且可以聲明共享同一個 Volume。(Pod間除了共享Network Namespace外,默認還會共享IPC namespace和 User namespace。 1.12版本開始還可以選擇是否開啓Pid namespace的共享)

好像通過 docker run --net --volumes-from 這樣的命令就能實現,比如:
$ docker run --net=B --volumes-from=B --name=A image-A ..
但是如果真這樣做的話,容器 B 就必須比容器 A 先啓動,這樣一個 Pod 裏的多個容器就不是對等關係,而是拓撲關係了。

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

img

在 Kubernetes 項目裏,Infra 容器一定要佔用極少的資源,所以它使用的是一個非常特殊的鏡像,叫作:k8s.gcr.io/pause。這個鏡像是一個用匯編語言編寫的、永遠處於“暫停”狀態的容器,解壓後的大小也只有 100~200 KB 左右。而在 Infra 容器“Hold 住”Network Namespace 後,用戶容器就可以加入到 Infra 容器的 Network Namespace 當中了。所以,如果你查看這些容器在宿主機上的 Namespace 文件,它們指向的值一定是完全一樣的。

對於 Pod 裏的容器 A 和容器 B 來說:

  • 它們可以直接使用 localhost 進行通信;
  • 它們看到的網絡設備跟 Infra 容器看到的完全一樣;
  • 一個 Pod 只有一個 IP 地址,也就是這個 Pod 的 Network Namespace 對應的 IP 地址;
  • 其他的所有網絡資源,都是一個 Pod 一份,並且被該 Pod 中的所有容器共享;
  • Pod 的生命週期只跟 Infra 容器一致,而與容器 A 和 B 無關。

對於同一個 Pod 裏面的所有用戶容器來說,它們的進出流量,也可以認爲都是通過 Infra 容器完成的。這一點很重要,因爲將來如果要爲 Kubernetes 開發一個網絡插件時,應該重點考慮的是如何配置這個 Pod 的 Network Namespace,而不是每一個用戶容器如何使用你的網絡配置,這是沒有意義的。

容器間的緊密協作,我們可以稱爲“超親密關係”。這些具有“超親密關係”容器的典型特徵包括但不限於:互相之間會發生直接的文件交換、使用 localhost 或者 Socket 文件進行本地通信、會發生非常頻繁的遠程調用、需要共享某些 Linux Namespace(比如,一個容器要加入另一個容器的 Network Namespace)等等。

Pod 這種“超親密關係”容器的設計思想,實際上就是希望,當用戶想在一個容器裏跑多個功能並不相關的應用時,應該優先考慮它們是不是更應該被描述成一個 Pod 裏的多個容器。

可以這麼理解 Pod 的本質:Pod,實際上是在扮演傳統基礎設施裏“虛擬機”的角色;而容器,則是這個虛擬機裏運行的用戶程序。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章