當一個pod包含多個容器,這些容器一定會在同一個節點上運作 (一個pod決不會跨多個工作節點)
容器被設計為每一個容器只運行一個程序(除非程序本身產生子程序),盡量別在一個容器執行多個程序。 如果再單個容器運行多個不相關的程序,那個保持所有程序執行、管理它們的log等將會是我們的責任。 例如:我們需要包含一種在程序崩潰的時能夠自動重啟的機制,同時這些程序都將log到相同的標準輸出中,而此時我們將很難釐清每個程序分別記錄了什麼。 讓每個程序都運行於自己的容器中,這個是 docker 與 k8s 期望的使用方式。
由於不能將多個程序其中在一個容器中,我們需要另一種更高級的結構來將容器綁定再一起,並且將他們做一個單元進行管理,這就是 pod 背後的基本原理。 在包含容器的pod下,我們可以同時運行一些密切相關的程序,並為它們提供(幾乎)相同的環境,此時這些程序就好像全部運行於單一個容器內,同時又保持著一定的隔離。 這樣一來,我們便能全面的利用容器所提供的特性,同時對這些程序來說他們就像運行再一起依樣,兩全其美。
了解到容器之間彼此完全隔離,但這時候我們想隔離的是 容器群組 ,而不是單個容器,並且讓每個容器群組內的容器共享一些資源,而不是全部(換句話說,沒有完全隔離)。 k8s透過設定 Docker 來讓一個pod內的所有容器共用相同的 Linux命名空間,而不是每個容器都有自己的命名空間。
由於一個pod中的所有容器都在相同的 network 與 UTS 命名空間下運行 (這裡討論的是 Linux命名空間),所以它們都共用相同的主機名稱與網路介面。 這意味著同一個pod中的容器運行的多個程序需要注意不能綁定到相同的port號,否則會衝突,但這個只有涉及到一個pod中的容器。
一個pod中的所有容器也都具有相同的loopback網路介面,因此容器可以通過 localhost 與同一個pod中的其他容器進行通訊。 同樣的,這些容器也都在相同的IPC命名空間下運行,因此能夠通過IPC進行通訊。
在最新版的k8s與docker,它們也能共用相同的PID命名空間,但是默認沒有啟用。 注意:當同一個pod中的容器使用單獨的PID命名空間時,在容器中執行
ps aux
就只會看到容器自己的程序。
但是牽扯到檔案系統時,情況就有所不同。由於大多數容器的檔案系統來自於容器映像檔。因此預設情況下,每個容器的檔案系統與其他容器完全隔離。 但我們可以使用 Volume 的 k8s資源 來共享文件目錄。
k8s叢集中的所有pod都在同一個共享網路地址空間中,這意味著每個pod都可以透過其他pod的IP來實現互相訪問。這也表示它們之間沒有經過NAT處理。 兩個pod彼此之間發送網路封包時,它們都會將對方的實際IP當作封包中的來源IP。
圖 3.2 每個pod取得可以路由的IP,其他pod都可以該IP下看到開Pod
不論將兩個pod安排在同一個節點或是不同節點上,同時不管其實節點之間的網路拓撲如何,這些pod內的容器都能像在無NAT的平坦網路中一樣的互相溝通,就像區域網路LAN上的電腦一樣。 此時每個pod都有自己的IP,並且可以通過這個特別建立的網路實現pod之間的互相溝通,這個特別的網路通常是由額外的軟體 (CNI) 基於真實網路上實現的。
pod是邏輯主機,它的行為與非容器世界中的實體機或者虛擬機非常相似。此外,運行在同一個pod中的程序與運行在一個實體機或虛擬機上的程序類似,只是每個程序都封裝在一個容器之中。
將pod視為獨立機器,其中每台機器只託管一個特定的應用程式。過去習慣將各種應用程式塞進一台主機,但是pod並不是這樣幹的。 由於pod比較輕量,可以幾乎不導致任何額外開銷的前提下擁有盡可能多的pod。這跟所有東西填充到一個pod中不同,應該將應用程式組織到多個pod中,而每個pod只包含緊密相關的元件或者程序。
例如雖然可以在單一個pod中同時運行前端服務跟資料庫這兩個容器,但這樣方式不推薦。pod中的容器永遠都會在同一台機器上運作,這樣就無法將前端跟資料庫分開在不同的機器上運作。 不應該放在一起的另一個原因就是因為擴展性。對於k8s來說,不能橫向擴縮單個容器,只能擴縮整個pod。
通常來說,前端組件與後端組件具有完全不同的擴展性需求,所以傾向於分別獨立擴縮它們。更不用說像資料庫這樣的後端服務,通常要比無狀態的前端web服務更難擴展。如果你需要擴縮pod的某個容器,那這個容器就建議部屬在單獨的pod中。
不過將多個容器加入到單個pod的主要原因可能是由一個主程序和一個或者多個輔助程序組成,彼此緊密耦合。 例如:pod中的主容器可以是一個服務於某個目錄中文件的web服務,而另一個容器(所謂的sidecar容器)則是定期從外部資源下載檔案到web目錄中。
sidecar容器還有其他例子,例如:收集log用、數據處理、網路通訊調配。
如何決定將兩個容器放在一個pod還是分開放兩個pod,可以根據以下問答來決定。
.它們需要一起運作在同一台機器上嗎? .它們代表的是一個整體還是互相獨立的元件? .它們必須一起進行擴縮嗎?