當前位置:
首頁 > 最新 > Kubernetes中的Pod的到底是什麼?

Kubernetes中的Pod的到底是什麼?

最近看到了偉大的「Amy Codes」(真心希望這是她真名)關於Kubernetes Pod的一條推文:

知道為什麼一個Pod中的容器總是配置成一起工作么?因為這是嵌套的容器。

——Amy Codes, 2017.8.21

儘管說的並不是100%的準確(容器並不是這回事,我們後面再講),但也確實說明Pod是非常神奇的。所以,也值得我們研究一下Pod和容器的真實面目。

Kubernetes的Pods官方文檔(https://kubernetes.io/docs/concepts/workloads/pods/pod/)最權威且詳盡地解釋了Pod,但是官方文檔寫的更偏整體性,而且用了很多術語。筆者強烈建議從頭到尾閱讀官方文檔,因為官方文檔的解釋要比筆者寫的更好更準確。這篇博文希望能提供更加接地氣的介紹。

容器並不是Linux系統的containers

許多人知道這個事實,但是Linux系統中的「containers」並不是真實存在的。在Linux中,沒有叫做「container」(容器)的實體。大家所知道的容器,其實是依託於Linux的兩個特性而運行的正常的系統進程,這兩個特性是命名空間和cgroups。命名空間提供對於某個進程的一種「視圖」,可以將其它命名空間的東西隱藏,從而為該進程提供它自己獨立運行的環境。這使得進程之間互相不可見,也不可相互影響:

命名空間包括如下:

主機名

進程ID(PID)

文件系統

網路介面

進程間通信(IPC)

上面提到,運行在一個命名空間的進程不會與其它的進程互相影響,其實也並不完全是這樣。一個進程可以使用它所在的物理機的所有資源,所以會擠占其它進程的可用資源。為了限制這樣的情況,Linux提供了一種特性叫做cgruops。進程在一個cgroup中運行的情況與在一個命名空間中類似,但是cgroup限制了該進程可用的資源。所謂的「資源」包括CPU、內存、阻塞I/O、網路I/O等。CPU的分配可以以千分之一核為單位,內存的分配可以以位元組(bytes)為單位。該進程可以正常運行,但是它只可以使用cgroup允許的CPU能力,如果所使用的內存超出cgroup設置的限制就會內存溢出。

通過Google可以搜索到很多關於命名空間和cgroups的學習資料。筆者建議大家可以先學習一下。以下是幾個推薦資料:

What even is a container: namespaces and cgroups(https://jvns.ca/blog/2016/10/10/what-even-is-a-container/)

YOUTUBE: Cgroups, namespaces, and beyond: what are containers made from?(https://www.youtube.com/watch?v=sK5i-N34im8)

需要指出的是,cgroups和每個命名空間類型,是_分開的特性_。上文列出的命名空間的組成部分,某些可能會用到,也有些用不到。你可以只使用cgroups進行隔離,或者使用cgroups和不同命名空間類型的組合(其實仍然是使用命名空間和cgroups,但只是使用根元素)。命名空間和cgroups也可以作用於_一組進程_。用戶可以在一個命名空間中運行多個進程。這種情況下,進程可以互相可見,也可以進行交互。用戶也可以在一個單獨的cgroup中運行多個進程。這種方式會限制這組進程可使用的CPU和內存資源。

組合的組合

在使用Docker運行容器時,Docker會為每個容器創建命名空間和cgroups,所以Docker和容器是一一對應的。這也是開發者對於容器的正常認知。

容器本質上類似於獨立的存儲倉。如果容器需要與外界通信,容器就需要存儲卷或將埠映射到宿主機。

但是,通過增加命令行參數,你可以用一個單獨的命名空間將Docker容器結合起來。首先,我們先為nginx創建一個單獨的容器。

$ cat nginx.conf> error_log stderr;> events { worker_connections 1024; }> http {> access_log /dev/stdout combined;> server {> listen 80 default_server;> server_name example.com www.example.com;> location / {> proxy_pass http://127.0.0.1:2368;> }> }> }> EOF$ docker run -d --name nginx -v `pwd`/nginx.conf:/etc/nginx/nginx.conf -p 8080:80 nginx

然後,我們再啟動一個容器,運行ghost(ghost是一款開源的博客發布平台/軟體)。但是這次我們會增加一些額外的參數,使得這個容器與nginx處於同一個namespace中。

$ docker run -d --name ghost --net=container:nginx --ipc=container:nginx --pid=container:nginx --net=container:nginx ghost

現在,我們的nginx容器可以在localhost上直接將請求代理轉發給ghost容器。如果你訪問http://localhost:8080,你應該可以看到通過nginx代理運行的ghost。上述命令創建了一組容器,這些容器運行在同一組命名空間中。這些命名空間允許Docker的容器互相發現並通信。

Pods是一種容器

我們已經看到,我們可以將命名空間和cgroups與多個線程結合起來,而這正是Kubernetes Pods的本質。Pods讓你可以指定想要運行的容器,而Kubernetes自動地建立相應的命名空間和cgroups。實際上還要複雜一些,因為Kubernets並不使用Docker網路(Kubernetes使用CNI,Container Network Interface,容器網路介面),但是本質是類似的。

只要我們將容器設置成這種模式,每個進程會「感覺」它運行在同一台機器上。這些容器可以在本機互相通信,也可以共享存儲卷(volume)。他們之間甚至可以使用IPC或者互相發送HUP或者TERM這種信號(需要在Kubernetes 1.7,以及Docker>=1.3環境共享PID命名空間)。

現在假設你想運行nginx和confd,使用confd更新nginx配置信息,並在你增加/移除應用伺服器時重啟nginx。假設你部署了一台etcd伺服器,該伺服器有後端應用伺服器的IP地址。當IP列表變化時,confd會收到通知,生成新的nginx配置,並且會給nginx發HUP信號通知nginx重新載入新配置。

如果基於Docker做上述工作,你可以將nginx和confd放在同一個容器中。由於Docker只有一個入口點(entrypoint),你需要使用類似supervisord的工具保證兩個進程持續運行。這種做法並不理想,因為你得為每個運行的nginx副本運行supervisord。更重要的是,Docker只「知道」supervisord,因為supervisord是Docker的入口點。Docker無法看到每個進程,這意味著維護人員以及所用工具無法通過Docker API獲取這些進程的信息。nginx可能已經跪了好久,但是Docker卻對此一無所知。

但是通過Pod,Kubernetes可以管理每個進程,因此對於每個進程的狀態都有監控。這樣,Kubernetes可以通過API向用戶提供進程的狀態,而且也可以提供一些服務,例如進程重啟或者自動日誌記錄等。

將Pods容器作為API

通過上文所述的方式將容器和Pod結合起來,本質上我們可以實現創建容器、將容器加入到Pod中並作為一種「API」供其他人使用。這種API跟正常的Web API不同,更像是一種其它Pods可以使用的抽象API。

以nginx+confd的結合為例。在此示例中,confd對nginx進程一無所知。confd認為自己的工作,就是監控一個etcd中的值,並且向某個進程發送HUP信號或者運行一條命令。confd監控的app並不一定是nginx。這個app可以是任何類型的應用。這種情況下,用戶可以使用confd容器鏡像和配置,並將confd應用於任何數量的、不同種類的Pods。以這種用法使用的Pods可以稱為「側斗容器」(「側斗」是像三輪摩托警車的側邊座位那種。譯者注),可調用「摩托車的側斗」鏡像。

你也可以想像其它類型的抽象描述。類似istio的全互連服務,可以作為「側斗」安插到服務中,提供服務路由、遙測、策略加強等服務,而且不需要修改主應用。

你也可以使用多個「側斗」。你完全可以同時結合confd和istio服務。多種應用可以使用這種方式結合起來,創建更加複雜可靠的系統,同時還能保持每個app相對簡單。

希望本文比較清楚地解釋了Pods是什麼,以及為什麼Pods在未來的容器部署中是必不可少的一部分。如果你有興趣對Kubernetes進行更深入的了解,可以加入Kubernetes Slack。這是最優秀的Kubernetes開發者集中討論問題的地方。你可以加入#Kubernetes-users聊天室(Slack中叫做channel。譯者注),參與Kubernetes各個方面的討論。

燒腦式Kubernetes實戰訓練營

本次培訓理論結合實踐,主要包括:Kubernetes架構和資源調度原理、Kubernetes DNS與服務發現、基於Kubernetes和Jenkins的持續部署方案 、Kubernetes網路部署實踐、監控、日誌、Kubernetes與雲原生應用、在CentOS中部署Kubernetes集群、Kubernetes中的容器設計模式、開發Kubernetes原生應用步驟介紹等,點擊識別下方二維碼加微信好友了解具體培訓內容

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Docker 的精彩文章:

Kubernetes是什麼?
如何開發部署Kubernetes Native應用
DC/OS 1.10:一個面向容器化未來的平台
為什麼我們要開源自己研發的高性能容器編排系統 Eru2
功能即服務介紹

TAG:Docker |