進入2016年以后,容器技術早已經從最初的牛逼滿天飛到了腳踏實地的大規模鋪開。很多企業都已經在實際項目中或深或淺的使用著容器技術,享受到新技術帶來的簡潔和高效。作為國內最早研究和使用Docker技術的企業,ThoughtWorks在2013年底就在實際項目中將Docker用于測試環境的資源復用,并在之后的許多項目中逐漸總結出許多有用的實踐和經驗。在這篇文章里,我將聊聊Docker在我經歷過項目中的一些比較有代表性的運用場景。
現實中的容器技術運用方式非常廣泛而靈活,時常讓人覺得腦洞大開,概括來說是『可小可大,可遠可近』。下面用四個案例來闡示容器在非特定領域里的運用場景。
容器之小:小而美的容器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相關的關鍵詞同樣占據了大量版面。在越來越多的技術領域里,無論是移動設備、
物聯網、大數據,都能看到容器技術各種形式的延伸,作為現實容器運用的一道縮影,此文可作為窺斑見豹、拋磚引玉之用。
核心關注:拓步ERP系統平臺是覆蓋了眾多的業務領域、行業應用,蘊涵了豐富的ERP管理思想,集成了ERP軟件業務管理理念,功能涉及供應鏈、成本、制造、CRM、HR等眾多業務領域的管理,全面涵蓋了企業關注ERP管理系統的核心領域,是眾多中小企業信息化建設首選的ERP管理軟件信賴品牌。
轉載請注明出處:拓步ERP資訊網http://www.guhuozai8.cn/
本文標題:現實中的容器技術運用案例
本文網址:http://www.guhuozai8.cn/html/support/11121819995.html