1. 程式人生 > >【容器化思維】傳統分布式架構容器化的實踐和挑戰

【容器化思維】傳統分布式架構容器化的實踐和挑戰

命令 整理 CM 拓展 對比 階段 AS 結合 客戶

作者:個推研發專家朱明智

隨著以Docker為典型代表的容器化理念逐漸興起,眾多的使用分布式架構的公司和企業,開始考慮對原有系統進行容器化升級。傳統分布式架構為什麽需要容器化?容器化面臨怎樣的機遇與挑戰?作為智能大數據服務商的個推如何將容器化落地?未來將有怎樣的發展?本文以個推在容器化上的實踐為例,與大家一起探討及展望。

傳統分布式架構的特點

傳統分布式架構系統,一般具有以下兩個特點:

一、根據業務和資源消耗的不同,開發者會對傳統分布式架構系統進行模塊劃分。例如:根據業務的區分,個推會劃分出不同的系統模塊,和手機SDK建立長連接的客戶端CM模塊,以及負責消息路由的IM模塊;根據資源消耗的不同,個推會將多次讀寫Redis 和多次讀寫MySQL的用戶模塊拆開成不同的角色。

二、在傳統分布式架構系統中,相同的角色模塊會有多個實例。這種系統,一方面做到了高可用性,當一個服務器宕機時不影響整體業務。另一方面,在壓力變大時方便通過擴容提升吞吐率。例如:當偏重Redis讀寫的角色請求較多的時候,系統就只需要擴這個角色的實例。

多年實踐證明,傳統分布式架構系統具有易拓展、高可靠、高效率、低沈本的顯著優勢,但也具有一定的局限性。

由於角色模塊紛繁復雜的特性,傳統分布式架構系統在配置管理、服務資源管理、部署環境等工作中難以通過人工快速地完成。例如:針對每個業務模塊的不同版本,上線前都需要開發者一一做配置修改;當需要修改具體功能時,必然牽涉很多模塊,為開發者產生大量重復的工單。

那麽,怎樣才能解決這些問題,創建出理想的線上環境和良好的可視化管理系統?這時,我們想到了容器化。

容器化的機遇與挑戰

容器化能夠有效地解決傳統分布式架構系統的一系列問題。其中Docker和Kubernetes是最常用的開源容器引擎和編排工具。

◎Docker

Docker無疑是目前最受歡迎的開源容器引擎。Docker的原理,是將多個應用以及運行所需要的一切環境,都通過集裝箱也就是容器包裝起來,這樣放置就可以避免很多因不規整而帶來的隱患。例如:Docker可以有效避免Java環境版本差異、不同應用相互影響、使用資源相互競爭等問題。

個推在使用Docker時,沿用了Docker鏡像的分層策略。首先,個推的各個產品線模塊,使用的是各自的基礎鏡像。其次,個推各產品線的服務程序,打在了各自的基礎鏡像層之上,這樣操作能確保各個容器的運行環境互不沖突。

技術分享圖片

◎Kubernetes

Kubernetes是一個用於容器集群的自動化部署、擴容以及運維的開源平臺。Kubernetes的理念在於指點每個集裝箱的擺放,降低服務器資源難度,讓運維管理變得更加簡便。

個推選擇Kubernetes作為Docker容器編排的工具,主要有兩方面的考量。

一、個推遇到的問題:
版本更新叠代快
應用進程多,服務器資源消耗大
服務器環境不統一
需要推進DevOps

二、Kubernetes的優勢:
運維自動化
應用容器一次性構建
計算機硬件資源能夠充分利用
編排管理具有突出優勢

在應用Docker和Kubernetes的過程中,個推受益良多,同時也為個推原有的分布式系統結構帶來一些壓力。例如:個推系統的原有框架及模塊都需要改動適配;原有系統非常龐大,需要逐步進行遷移;對原有的生態服務必須有所取舍。因此,我們通過一次落地的容器化實踐來探索這個領域。

個推容器化實踐

在個推的某項目中,我們進行了一次全程的容器化實踐。

