DevOps轉型的動機
我們的客戶是一家海外本土最大的金融保險集團,他們在發展到一定規模以后,意識到自己就像一頭笨重的大象,舉步維艱,通過對整個交付流程的思考和分析,發現了以下一些嚴重影響交付速度的問題:
- 一些好的關于產品改善和創新的想法很難落地。涉及到一些遺留系統的配合:調整、部署、擴展等,使團隊對發布沒有信心。新的服務或者應用的構建,很難快速上線,被卡在了生產環境部署階段。
- 各種不同種類的應用、服務的部署方式和流程不一致。運維部門作為一個支持部門,很難為大量團隊提供快速反應。運維人員對于需要部署和運營環境之上的產品也不夠了
解。 - 微服務運營過程中,交付團隊難以做到快速集成和部署。運維團隊對微服務的部署運維方式不理解,依舊老瓶裝新藥,很難適配新架構下的交付模式。開發團隊大多關注代碼和架構,對于產品如何能在生產環境穩定運行、需要考慮哪些安全性和可持續性的因素并不是很了解。
問題分析和挑戰
通過對這些問題和各個團隊反饋的深入分析,發現其中最大的瓶頸在于交付團隊與運維部門之間的各種依賴和溝通浪費,而這個瓶頸又是解決大多數問題的前提。
我們將瓶頸具象化后(如圖上圖),可以看到兩種團隊之間其實是存在一堵墻的,一是因為傳統的部署流程非常繁瑣和低效。二是因為兩種角色關注點和目標的不一致。
如果在這樣的情況下,想實現微服務架構轉型,實現更快速和安全的交付,只會更快的暴露出這堵墻引起的各種問題。開發階段,系統的架構和依賴環境都是Developer說了算,對生產環境的關注度不高。部署、發布階段,Operations會考慮如何構建一套穩定的基礎設施,又如何去部署和運維開發的產物,但是往往對于產物的了解不充分,對于產物的周邊生態和與它們關系的了解也不夠。
那么引入DevOps文化,消除開發與運維之間的壁壘,逐步打造更高效的交付流程就成為我們破局的關鍵,那我們應該怎么做呢?
改革之初,我們發現并去嘗試了Bimodel(雙模IT), 我們看看它是否能解決我們的問題:
先簡單介紹一下什么是雙模IT:
它將IT系統分成了兩種模式:
- 一種是新型的數字化、高市場適應性的IT,這部分業務聚焦企業新市場和業務的開拓,創新和發展,強調IT自身對于市場的高適應力。
- 另外一種模式下,我們則需要穩固發展,對于傳統模式我們傾向于更加嚴謹和標準的流程去保護現有業務,穩定性比速度更加重要。
我們從采用這樣一種模式的實踐案例中發現:組織內部會出現連兩種速度的交付流程,好的情況可能是采用敏捷開發流程的交付線,有著快速的交付能力,相反,對于繼續采用傳統開發流程和運維方式的團隊,保持著穩定但低效的交付能力。
從業界很多公司的現狀和發展趨勢來看,雙模IT確實是很多組織存在的現狀或是必然經歷的過程,但不是一個好的模式,從實際的交付過程來看,存在4點問題:
- 雙模IT的劃分方式更多是基于軟件系統,而不是從業務活動出發進行的,所有軟件系統的交付都應該是面向業務價值的。
- 雙模IT會讓我們誤以為速度的提升會引起質量的下降,但是對于我們在ThoughtWorks的很多敏捷實踐中學到的:隨著交付的推進,質量內建是團隊共同負責和持續改進的重點。交付速度的提升,往往都伴隨著質量的保障,而不是忽視質量。
- 實際生產中,一個新的產品或者功能往往會依賴很多遺留系統提供的服務,如果它們僅僅只能達到穩定和低效的交付,對企業來說對市場整體的響應能力也會越來越低。
- 企業的創新不僅僅只是從零創造一個新的產品,還有很多機遇現有的資源。一個新的系統和功能往往不僅會既涉及到新服務、應用的創建,也會涉及到遺留系統的修改,調整和改造。
由此可見雙模IT是在以一種試圖掩蓋問題的方式來逃避目前最重要的問題:開發和運維之間的壁壘。感覺像是一個病人先是放棄治療,然后又努力的尋找延長壽命的方法,有些隱患終會爆發。
打造自服務持續交付
緊接著,我們開始采用了一種看似不可行的方式開啟了DevOps轉型,建立公有DevOps團隊。有很多人可能會說這是一種反模式,怎么可能會建立一個團隊專做DevOps相關的事情,那和以前的運維部門又有什么區別?DevOps提倡的Dev與Ops高頻度合作的文化是不是就無法大面積傳播了?
因此我們需要很明確的定義我們對這個團隊的期望和它的職責是什么,它是怎樣和交付團隊合作,影響交付團隊,最終能讓DevOps的文化可以大面積傳播。這個團隊的目標是要像杠桿一樣,翹起更大面積的DevOps變革。
所以我們認為公有DevOps團隊應該與其它的端到端交付團隊的人員構成是一樣的。不同的只是目標和價值,主要體現在幫助更多的團隊植入DevOps文化、優化持續交付流程。最終達到的目標是每個團隊都可以自治,每個團隊都可以進行端到端的開發、測試和部署,并可以自驅動的持續改進。與此同時,這個團隊不僅僅只是為交付團隊提供更多涉及基礎設施、持續交付流水線、部署等活動所需要的自動化能力,還會支撐交付團隊根據自身的上下文去定制和規劃自己的持續交付流程和部署策略等。
(圖片來自:http://t.cn/R9jnzHR)
現在,相比于DevOps團隊的叫法,我們更愿意稱呼這個團隊為Platform團隊,一個原因是我之前所說的避免被錯誤理解,另一個原因是隨著各個交付團隊逐步實現自服務持續交付,這個專有團隊也有了更高的目標:持續打造和優化一個能夠支持各交付團隊快速交付的平臺。
當時,我們首先為團隊定義了新的工作方式:以自服務,自動化和協作 作為核心文化,希望團隊通過提供便捷的基礎服務,讓交付團隊擁有自動化的交付流水線,并通過更多的溝通協作,盡可能讓每個交付團隊都能夠獨立自主的設計、創建和更改自己的基礎設施。然后再根據各個交付團隊的實施情況和結果來對流程和服務持續改進。
所以第一件事,我們首先設計了一個高效的持續交付流水線,讓Platform團隊和交付團隊建立觸點:
如下圖所示,藍色的基因鏈為交付團隊的持續交付環,紅色的基因鏈為平臺團隊的持續交付環。兩種團隊以某種低耦合的弱連接進行全程協作,Platform團隊在整個端到端的交付過程中都要能盡量通過構建自動化能力來支撐交付團隊能夠快速、安全的進行持續集成、部署等活動。這樣的合作方式也給我們提供了優化觸點的可能性,也能夠通過優化和改進,縮小這個持續交付周期,讓交付更高效。
實踐過程
下圖是我們為團隊設計的持續交付流水線,目的是能讓Platform團隊和交付團隊之間的觸點能夠被融入到持續交付流水線中,并且以基礎設施代碼作為協同媒介,通過自動化的方式實現開發與運維(即基礎設施與軟件系統)的無縫對接。
我們來看看我們給持續交付流水線賦予了哪些能力:
- 站在交付團隊的視角,我們決定將基礎設施構建,流水線構建,部署等活動都代碼化,與應用代碼放在同一個代碼倉庫中。
- 交付團隊通過提交我們的基礎設施代碼到倉庫后,自動觸發持續交付工具創建或更新流水線。
- 接著會自動觸發構建,靜態檢查,測試覆蓋率校測,代碼規范驗證等任務,最終輸出構建產物并將構建產物推送到倉庫。
- 然后會根據交付團隊對基礎設施和環境的定義到當前要部署的網絡環境中去創建或更改虛擬機、網絡、存儲方式等
- 最后,當基礎設施創建成功以后,就會去倉庫下載指定版本的構建產物進行最終的部署活動。
但需要注意的是:
- 為了持續優化交付流程,我們對開發的許多活動進行的數據收集和分析,以報表的形式去分析展示代碼提交頻率,系統和代碼的質量情況,缺陷和構建情況等,幫助團隊找到自己的瓶頸或問題。
- 幫助團隊能夠實時監控自己應用的運行狀態,設計和查看不同緯度的日志總匯等。
那我們來看看通過什么技術可以實現這樣的持續交付流程:
我們選擇了一種輕量級、低耦合的技術組合Ansible+Jenkins+AWS。我認為其核心是Ansible。
下面我們來看看Ansible可以幫助我們做些什么:
- 創建和更改AWS中的資源
- 自動化部署和基礎設施測試
- 建立開發與平臺團隊之間的溝通體系
考慮到基于yaml語法的Ansible配置簡潔且易讀,所以我們選擇直接用它作為提供給交付團隊的公有DSL模板,利用Ansible Playbook的模塊化思想將開發團隊的職責和平臺團隊的職責很清晰的分離,平臺團隊關注Ansible提供給交付團隊的服務是否滿足需求和DSL模板是否易用,而交付團隊只用關注如何基于公有DSL去定制自己的基礎設施,環境依賴和部署等。
于此同時也滿足了很多開發對于Ansible和AWS的興趣和熱情,更使得之后在交付團隊落地變得更容易。
接下來通過一個實例來看看:
左邊是Platform團隊的倉庫,這個倉庫里面包含了創建基礎設施、環境配置和部署的實現。
右邊是交付團隊的倉庫,其中deployment目錄下,是公有的DSL模板,其中包含多種環境(開發、測試、預生產環境等的獨立配置),以及一套基于DSL的代碼模板,其中包含創建基礎設施和部署應用這兩部分DSL代碼模板。
接下來,我們來看看它們配合與集成的方式:
他們會在持續集成流水線中被動態組合到一起:
- 在創建基礎設施和部署的時候會分別拉取基礎設施代碼庫和應用代碼庫。
- 此時應用代碼為調用入庫,公有基礎設施為功能框架庫,兩者配合,完成環境的創建和應用部署。
在做微服務的團隊,接受度非常高,能夠快速上手,而且甚至有團隊因為自身的一些需求,自己去寫一些Ansible模塊,然后向我們發起pull request。
當然,我們在推廣這套流程的過程中發現,一些實踐能夠幫助我們更快速落地:
- DevOps團隊的成員由各交付團隊和原運維團隊組成,這樣的組成方式,能夠保證團隊的視角可以關注到整個持續交付過程的每個環節。
- 交付團隊成員與DevOps團隊成員定期輪崗制,DevOps小組中的文化(如自動化優先)可以蔓延開,讓交付團隊更快適應。
- 結對、Showcase和培訓,主要目的是知識的傳遞,讓更多地團隊逐步采用新的交付模式,得到更多改進中的反饋。
- 提供給交付團隊的自服務代碼倉庫對每個人開放,交付團隊被授權優化、新增基礎設施,讓DevOps文化和職責落地到交付流程中。
現在來看,集中式、審批式、被動響應請求的中央運維團隊不再是整個交付流程中的依賴和瓶頸,已基本轉向帶自服務化、審查式、主動優化的去中心化交付團隊:
我們通過技術驅動改進,讓團隊之間的合作方式發生了巨大改變,開發與運維之間的那道墻也漸漸消失,以前被動響應請求中央運維團隊逐步被平臺團隊所替代,平臺團隊中一部分人會負責基礎設施平臺的發展,負責公有云與企業內部系統的對接、完善安全、災備、提供基礎設施的自服務機制,另一部分人會為產品團隊提供可定制的工作、平臺、并為產品團隊賦能。這時交付團隊開始管理自己的環境、維護流水線、負責生產環境變更。
在推廣和落地自服務持續交付流程的過程中,我們也遇到了很多遺留系統和復雜部署應用的交付團隊,他們無法直接對接這套交付流程。
例如有一個40-50人的團隊,它是基于AEM開發整個公司所有的前端門戶,AEM是Adobe公司的CMS系統,其安裝和部署很復雜,以前都是通過手工安裝和拷貝的方式進行部署,而且他們在開發-》測試-》部署階段可能會動態擴張多套環境來支持,且每次代碼變更的提交都會對已經安裝的AEM進行修改、配置、重啟等操作。
整個開發和測試流程都很復雜,而且效率很低,出現問題和故障的風險也很大,如果我們直接利用Ansible把AEM的安裝和部署過程都自動化,由于AEM本身部署的復雜性,可以預見以后這部分更新和維護的工作還是很難交由交付團隊自治。所以我們第一步要做的就是為其設計新的持續交付流水線,然后在這個流程中去定義和識別兩個團隊的職責和關注重心,最后再通過打造高效的自服務使整個交付流程得到改進。
首先我們根據校服團隊提交變更的平率,從低到高依次定義了三條持續集成流水線(如下圖):
- 創建和測試基礎設施資源
- 配置基礎設施資源和環境
- 部署應用程
因為AEM安裝和更新很復雜,所以我們引入了鏡像技術。基礎設施和基礎設施配置兩條流水線的產物為一個image,應用流水線在部署階段會去檢查是否存在新的環境鏡像,如果存在,就會基于快速創建一個新的AEM環境,然后進行應用代碼的部署。
通過新的自動化持續交付流水線大大加速了AEM團隊的開發和測試速度,也使得整個環境更加可控和易維護。對于交付團隊來說,他們可以自己去維護包括基礎設施、環境變更和應用部署等全生命周期交付活動。對于Platform團隊來說,只用去考慮鏡像的生命周期管理,如何去優化鏡像的創建速度等,這些可以幫助到更多其它團隊解決類似問題的領域。對于這種特殊情況,我們盡管引入很多與大多數團隊不同的交付流程和技術,但所有的工作和優化都是基于之前打造的自服務持續交付流程、協議和工具平臺之上的,保證了不同的交付團隊與Platform的配合方式的一致性。
實踐啟示
通過在大量交付團隊落地基于自服務的持續交付流程,兩種團隊的職責更加清晰了:
所有好的實踐都必須考慮規模化的問題,如果無法大規模的被接受和落地,再好的實踐也沒用。對于咱們這個轉型的過程,我也給出一個套路:(如下圖)
有了套路,接下來總結一下應用這個套路進行DevOps轉型過程中的一些經驗和思考:
- 易用的通用DSL模板設計,提供交付與Platform團隊統一的DSL模板(build and update anything)。
- 構建通用持續交付流水框架,提供給交付團隊定制化流水線的能力,使流水線主要關注點始終在產品的成功交付。
- 以技術驅動DevOps文化大面積傳播,讓Platform團隊成員走入交付團隊,協作改進、知識傳遞,確保實踐落地。
- 將一切自動化、自服務化。交付團隊應該被授權優化、新增基礎設施服務,讓DevOps能力和職責在交付團隊落地生根。
最后,我提取了5點對我們來說非常重要的策略或是推進方法:
- 小步快跑,在有大方向的基礎上,需要將每一步改變都設計得足夠小,這樣才能足夠快的去改進。
- 交付團隊賦能,給每個人都留一扇門,在他意識到要做些事情的時候,可以很快付諸行動。
- 逐步用基礎設施自服務化替代運維部門的審批流程。
建立持續反饋和改進機制。 - 以DevOps團隊為杠桿,撬動更大范圍自服務交付。