現實中的容器技術運用案例

進入2016年之後,容器技術早已經從最初的牛逼滿天飛到了腳踏實地的大規模鋪開。不少企業都已經在實際項目中或深或淺的使用着容器技術,享受到新技術帶來的簡潔和高效。做爲國內最先研究和使用Docker技術的企業,ThoughtWorks在2013年末就在實際項目中將Docker用於測試環境的資源複用,並在以後的許多項目中逐漸總結出許多有用的實踐和經驗。在這篇文章裏,我將聊聊Docker在我經歷過項目中的一些比較有表明性的運用場景。node

現實中的容器技術運用方式很是普遍而靈活,時常讓人以爲腦洞大開,歸納來講是『可小可大,可遠可近』。下面用四個案例來闡示容器在非特定領域裏的運用場景。程序員

容器之小:小而美的容器DevOps架構棧數據庫


圖1基於容器和DevOps理念的運維架構瀏覽器

這張架構圖來自於一個規模不到20人的小型產品團隊,團隊的結構十分精巧,由兩名開發人員兼任主要的運維工做。這兩位開發人員,花了幾周時間經過Ansible陸陸續續搭建起了這套由上百個服務器節點組成的集羣,並由團隊全部開發人員共同維護。總體套集羣系統高度自動化,使得團隊的每一個人都可以十分快速而安全的完成業務功能的部署、獲取線上業務的運行情況、以及對出現問題的故障點進行快速的日誌錯誤定位。安全

麻雀雖小,五臟俱全。這套技術方案包含了集羣管理、網絡管理、服務發現、日誌管理、性能監控等許多方面的設計,從架構的角度上看,已經儼然是一個小型私有PaaS平臺。服務器

Swarm做爲集羣的管理工具,具備與Docker原生命令良好的一致性,在學習曲線比較緩和,在DevOps文化比較好的團隊中很容易讓開發人員快速上手。在這個架構方案中使用了Consul做爲集羣元數據存儲的方案,Swarm的主、從節點信息以及Docker的跨節點網絡劃分的信息都存放在這裏。Consul除了做爲集羣信息的存儲,還能夠用於應用服務的配置存儲和服務發現,以及做爲內網的DNS服務使用。不過出於安全性和可維護性的考慮,應該爲應用服務單獨搭建獨立的Consul節點,與存儲集羣配置的Consul分開,防止因爲數據干擾和意外修改引發大規模系統故障。網絡

使用Swarm的另外一個潛在好處是它可以充分利用Docker內置的跨節點網絡功能,這套基於VxLAN的SDN實現十分簡潔易用,通訊效率也很不錯。架構

容器集羣的的性能監控和日誌管理是使得這個小團隊得以駕馭比團隊人數更多的服務節點的關鍵要素,任憑運行的服務在機器漫漫海洋中隨意穿行,這兩件工具就是開發人員的羅盤和風向標,在關鍵時候爲線上故障的定位爭取寶貴時間,並能從中迅速找到每一個服務當前運行的節點,從而採起必要的應急措施。cAdvisor+Influxdb+Grafana是一套爲容器集羣性能監控設計的開源解決方案,利用cAdvisor對容器信息的良好監控能力,Influxdb對時間序列數據的快速檢索能力,以及Grafana的強大圖表展現能力,造成性能數據的實時查看和歷史回溯,並反饋到開發和運營的狀態報表,造成完整閉環。不過,這個開源組合的缺陷在於缺少現成的事件告警組件,在Influxdata公司的Telegraf項目逐漸成熟後,能夠考慮使用它替代cAdvisor的功能,而後集成Kapacitor做爲告警模塊,提早預知服務的不正常狀態。日誌管理方面,這套系統使用了當下最主流的容器日誌開源工具組合Fluentd+EslasticSearch+Kibana,在《程序員》2016年6月刊『容器的性能監控和日誌管理』一文中已經對這個組合進行過比較深刻的探討。框架

