天天看點

基于容器服務的持續內建與雲端傳遞(一)- 傳遞之禅

前言

随着微服務架構與容器虛拟化技術的發展,持續內建與持續傳遞的概念又重新回到了大家的視野,越來越多的公司開始使用持續內建的系統來解決頻繁釋出帶來的品質問題;使用持續傳遞的工具來實作代碼在不同環境上的自動部署。原本有些學院派烏托邦式的思想正被千千萬萬次的內建與部署證明着它應有的價值。那麼究竟是因為什麼讓持續內建與持續傳遞這個已經不再年輕的軟體開發與傳遞的思想重新煥發綻放迷人的光彩呢?

傳統軟體傳遞之殇

傳統軟體的開發與傳遞的周期都很漫長,一款普通的企業軟體通常需要十幾個開發人員,幾個月的時間來完成,從需求的分析、系統的設計、編寫測試用例、系統開發、單元測試、組裝測試到傳遞調試。有條不紊的流程與規範像一輛綠皮火車下的枕木,穩定而可靠的保證整個系統緩慢的推進,每一次傳遞、更新,都需要提供基礎的硬體、軟體的環境、軟體的代碼、軟體的文檔與手冊。還記得剛剛邁入軟體開發行業的時候,跟随公司的服務團隊,駐場傳遞産品,每一個駐場工程師都按照之前預演過好多遍的流程,對照着系統的部署手冊,一步一步的組裝硬體,安裝軟體,稍有差池,就要按照對應的應急預案進行復原。開始的時候覺得傳遞像一個神聖的儀式,将用智慧和汗水建構成的軟體傳遞給客戶使用,是一種非常榮耀和值得驕傲的事情;後來越來越多次的産品傳遞讓我深深的感覺每一次傳遞都像分娩一樣痛苦,扪心自問是否有簡單更舒暢的流程可以将軟體傳遞給客戶呢?

傳統模式的反思與ci/cd概念的提出

基于容器服務的持續內建與雲端傳遞(一)- 傳遞之禅

通常來講,一個軟體的生命周期分為問題的定義、可行性的分析、系統設計、系統編寫、系統測試與調試、系統部署與傳遞、維護與更新等步驟。在傳統軟體的生命周期中,更傾向于使用瀑布流的模式來去有條不紊的規範整個流程,每一個階段都期望遵循“活動-結果-稽核-再活動-直至正确”的流程來保證系統穩定。整個軟體的生命周期就變成了一個很長的二維線性的流程。這也制約了軟體的開發疊代與傳遞的速度,前輩們想了非常多的辦法來提高整體的開發速度,比如将一個單體的系統系統設計成為服務化的分布式的子系統,這樣可以讓一個大型的單體軟體的開發變成多個小的獨立系統的并行開發;使用元件化的方式組建系統,在不同的系統間複用子產品加速開發;通過自動化工具或者腳本進行自動化部署與傳遞等等。

誠然,這些都解決了軟體傳遞過程中的一些問題與難點,但是這些方式都像西醫一樣,治标不治本,因為要想快速的傳遞,首先要明白軟體傳遞過程中遇到的核心問題是什麼。總結成兩個詞“自動”與“可靠”。自動是一個很寬泛的詞彙,在軟體傳遞中代表着測試自動化、傳遞自動化、運維自動化等等,而可靠講的是每一次傳遞要保證是目前的傳遞是穩定的或可復原到穩定版本的。

為了解決“自動”與“可靠”的問題,靈活開發鼻祖martin fowler提出了持續內建與持續傳遞的概念,它所描述的軟體開發,是從原始需求識别到最終産品部署到生産環境這個過程中,需求以小批量形式在團隊的各個角色間順暢流動,能夠以較短地周期完成需求的小粒度頻繁傳遞。頻繁的傳遞周期帶來了更迅速的對軟體的回報,并且在這個過程中,需求分析、産品的使用者體驗和互動 設計、開發、測試、運維等角色密切協作,相比于傳統的瀑布式軟體團隊,更少浪費。通過這種小步快跑的方式,将小功能快速疊代、驗證、傳遞,通過自動化的工具,将測試、部署、運維自動化,減少需求在軟體生命周期中流動的時間。但是為什麼看上去可以奉為圭臬的持續內建與持續傳遞的思想卻在相當長的時間被開發者束之高閣呢?

實作持續內建持續傳遞的難點

對持續內建持續傳遞有一些了解與體會的開發者會經常看到類似下面這張圖的持續傳遞流程。

基于容器服務的持續內建與雲端傳遞(一)- 傳遞之禅

在這張圖中我們講述了一個持續內建與持續傳遞的流程,從代碼的送出、建構與編譯、單元測試到部署環境、內建測試與釋出。軟體傳遞本身就是一件複雜的事情,不同的産品、不同的架構、不同的業務形态會導緻持續內建與持續傳遞的實作上有非常大的不同。還記得很久以前流行一個關于哲學的笑話,當你問十個哲學家什麼是哲學的時候,你會得到十一種答案,因為每個人都有對哲學不同的了解。對于持續傳遞也一樣,martin fowler講述了一個烏托邦式的軟體開發與傳遞的模式-持續內建與持續傳遞,但是前輩隻給了我們先進的思想,并沒有給出預設的實作。不同的公司、不同的産品、不同的技術棧、不同的開發與部署形态決定了持續內建與持續傳遞注定是因人而異的,在大家不斷摸索什麼樣的方式是持續內建與持續傳遞的最佳實踐的過程中。有的人做少了,隻實踐了其中的一部分,導緻基本的傳遞能力上有缺欠;有的人做多了,引入了更多複雜的流程,導緻原本應該提速的傳遞流程,像穿着名牌高跟鞋參加跨欄一樣,怎麼也快不起來。

