容器(Container)常被用來解決好比微服務的單個問題,但在實際場景中,問題的解決每每須要多容器方案。本文會討論將多個容器整合進單個Kubernetes Pod 中,以及Pod中的容器之間是如何通訊的。nginx
首先咱們來探討下什麼是Pod。Pod是Kubernetes中最小的可部署和管理單元。換句話講,若是須要在Kubernetes中運行單個容器,那麼你就得爲這個容器建立一個Pod。同時,一個Pod能夠包含多個容器,這些容器每每是緊耦合的。怎麼樣個緊耦合法呢?試着想象這麼一個場景,一個Pod中的多個容器表明須要運行在同一個服務器上的多個進程。這種類比是合理的,由於在許多方面,Pod就相似於一臺服務器。好比,經過localhost每一個容器能夠訪問它所在Pod中的其它容器。web
儘管直接部署單個容器也許會更容易,但增長Pod這個新的抽象層會帶來新的好處。容器是一個真實存在的實體,它表明一個具體的東西。這個「東西」能夠是一個Docker容器,也能夠是一個rkt容器。每種「東西」都有不一樣的用途。爲了管理容器,Kubernetes須要更多的信息,好比重啓策略(restart policy),它定義了當容器終止了時怎樣重啓容器;還有活性檢測(liveness probe),它定義瞭如何從應用視角去檢測容器中的進程是否活着,好比Web服務器進程是否能響應HTTP請求。瀏覽器
爲了不在容器這個已有的實體上增長這些新的屬性,Kubernetes架構師們決定使用一個新的實體,那就是Pod。它邏輯地包含一個或多個容器。服務器
Pod中的容器們運行在一個邏輯「主機」上。他們使用同一個網絡命名空間(network namespace,換句話講,就是一樣的IP地址和端口空間),以及一樣的IPC(inter-process communication,進程間通訊)命名空間,他們還使用共享卷(shared volume)。這些特徵使得Pod內的容器能互相高效地通訊。同時,Pod使得你能夠將多個緊耦合的應用容器當作一個實體來管理。網絡
那麼,若是一個應用須要在同一臺服務器上運行多個容器,爲何不把全部東西放在一個容器裏面呢?好吧,首先,這會違反「一個容器一個進程」規範。這個規範很重要,由於當一個容器中有多個進程時,調試會變得很是困難,由於不一樣進程的日誌會混在一塊兒,並且很難去管理這些進程的生命週期。其次,爲一個應用使用多個容器會更簡單、更直接、能解耦軟件依賴。並且,更細粒度的容器能夠在團隊間複用。架構
多容器Pod的主要目的是爲了支持同時存在的(co-located)及同時被管理的(co-managed)幫助進程(helper process)。幫助進程有幾種通用場景:curl
邊車容器(sidecarcontainer):好比日誌或數據變化監視器等。一個團隊建立日誌監視器(log watcher)後,它能夠被各類應用使用。另外一個邊車容器的例子是文件或數據加載器,它負責爲主容器產生數據。ide
代理(Proxy)、橋(bridge)和適配器(adapter):它們將主容器鏈接到外部世界。好比,Apache HTTP 服務器或nginx 會讀取靜態文件。它們還能被用做主容器中的web應用的反向代理(reverseproxy)。微服務
當你在Pod中運行多層應用(好比WordPress)時,推薦的方式是爲每層使用單獨的Pod。最簡單的理由是這樣你就能夠獨立地擴展每層,並將他們分佈在不一樣節點上。工具
在Pod中運行多個容器,使得它們之間的通訊很是直接。他們本身的通訊有幾種方法。
在Kubernetes中,Pod中的容器能夠將共享卷當作一種簡單和高效的共享數據方式。在大多數場景中,使用主機上的一個目錄,並在多個容器間共享,是一種高效的方式。
Kubernetes volume(卷)使得在容器重啓後數據能被保存下來。卷具備和Pod同樣的生命週期。這意味着,只要Pod存在,卷就存在。若是Pod被刪除了,即便如出一轍的Pod被建立出來,原來Pod的共享卷也會被銷燬,一個新的共享卷會被建立出來。
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端口。