這是Docker集羣化實踐中運用得比較出色的一個案例,特別是對中小型產品團隊,會有很多可借鑑和啓發之處。在不用增長額外運維人員的狀況下,這套系統能夠比較輕鬆的擴容至幾百上千的規模。然而,這個架構自己並無考慮譬如多數據中心、租戶隔離、訪問受權、資源配額等複雜情景,它主要的設計初衷在於解決集羣易用性的問題。試想在過去使用虛擬機管理服務的時代,讓只有幾我的的團隊去維護上千個計算節點上運行的須要各類不一樣環境和配置的服務,這簡直是不可完成的任務,然而經過容器化的部署、DevOps思惟的團隊、加上適當的集羣輔助工具,他們作到了。運維

容器之大:大型任務集羣的容器化調度


圖2基於容器的多數據中心任務平臺架構

並非全部的團隊都願意從頭構建本身的整套運維架構和基礎設施環境。在許多企業裏,服務的運維管理是有專門的組織負責的。這些組織可能叫作平臺部門、運維部門、或者環境支持部門,不論稱呼如何,這些組織以及部門一般都須要管理數量至關龐大的計算資源。這些資源多是跨機房,跨城市,甚至是分佈在歐洲、美洲、非洲而且相互沒法直接通訊的數據中內心。他們所須要調度的做業數量和種類也遠遠超過一個自運維產品團隊所須要考慮的規模。

爲這樣的組織設計基於容器的任務調度平臺須要對企業的需求和特定業務領域有充分的瞭解,越是大型的基礎設施集羣,所須要應對的風險和不肯定也越大,設計一個面面俱到的通用大型集羣也越困難。所以針對具體業務場景作出必定的取捨是不得已、但又是必要的。例如爲了得到較高的響應速度而將集羣劃分爲多個互不重疊的調度區域,於是限制了每一個區域的容量;爲了不內網數據網絡風暴而將節點數據分層處理並逐級減小數據彙總的維度,於是增長監控管理複雜度;或者爲了增長系統規模而採用高度聚合而不適合多數據中心的方案。這些方案每每不須要具有普適性,而是會針對特定企業和業務場景進行恰到好處的修剪和優化。

上面圖中展現的是一個企業PaaS服務平臺的結構,架構基於Kubernetes集羣,須要應用在多個異地數據中心,並在統一的部署系統上對服務進行管理。因爲單Kubernetes集羣容量有限,這個方案實際上根據地域劃分和租戶的規模構建了多個幾十到上千節點不等的子集羣,集羣直接互不重合,屬於同一個任務組的服務只會在特定的某個集羣內進行部署和調度,其實就是將集羣和租戶進行了綁定。在全部集羣之上,經過自研的一個任務分發服務做爲全部調度任務的入口,在這裏處理服務的依賴關係、所屬區域、以及其餘元數據信息,而後調用Kubernetes的API完成任務的部署和調度,並經過額外的組件處理網絡、存儲等資源的配置。

在圖中省略了系統採用的其餘自研模塊,值得一提的是這個系統的性能數據管理使用了開源的Promethus軟件。Promethus是SoundCloud公司維護的一款包含信息採集、處理、分析、展現和告警的性能監控總體解決方案,它提供了比較靈活的多數據中心級聯能力和集中式的配置管理功能,所以特別適合規模較大的計算集羣。不一樣於前一案例中Influxdb方案每一個數據採集節點發數據給存儲數據的中心節點的方式,Promethus的性能數據採集是由中心服務器主動向全部節點定時輪詢的方式拉取的,所以全部與數據採集相關的配置所有在中心服務器上進行修改便可。而節點的數量和IP地址變更則經過服務發現機制來告知中心服務器,這大大簡化了修改數據收集參數的流程。

這個案例是一個比較典型的大規模容器集羣,在大型容器集羣方面許多企業都有着本身的實踐沉澱。其中有兩個比較明顯的特色是從業務場景制定架構和系統中包含許多自研的組件,所以在借鑑的時候更須要普遍的收集信息,避免盲目照搬。

容器之遠:基於容器的持續集成實踐


圖3基於容器的持續交付流水線示意

接下來,讓咱們用廣角鏡頭來審視一下軟件發佈的生命週期。經過持續交付的流水線,咱們可以清晰的定義出軟件從代碼提交到上線發佈以前所須要通過的每一個環節,協助開發者發現工做流程中存在的瓶頸,並促使團隊提高端到端的自動化程度,縮短獨立功能上線的週期。