在具體實施前,我們先確定整體的架構圖,架構圖包含Kubernetes基本的一些結構。例如:在Master節點部署上,APIserver是整個系統的控制入口,Scheduler負責任務調度、命令下發,Controller Manager則作為集群內部的管理控制中心;在Node節點部署上,Kubelet作為Agent監聽執行該節點的任務,匯報該節點的狀態,而Proxy則負責整個網絡規則的連接與轉發。

當具體實踐時,有狀態組件怎樣才能成功部署,內外網如何實現互通,需要怎樣的配置中心,監控怎麽做,都是開發者容易遇到的問題。

◎有狀態組件的部署

在Kubernetes中,存在很多無狀態組件,它們對於Pod的管理都是基於無狀態、一次性的理念。如Replication Controller,它只是簡單地保證可提供服務的Pod數量。如果一個Pod被認定為非健康 的狀態,那麽Kubernetes就會以非常簡單粗暴的態度對待這個Pod:刪掉、重建、自動擴縮容。這種處理方式通常適用於業務邏輯處理和內存計算型程序。

但是, Kubernetes可以通過StatefulSet的方式,給Pod提供唯一的標誌,從而保證ZooKeeper、MySQL、Redis等有狀態組件的成功部署和有序擴展。

但在系統中,如果要滿足服務的Pod無論被置於何處,數據都要落地到同一目錄的要求,當有狀態組件被放置到容器中時,掛載就肯定需要經過網絡。然而,使用網絡卷進行掛載沒有本地掛載可靠,網絡的性能損耗也是高於本地的幾十倍上百倍。同時,這種組件的維護操作並不頻繁,沒有為運維帶來太多便利。因此,經過綜合考慮,個推沒有將這類有狀態組件放到容器中。

◎內外網絡的互通

內外網絡的互通是容器化過程中容易遇到的典型問題。個推使用calico進行虛擬地址的分配,所以同個集群內的網絡可以實現互通。集群內的服務訪問外部的時候,可以直接使用真實的物理地址。集群外的服務訪問內部的時候,需要通過iproute的方式,將虛擬ip映射到真實ip,才能實現內部服務的訪問。

◎配置中心

關於配置中心,可以先整理羅列一些需求點,標出重點後逐個去解決。個推此次容器化實踐過程中重點關註的需求點包括配置中心集群化,提供WEB界面化管理和權限管理,支持多種環境配置,開發集成簡單,本地有備份等。

在對一系列開源配置中心進行調研後,通過對比QConf、diamond、Xdiamond、disconf、Apollo、mconf以及xxl-conf的各項功能,個推選擇了功能更加齊全的Apollo。

技術分享圖片

(註釋:調研具有時效性,圖中某些配置中心的最新版本,現在可能已經支持當時還未支持的功能)

◎監控采集

運行在Kubernetes裏的應用程序,容易產生如網絡同外部隔離、生存周期受集群管理、運行節點不固定等問題。我們通過對自有的監控系統進行一些調整,比如將主服務部署在Kubernetes集群外部,在集群每個Pod裏面部署Agent,從而實現數據的采集監控並匯報主服務。

容器化的後續展望

最後,個推希望在吸取本次經驗的同時,對未來的容器化實踐有所規劃與展望。例如,我們可以考慮從業務監控和擴縮容結合、自動化測試、Stateful服務等方面繼續深入探索。

業務監控和擴縮容結合,能識別出假死,判斷出業務壓力。自動化測試,通過補充各個業務和模塊的自動化測例,便能在很大程度上節省回歸測試的成本,更好地實現快速叠代持續交付的目標,是DevOps進程中非常重要的一步。Stateful服務,後續隨著Kubernetes相關技術的發展,能夠幫助我們找到更多合適的容器化方式,從而做到完整的容器化,甚至是雲服務化。

結語:

現階段容器化大行其道,容器化在控制成本、保障服務穩定性、提高工作效率上都有極大的優勢,然而傳統分布式架構卻往往因其基礎組件和架構的定型,增加了容器化轉型的難度,導致船大難掉頭。本文希望通過作者的分享,能夠幫助開發者在容器化過程中更好地理清自己的思路。

需要註意的是,容器化實踐並不是為容器化而容器化,而是在充分理解現有業務需求和解決方案的基礎上,通過容器化提供更高效、更穩定的系統服務,這才是容器化真正的價值所在。

【容器化思維】傳統分布式架構容器化的實踐和挑戰