本文已發布超過一年。較舊的文章可能包含過時的內容。請確認頁面中的資訊自發布以來是否已變得不正確。
分散式系統工具組:複合容器的模式
有幸在 DockerCon 2015 上展示 Kubernetes 的一些想法,我想發布一篇部落格文章,與無法親臨現場的各位分享這些想法。
過去兩年來,容器已成為日益普及的程式碼封裝與部署方式。容器映像檔解決了現有封裝與部署工具的許多實際問題,除了這些顯著的優點之外,容器也為我們提供了一個從根本上重新思考建置分散式應用程式方式的機會。正如服務導向架構 (SOA) 鼓勵將應用程式分解為模組化、重點明確的服務一樣,容器應鼓勵將這些服務進一步分解為緊密協作的模組化容器。 藉由建立邊界,容器讓使用者能夠使用模組化、可重複使用的元件來建置服務,進而產生比從單體容器建置的應用程式更可靠、更具擴充性且建置速度更快的服務。
在許多方面,從 VM 切換到容器就像是從 1970 年代和 80 年代初期的單體程式切換到 1980 年代後期及以後的模組化物件導向程式。容器映像檔提供的抽象層與物件導向程式設計中類別的抽象邊界有許多共同之處,並且它提供了相同的機會來提高開發人員的生產力和應用程式品質。 就像正確的程式碼編寫方式是將關注點分離到模組化物件中一樣,在容器中封裝應用程式的正確方式是將關注點分離到模組化容器中。 從根本上來說, 這意味著不僅要分解整體應用程式,還要將任何一台伺服器內部的組件分解為多個易於參數化和重複使用的模組化容器。透過這種方式,就像現代語言中無處不在的標準程式庫一樣,大多數應用程式開發人員可以將其他人編寫的模組化容器組合在一起,並以更快的速度和更高品質的組件來建置他們的應用程式。
以模組化容器思考的好處非常巨大,特別是,模組化容器提供以下優點
- 加速應用程式開發,因為容器可以在團隊之間甚至更大的社群之間重複使用
- 將專家知識編纂成典,因為每個人都協作開發單一容器化實作,該實作反映了最佳實務,而不是無數個功能大致相同的自家容器
- 支援敏捷團隊,因為容器邊界是團隊職責的自然邊界和契約
- 提供關注點分離並專注於特定功能,從而減少義大利麵式依賴關係和無法測試的組件
從模組化容器建置應用程式意味著思考協作以提供服務的共生容器群組,而不是每個服務一個容器。 在 Kubernetes 中,這種模組化容器服務的體現是 Pod。 Pod 是一組容器,它們共享檔案系統、核心命名空間和 IP 位址等資源。 Pod 是 Kubernetes 叢集中排程的原子單元,正是因為 Pod 中容器的共生性質要求它們被共同排程到同一部機器上,而可靠地實現這一點的唯一方法是使容器群組成為原子排程單元。
當您開始以 Pod 的角度思考時,自然會出現一些模組化應用程式開發的通用模式,這些模式會多次重複出現。 我確信,隨著我們在 Kubernetes 開發方面向前邁進,將會識別出更多這些模式,但以下是我們常見的三種模式
範例 #1:Sidecar 容器
Sidecar 容器擴展和增強「主要」容器,它們採用現有的容器並使其變得更好。 例如,考慮一個執行 Nginx 網頁伺服器的容器。 新增一個不同的容器,將檔案系統與 git 儲存庫同步,在容器之間共享檔案系統,您就建置了 Git push-to-deploy。 但您是以模組化的方式完成的,git 同步器可以由不同的團隊建置,並且可以在許多不同的網頁伺服器(Apache、Python、Tomcat 等)之間重複使用。 由於這種模組化,您只需要編寫和測試您的 git 同步器一次,就可以在眾多應用程式中重複使用它。如果其他人編寫了它,您甚至不需要這樣做。
範例 #2:Ambassador 容器
Ambassador 容器將本機連線代理到外部世界。 例如,考慮一個具有讀取複本和單一寫入主節點的 Redis 叢集。 您可以建立一個 Pod,將您的主要應用程式與 Redis Ambassador 容器分組在一起。 Ambassador 是一個代理,負責拆分讀取和寫入操作,並將它們發送到適當的伺服器。 由於這兩個容器共享一個網路命名空間,因此它們共享一個 IP 位址,並且您的應用程式可以在「localhost」上開啟連線並找到代理,而無需任何服務探索。 就您的主要應用程式而言,它只是連線到在本機執行之 Redis 伺服器。 這非常強大,不僅僅是因為關注點分離以及不同團隊可以輕鬆擁有組件的事實,還因為在開發環境中,您可以簡單地跳過代理並直接連線到在本機執行之 Redis 伺服器。
範例 #3:Adapter 容器
Adapter 容器標準化和正規化輸出。 考慮監控 N 個不同應用程式的任務。 每個應用程式都可能使用不同的方式匯出監控資料。(例如 JMX、StatsD、應用程式特定統計資訊),但每個監控系統都期望監控資料的資料模型是一致且統一的。 透過使用複合容器的 Adapter 模式,您可以透過建立將應用程式容器與知道如何進行轉換的 Adapter 分組在一起的 Pod,將來自不同系統的異質監控資料轉換為單一的統一表示形式。 同樣地,由於這些 Pod 共享命名空間和檔案系統,因此這兩個容器的協調非常簡單明瞭。
在所有這些情況下,我們都將容器邊界用作封裝/抽象邊界,這使我們能夠建置模組化、可重複使用的組件,我們將這些組件組合起來以建置應用程式。 這種重複使用使我們能夠更有效地在不同開發人員之間共享容器,在多個應用程式中重複使用我們的程式碼,並通常更快地建置更可靠、更穩健的分散式系統。 我希望您已經了解 Pod 和複合容器模式如何使您能夠更快地建置穩健的分散式系統,並實現容器程式碼的重複使用。 為了在您自己的應用程式中親自嘗試這些模式。我鼓勵您去查看開源 Kubernetes 或 Google Container Engine。