那麼容器在其中能扮演什麼樣的角色呢?首先是資源的隔離,爲了確保每一次編譯和測試的獨立性,軟件應該在乾淨的環境中分別進行構建、打包、並運行測試用例,而容器是很是合適用來提供這種虛擬環境的輕量級工具。其次是一致的軟件打包方式,Docker的封裝意味着不論運行的服務是用Java、Python、PHP仍是Scala、Golang,平臺能夠用幾乎相同的方式去完成部署,而不用考慮安裝服務所需的環境,這些都在軟件開發的時候就已經準備好了。最後是成熟的調度平臺。基於容器有許多現成的任務調度框架,也正是因爲前兩個角色,容器使得任務的分發變得容易,因爲應用不須要依賴主機的配置,這就讓任務的靈活調度成爲可能。

基於容器的持續交付流水線和普通交付流水線很類似,包含構建、打包、測試、部署等環節。同時這其中也有許多技巧和專用於容器的優化手段。這個案例中咱們選取其中兩個比較具備啓發性的來講。

第一個例子是關於容器構建的優化。容器的構建一般都是由某個基礎鏡像開始,經過Dockerfile的描述自動化逐步執行,直至完成預期的狀態。幾乎全部項目的Dockerfile都不會每次從一個原始的Ubuntu或者CentOS的鏡像作爲基礎,從頭構建整個運行環境,由於那樣會使得每次構建花費很是長的時間。製做用於繼承的公共基礎鏡像是早已世人皆知的鏡像構建提速優化的方法,這樣可讓費時而又不常改變的步驟固定下來,每次構建時候就只須要基於這個鏡像再進行增量修改就能夠了。但這種方法其實也有潛在問題,那就是當咱們須要升級基礎鏡像的時候,不得不從新構建全部基於它製做的全部服務鏡像。

這個問題被稱爲『脆弱的基礎鏡像』,該問題的應對策略有不少。例如簡單的延遲子級鏡像的升級時間,直到每一個子鏡像下次從新構建發佈時天然會得到更新。又例如比較激進的方式,經過流水線創建鏡像的依賴關係,在父級鏡像一旦更新時,自動觸發全部子級鏡像的自動重建,這種方式要慎重採用,由於它極可能會致使同時產生大量的鏡像構建任務,對網絡和磁盤形成嚴重的壓力。那麼,有沒有在一種辦法既能得到具備時效性的更新,又不會產生短期內的構建風暴呢?其實對於一些場景是能夠有取巧方法的,經過Docker的外掛存儲能力,將常常可能變化的內容作成單獨的鏡像,而後利用Docker的『–volume-from』參數在服務啓動時覆蓋掉運行容器的特定目錄。典型的場景就是用於編譯其餘服務的容器,這些容器中通常都會有一些編譯服務時所需的時依賴庫,這些依賴庫隨着項目所需依賴的變化也要跟着變,像Maven的~/.m2/repository目錄,Node的全局node_module目錄等就很適合這樣管理。當這個目錄下面的內容須要更新時,只需從新構建提供目錄內容的一個鏡像,而不會產生鏡像構建的鏈式反應,服務下次啓動時候就會得到新的依賴庫目錄了。

第二個例子是流水線中的測試環節。進行自動化測試的時候,容器的優點發揮尤爲明顯。對於外部服務的依賴,好比與數據庫相關的測試,因爲測試過程須要反覆運行,過去時候,若是測試運行完沒有正確的清理留下的數據,特別容易影響後續測試的運行結果。容器偏偏是提供這種即用即棄基礎設施最佳的方式,徹底能夠在測試腳本中先啓動一個全新的MySQL服務,而後測試完就銷燬,保證了每次測試的獨立性。關於這方面的應用在下個案例中再介紹更多細節。

相似的技巧還有不少。持續交付流水線是最能體現容器在軟件領域帶來各方面改進的大觀園。許多現成的工具能夠最大化的避免手工操做對流程的干擾,讓軟件發佈開上高速公路。