如果将上面的流程具象化一個lnmp(linux、nginx、mysql、php)的例子,就變成了如下的過程。

基于容器服務的持續內建與雲端傳遞(一)- 傳遞之禅

我們會發現當整個持續傳遞的流程流轉到了持續傳遞系統的時候,流程開始和具體的環境與程式設計架構開始耦合,比如單元測試在這個例子中需要運作phpunit相關的指令去實作;準備環境需要根據具體的部署環境是kvm的虛拟機還是實體機或者是雲伺服器差別實作;配置環境需要根據具體的程式設計模型來準備在本例中會通過自動化配管工具例如ansible來驗證與準備不同環境中的代碼運作時環境;分發代碼後的流程在本例中是通過重新開機nginx實作。其實這就是持續內建與持續傳遞真正難的部分,它并沒有特定的要求規定什麼流程該用什麼方式做什麼,就像大型軟體系統的架構設計,隻有“法”沒有“型”,這也就是為什麼程式員有很多,但架構師少的可憐的道理。

歸根結底,持續內建與持續傳遞的難點在于如何屏蔽不同語言、不同架構、不同系統之間的持續內建與持續傳遞流程的差異性。曾經幻想過是否能有一種方式可以歸約軟體的傳遞,而這就是martin fowler留給我們的課後思考題-論如何實作持續內建與持續傳遞的流程标準化。

新的傳遞之道——容器标準化傳遞

容器虛拟化這幾年随着docker的推出,也逐漸進入到開發者的視野中。剛剛接觸docker的時候,按照學習新知識的習慣,我将docker和虛拟機或者虛拟化進行了等同,認為他們是一個領域的不同實作,通過類比的方式來學習docker。但是後來我發現,docker的意義不在于解決軟體底層的環境定義的問題,更多的是在解決傳遞的問題。

在上文中我們讨論了為什麼持續內建與持續傳遞對于很多公司來講是有難度的。而解決這個問題的最理想的辦法就是是否有一種方式可以将傳遞的流程程式設計一個标準化,這樣進行持續內建與持續傳遞的開發者可以很快的像讀說明書一樣,一步一步完成自己的持續內建與持續傳遞流程。

容器給傳遞帶來最大的變革就是标準化。

dockerfile:将代碼和環境打包成了鏡像,将原來系統中分發的最小單元由代碼變成了鏡像,不同的環境、不同的軟體、不同的配置都可以通過dockerfile的配置來實作,标準化了傳遞的最小單元,讓傳遞的最小單元不再和環境、程式設計架構耦合。

docker api:将軟體的生命周期管理從原來的不同架構不同實作變成了統一标準的指令。啟動軟體變成了docker run,停止軟體變成了docker stop,重新開機軟體變成了docker restart。

docker compose:将軟體傳遞的方式進行了标準化,大型的軟體是由很多不同的部分組成的,而docker compose就是将軟體之間的關聯關系用标準話的方式進行了描述,并通過分發docker comopse的配置檔案即可将軟體進行傳遞。

基于容器服務的持續內建與雲端傳遞(一)- 傳遞之禅

如上圖,我們将剛才的例子用docker的方式進行推演,發現原本和程式設計架構或者環境耦合的部分現在通過docker進行了标準化,這樣不同語言不同架構不同業務場景的開發者就可以快速的時間自己的持續內建與持續傳遞了。

軟體定義傳遞時代已到來?

雲計算的興起,讓越來越多的it基礎設施變成虛拟的、軟體定義的,比如軟體定義存儲、軟體定義網絡等等。通過程式設計的方式可以将原本的it基礎設施進行建立、配置設定、管理,屏蔽掉了底層的硬體的異構。反過來看雲端傳遞的場景,是否可以變成軟體定義的。我們可以通過資源編排(例如阿裡雲的ros或者aws cloudformation)定義基礎的設施;可以通過docker軟體定義部署;雲資源和容器化的應用都可以用api的方式來實作軟體定義運維。

軟體定義基礎設施+軟體定義部署+軟體定義運維=軟體定義傳遞?這個問題留給大家更多的思考。

阿裡雲容器服務是阿裡雲2015年12月推出的基于容器的caas産品,內建了阿裡雲oss、ecs、slb、sls、vpc、rds等多款iaas雲産品的能力。容器的傳遞方式雖然給傳遞帶來了很多的便利,但是還遠遠不夠,阿裡雲容器服務為微服務、持續傳遞提供了大量雲傳遞的能力,可以讓docker的傳遞過程更順暢。在下一篇文章中,我們将讨論下阿裡雲容器服務提供了什麼樣的功能特性滿足大家的雲端傳遞場景。

個人簡介

莫源,阿裡雲進階研發工程師。在加入阿裡巴巴之前,先後在北京天方地圓科技有限公司、微軟亞洲研究院任職。現主要負責阿裡雲容器服務産品的底層服務發現系統、叢集管理系統的研發,從事容器的持續傳遞、持續內建的方案的設計與實作。在雲計算、分布式系統、圖像識别與虛拟現實方向有多年的開發經驗。