K8s中的多容器Pod和Pod內容器間通信



容器(Container)常被用來解決比如微服務的單個問題,但在實際場景中,問題的解決往往需要多容器方案。本文會討論將多個容器整合進單個Kubernetes Pod 中,以及Pod中的容器之間是如何通信的。

Kubernetes Pod 是什么?

首先我們來探討下什么是Pod。Pod是Kubernetes中最小的可部署和管理單元。換句話講,如果需要在Kubernetes中運行單個容器,那么你就得為這個容器創建一個Pod。同時,一個Pod可以包含多個容器,這些容器往往是緊耦合的。怎么樣個緊耦合法呢?試着想象這么一個場景,一個Pod中的多個容器代表需要運行在同一個服務器上的多個進程。這種類比是合理的,因為在許多方面,Pod就類似於一台服務器。比如,通過localhost每個容器可以訪問它所在Pod中的其它容器。

為什么Kubernetes將Pod而不是單個容器作為最小可部署單元呢?

盡管直接部署單個容器也許會更容易,但增加Pod這個新的抽象層會帶來新的好處。容器是一個真實存在的實體,它代表一個具體的東西。這個“東西”可以是一個Docker容器,也可以是一個rkt容器。每種“東西”都有不同的用途。為了管理容器,Kubernetes需要更多的信息,比如重啟策略(restart policy),它定義了當容器終止了時怎樣重啟容器;還有活性檢測(liveness probe),它定義了如何從應用視角去檢測容器中的進程是否活着,比如Web服務器進程是否能響應HTTP請求。

 

為了避免在容器這個已有的實體上增加這些新的屬性,Kubernetes架構師們決定使用一個新的實體,那就是Pod。它邏輯地包含一個或多個容器。

為什么Kubernetes允許Pod中存在一個或多個容器?

Pod中的容器們運行在一個邏輯“主機”上。他們使用同一個網絡命名空間(network namespace,換句話講,就是同樣的IP地址和端口空間),以及同樣的IPC(inter-process communication,進程間通信)命名空間,他們還使用共享卷(shared volume)。這些特征使得Pod內的容器能互相高效地通信。同時,Pod使得你可以將多個緊耦合的應用容器當做一個實體來管理。

 

那么,如果一個應用需要在同一台服務器上運行多個容器,為什么不把所有東西放在一個容器里面呢?好吧,首先,這會違反“一個容器一個進程”規范。這個規范很重要,因為當一個容器中有多個進程時,調試會變得非常困難,因為不同進程的日志會混在一起,而且很難去管理這些進程的生命周期。其次,為一個應用使用多個容器會更簡單、更直接、能解耦軟件依賴。而且,更細粒度的容器可以在團隊間復用。

多容器Pod的用例

多容器Pod的主要目的是為了支持同時存在的(co-located)及同時被管理的(co-managed)幫助進程(helper process)。幫助進程有幾種通用場景:

 

  • 邊車容器(sidecarcontainer):比如日志或數據變化監視器等。一個團隊創建日志監視器(log watcher)后,它可以被各種應用使用。另一個邊車容器的例子是文件或數據加載器,它負責為主容器產生數據。

  • 代理(Proxy)、橋(bridge)和適配器(adapter):它們將主容器連接到外部世界。比如,Apache HTTP 服務器或nginx 會讀取靜態文件。它們還能被用作主容器中的web應用的反向代理(reverseproxy)。

     

當你在Pod中運行多層應用(比如WordPress)時,推薦的方式是為每層使用單獨的Pod。最簡單的理由是這樣你就可以獨立地擴展每層,並將他們分布在不同節點上。

Pod 中容器間的通信

在Pod中運行多個容器,使得它們之間的通信非常直接。他們自己的通信有幾種方法。

通過共享卷通信 

在Kubernetes中,Pod中的容器可以將共享卷當做一種簡單和高效的共享數據方式。在大多數場景中,使用主機上的一個目錄,並在多個容器間共享,是一種高效的方式。 

 

Kubernetes volume(卷)使得在容器重啟后數據能被保存下來。卷具有和Pod一樣的生命周期。這意味着,只要Pod存在,卷就存在。如果Pod被刪除了,即使一模一樣的Pod被創建出來,原來Pod的共享卷也會被銷毀,一個新的共享卷會被創建出來。 

進程間通信(Inter-processCommunication,IPC)

Pod中的容器共享同一個IPC命名空間,這意味着它們可以使用標准的進程間通信方式來互相通信,比如SystemV信號量和POSIX共享內存。

 

容器間的網絡通信

Pod中的容器可以通過“localhost”來互相通信,因為他們使用同一個網絡命名空間。而且,對容器來說,hostname就是Pod的名稱。因為Pod中的所有容器共享同一個IP地址和端口空間,你需要為每個需要接收連接的容器分配不同的端口。也就是說,Pod中的應用需要自己協調端口的使用。

 

在下面的例子中,我們會創建一個多容器Pod,其中一個容器中運行Nginx,它作為另一個容器中運行的web應用的反向代理。

(1)步驟1,為nginx配置文件創建一個ConfigMap。從80端口進來的HTTP請求會被轉發到localhost上的5000端口。

(2)步驟2:創建一個兩容器Pod,一個容器運行nginx,另一個容器運行簡單的web應用。注意我們只為Pod定義了80端口。端口5000不能被從Pod外部訪問到。

 查看pod中的端口空間,能看到有80 和 5000端口。

 

(3)步驟3:將Pod暴露為一個 NodePort服務

 (4)步驟4:確認服務

現在,就可以使用瀏覽器或者curl工具來訪問這個web應用了。

nginx容器的80端口上收到的HTTP請求會被轉發到web應用容器的5000端口。

 


免責聲明!

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



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