容器之近:容器在自動化測試平臺的運用


圖4基於容器的自動化測試平臺架構

最後這個案例是一個針對軟件自動化測試環節的容器化基礎設施設計。它是軟件持續交付流水線上的一個重要環節,讓咱們帶上長焦鏡,近距離審視容器在軟件測試場景中能解決怎樣的問題。

容器快速啓動、快速銷燬的特性與軟件測試時所需的每次乾淨獨立的臨時運行環境十分匹配。使得在這方面容器能夠大有做爲。特別是在集成測試和功能性測試的階段,被測系統的運行每每會須要涉及多個要獨立運行的子組件或子模塊。還有外部模塊的依賴,若是進行的是界面相關的測試用例,每每還會用到Selenium和瀏覽器的組件。而運行數據庫相關的測試則會須要MySQL、Mongodb等組件。手工爲每一個測試用例準備並維護這些環節依賴是十分讓人抓狂的事情。過去作這類測試時候爲了解決依賴問題,一般作法是額外部署一套專用於測試依賴的環境,全部模塊測試須要別的模塊時都統一指向這套測試環境做爲目標。因爲過於頻繁的升級這個依賴環境可能會打斷正在運行的測試用例,所以只能對它進行按期的更新,這種無形中限制了的時效性和可靠性。

特別是一些比較重要而且耗時較短的迴歸測試和冒煙測試用例,理想狀況下應該在每次代碼提交後都全量的更新並執行,以便第一時間發現一些潛在的功能缺陷。但爲每次提交建立一套測試環境不管是手工操做仍是過去基於虛擬機的自動化方式都過於繁瑣。

案例中的測試平臺正是意圖經過容器和簡單的依賴描述,來解決測試環境管理的問題。它基於全部被測組件和所依賴的組件都使用Docker鏡像來提供的前提之上,將全部組件抽象成一致的模型寫成描述文件,描述文件的主要內容就是整個測試環境所需的鏡像和啓動順序。

示意圖中的『運行調度器模塊』是接入持續交付流水線的調用入口,能夠採用譬如Jenkins的形式插件實現,它用來建立和保存特定測試用例所需的環境描述文件內容。在流水線觸發該測試環節時,這個模塊調用『測試執行器模塊』,將描述模型用特定的結構體傳遞給後者,後者解析這個數據模型,轉化爲接近Kubernetes服務模型的形式,而後在『服務依賴管理模塊』的協助下,經過Kubernetes建立臨時的Namespace,並依次建立每一個服務。當測試環境就緒後,『測試執行器模塊』就開始執行測試用例,最後又經過『服務依賴管理模塊』通知Kubernetes銷燬整套環境。

整個過程對於平臺的用戶而言,僅僅是增長了一個測試環境描述的內容,寫在持續交付流水線測試步驟的定義(例如Jenkins插件配置)裏。而這套系統內部頗爲複雜的執行過程,可以有效的利用整個集羣的資源,恰到好處的爲測試的過程提供支持。

總結

這四個案例由淺入深、由遠及近的展示了容器在現代軟件和基礎設施設計中舉足輕重的做用。有些技術會直接改變人們的生活,而另外一些技術則會改變技術自己以及技術的發展方向,容器技術屬於後者。

隨着容器運用的普及,當下的主流媒體對容器周邊技術的關注還在持續升溫。不只是《程序員》推出了本期的容器技術專刊,在最新一期的ThoughtWorks公開刊物《技術雷達【1】》中,容器和Docker相關的關鍵詞一樣佔據了大量版面。在愈來愈多的技術領域裏,不管是移動設備、物聯網、大數據,都能看到容器技術各類形式的延伸,做爲現實容器運用的一道縮影,此文可做爲窺斑見豹、拋磚引玉之用。

參考連接:

【1】https://assets.thoughtworks.com/assets/technology-radar-apr-2016-cn.pdf

做者:林帆,ThoughtWorks公司DevOps技術諮詢師。熱衷於對DevOps和容器技術應用的推廣,在容器規模化運維方面有較豐富實踐經驗。

相關文章
相關標籤/搜索