實戰訓練營:傳統分散式架構如何進行容器化升級

HitTwice發表於2018-07-05

前言:隨著以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相關技術的發展,能夠幫助我們找到更多合適的容器化方式,從而做到完整的容器化,甚至是雲服務化。

結語:

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

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

作者:個推研發專家朱明智
原文連結:https://my.oschina.net/u/1782938/blog/1834160

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31473948/viewspace-2157400/,如需轉載,請註明出處,否則將追究法律責任。

相關文章