何為DevOps,知乎的漫畫
鏈接:https://www.zhihu.com/question/24413538/answer/308246508
來源:知乎
著作權歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權,非商業(yè)轉(zhuǎn)載請注明出處。
加班熬夜趕需求!暴怒吐血改需求!發(fā)布謹慎怕事故!技術“猿”就一定要承受“傷害”和吸引“仇恨”嗎?說了這么多年DevOps,到底是啥?
來,阿里云應用服務的技術、文藝"騷年"策劃了小漫畫,讓你秒懂DevOps!
真正的dev+ops有那些了?轉(zhuǎn)之前公司同事翻譯的文章,讓理解猛然一亮。
最近我閱讀了很多有關DevOps的文章,其中一些非常有趣,然而一些內(nèi)容也很欠考慮。貌似很多人越來越堅定地在DevOps與chef、puppet或Docker容器的熟練運用方面劃了等號。對此我有不同看法。DevOps的范疇遠遠超過puppet或Docker等工具。
這樣的看法甚至讓我感覺有些氣憤。DevOps在我看來極為重要,過去15年來,我一直在大型機構(gòu),主要是大型金融機構(gòu)中從事工程業(yè)務。DevOps是一種非常重要的方法論,該方法將解決一些最大型問題的基本原則和實踐恰如其分地融為一體,很好地解決了此類機構(gòu)的軟件開發(fā)項目中一種最令人感覺悲涼的失敗要素:開發(fā)者和運維人員之間的混亂之墻。
請不要誤會我的這種觀點,除了某些XP實踐,大部分此類大型機構(gòu)對敏捷開發(fā)方法論的運用還有很長的路要走,同時還有很多其他原因會導致軟件開發(fā)項目的失敗或延誤。
但在我看來,混亂之墻目前依然是他們所面臨的最令人沮喪、最浪費時間、同時也相當愚蠢的問題。
與其獨自生悶氣,我覺得不如說點更實在的東西,寫一篇盡可能精準的文章,向大家介紹DevOps到底是什么,能為我們帶來什么。長話短說,DevOps并不是某一套工具。DevOps是一種方法論,其中包含一系列基本原則和實踐,僅此而已。而所用的工具(或者說“工具鏈”吧,畢竟用于為這些實踐提供支持的工具集有著極高的擴展性)只是為了對這樣的實踐提供支持。
最終來說,這些工具本身并不重要。相比兩年前,目前的DevOps工具鏈已經(jīng)產(chǎn)生了翻天覆地的變化,可想而知,兩年后還會產(chǎn)生更大的差異。不過這并不重要。重要的是能夠合理地理解這些基本原則和實踐。
本文并不準備介紹某些工具鏈,甚至完全不會提到這些工具。網(wǎng)上討論DevOps工具鏈的文章已經(jīng)太多了。我想在本文中談談最基本的原則和實踐,它們的主要目的,畢竟這些才是對我而言最重要的。
DevOps是一種方法論,歸納總結(jié)了面臨獨一無二的機遇和強有力需求的網(wǎng)絡巨頭們,結(jié)合自身業(yè)務本質(zhì)構(gòu)思出全新工作方式的過程中所采用的實踐,而他們的業(yè)務需求也很直接:以史無前例的節(jié)奏對自己的系統(tǒng)進行演進,有時候可能還需要以天為單位對系統(tǒng)或業(yè)務進行擴展。
雖然DevOps對初創(chuàng)公司來說很明顯是不可或缺的,但我認為那些有著龐大的老式IT部門的大企業(yè)才是能從這些基本原則和實踐中獲得最大收益的。本文將試圖解釋得出這個結(jié)論的原因和實現(xiàn)方法。
本文的部分內(nèi)容已發(fā)布為Slideshare演示幻燈片,可在這里瀏覽:http://www.slideshare.net/JrmeKehrli/devops-explained-72091158
目錄
1. 簡介
1.1 管理信條
1.2 一個典型的IT組織
1.3 運維人員測挫敗感
1.4 基礎架構(gòu)自動化
1.5 DevOps:僅此一次,一顆神奇的銀子彈
2. 基礎架構(gòu)即代碼
2.1 概述
2.2 DevOps工具鏈
2.3 收益
3. 持續(xù)交付
3.1 從實踐中學習
3.2 自動化
3.3 更頻繁的部署
3.4 持續(xù)交付的前提需求
3.5 零停機部署
4. 協(xié)作
4.1 混亂之墻
4.2 軟件開發(fā)流程
4.3 共享工具
4.4 協(xié)同工作
5. 結(jié)論
1. 簡介
DevOps所關注的不是工具本身,也不是對chef或Docker的掌握程度。DevOps是一種方法論,是一系列可以幫助開發(fā)者和運維人員在實現(xiàn)各自目標(Goal)的前提下,向自己的客戶或用戶交付最大化價值及最高質(zhì)量成果的基本原則和實踐。
開發(fā)者和運維人員之間最大的問題在于:雖然都是企業(yè)中大型IT部門不可或缺的,但他們有著截然不同的目的(Objective)。
開發(fā)者和運維人員之間目的上的差異就叫做混亂之墻。下文會介紹這個概念的準確定義,以及為什么我認為這種狀況很嚴峻并且很糟糕。
DevOps是一種融合了一系列基本原則和實踐的方法論(并從這些實踐中派生出了各種工具),意在幫助這些人員向著一個統(tǒng)一的共同目的努力:盡可能為公司提供更多價值。
令人驚奇的是,這個問題竟然有一個非常簡單的“銀子彈”:讓生產(chǎn)端變得敏捷起來!
而這恰恰正是DevOps所要達成的唯一目標!
但在進一步討論這一點之前,首先需要談談其他幾件事。
1.1 管理信條
IT管理這場戰(zhàn)爭的原動力到底是什么?換句話說,在軟件開發(fā)項目中,管理工作首要的,以及最重要的目的是什么?
有什么想法嗎?
我來提供一個線索吧:在建立一家初創(chuàng)公司時,最重要的事情是什么?
當然是要加快上市時間(TTM)!
上市時間(即TTM)是指一件產(chǎn)品從最初的構(gòu)思到最終可供用戶使用或購買這一過程所需要的時間。對于產(chǎn)品很快會過時的行業(yè),TTM是一個非常重要的概念。
在軟件工程方面,所采用的方法、業(yè)務,以及具體技術幾乎每年都會變化,因而TTM就成了一個非常重要的KPI(關鍵績效指標)。
TTM通常也會被叫做前置時間(Lead Time)。
第一個問題在于,(很多人認為)在開發(fā)過程中TTM和產(chǎn)品質(zhì)量是兩個對立的屬性。在下文可以看到,改善質(zhì)量(進而提高穩(wěn)定性)是運維人員的目的,而開發(fā)者的目的在于降低前置時間(進而提高TTM)。
請容我來解釋一下。
IT組織或部門通常會通過兩個關鍵的KPI進行評估:軟件本身的質(zhì)量,因而需要盡可能減少缺陷的數(shù)量;此外還有TTM,因而需要將業(yè)務構(gòu)想(通常由業(yè)務用戶提供)變?yōu)樽罱K成果,并以盡可能快的速度提供給用戶或客戶。
這里的問題在于,大部分情況下這兩個截然不同的目的是由兩個不同團隊提供支持的:負責構(gòu)建軟件的開發(fā)者,以及負責運行軟件的運維人員。
1.2 一個典型的IT組織
在組織內(nèi)部負責管理重要IT部門的典型IT組織通常看起來是這樣的:
主要由于歷史的原因(大部分運維人員來自硬件和電信業(yè)務領域),運維人員和開發(fā)者分屬不同的組織結(jié)構(gòu)分支。開發(fā)者屬于研發(fā)部門,而運維人員大部分時候?qū)儆诨A架構(gòu)部門(或?qū)iT的運維部門)。
別忘了,他們有著不同的目的:
此外作為旁注,這兩個團隊有時候會使用不同的預算來運營。開發(fā)團隊使用構(gòu)建(Build)預算,運維團隊使用運營(Run)預算。不同的預算,對控制權越來越高的需求,以及企業(yè)IT成本的縮水,這些因素結(jié)合在一起會進一步放大兩個團隊各自目的的對立性。
(依本人愚見,時至今日,隨著人與人之間無時無刻隨時隨地進行的交互,以及由不同目的推動著企業(yè)和社會進行數(shù)字化轉(zhuǎn)型,IT預算方面古老的“規(guī)劃/構(gòu)建/運行”框架已經(jīng)不那么合理了,不過這又是另一回事了。)
1.3 運維人員測挫敗感
接下來看看運維人員,一起看看典型的運維團隊把大部分時間都花在哪里了:
生產(chǎn)團隊有將近一半(47%)的時間花在了與部署有關的工作中:
執(zhí)行實際的部署工作,或
修復與部署工作有關的問題
這樣的KPI其實相當瘋狂,但實際上我們早就應該采納。實際上早在40年前,計算機科學的“原始時代”就已涌現(xiàn)出運維團隊,當時計算機主要運用在工業(yè)界,運維人員需要手工運行大量命令來執(zhí)行自己的任務。為了履行職責,他們已經(jīng)習慣于按照清單運行各種各樣的命令或手工流程。
突然有一天他們終于意識到自己“總在做著相同的事情”,然而長達四十多年的工作過程中卻幾乎沒人考慮過變革。
考慮到這一點你會發(fā)現(xiàn),實在是太瘋狂了。平均來說,運維人員將近一半的時間都在處理與部署有關的任務!
為了改變這種狀況,必須考慮到兩個最關鍵的需求:
通過自動化部署將目前這種手工任務所需的時間減少31%。
通過產(chǎn)業(yè)化措施(類似于通過XP和敏捷實現(xiàn)的軟件開發(fā)產(chǎn)業(yè)化)將需要處理的與這些部署有關的問題減少16%。
1.4 基礎架構(gòu)自動化
在這方面也有一個相當富有啟發(fā)性的統(tǒng)計結(jié)果:
以手工操作的數(shù)量所表示的成功部署概率。
這些統(tǒng)計告訴我們:
只需手工運行5條命令的情況下,成功部署的概率就已跌至86%。
如需手工運行55條命令,成功部署的概率將跌至22%。
如需手工運行100條命令,成功部署的概率將趨近于0(僅2%)!
成功部署意味著軟件能夠按照預期在生產(chǎn)環(huán)境中運行。未能成功部署意味著有東西出錯,可能需要進行必要的分析才能了解部署過程中哪里出錯,是否需要應用某種補丁,或需要修改某些配置。
因此讓這一切實現(xiàn)自動化并不惜一切代價避免手工操作似乎是個好主意,對吧?
那么行業(yè)里這方面的現(xiàn)狀是怎樣的:
(來源:IT Ops & DevOps Productivity Report 2013 - Rebellabs?)
(說實話,這個統(tǒng)計信息比較老了,是2013年的結(jié)果,相信現(xiàn)在的結(jié)果會有所不同)
然而這也可以讓我們明確的知道,在基礎架構(gòu)自動化方面我們還有多遠的路要走,并且DevOps的基本原則和實踐依然是那么的重要。
網(wǎng)絡巨頭們當然會通過新的方法和實踐及時滿足自己的需求,他們早已開始構(gòu)建自己的工程業(yè)務,而正是他們所確立的實踐逐漸衍生出當今我們所熟悉的DevOps。
看看這些網(wǎng)絡巨頭們在這方面目前所處的位置吧,舉幾個例子:
Facebook有數(shù)千名開發(fā)和運維人員,成千上萬臺服務器。平均來說一位運維人員負責500臺服務器(還認為自動化是可選的嗎?)他們每天部署兩次(環(huán)式部署,Deployment ring的概念)。
Flickr每天部署10次。
Netflix明確針對失敗進行各種設計!他們的軟件按照設計從最底層即可容忍系統(tǒng)失敗,他們會在生產(chǎn)環(huán)境中進行全面的測試:每天通過隨機關閉虛擬機的方式在生產(chǎn)環(huán)境中執(zhí)行65000次失敗測試…… 并確保這種情況下一切依然可以正常工作。
他們這種做法秘密何在?
1.5 DevOps:僅此一次,一顆神奇的銀子彈
他們的秘密很簡單:將敏捷擴展至生產(chǎn)端:
DevOps的共存主要是為了擴展敏捷開發(fā)實踐,進一步完善軟件變更在構(gòu)建、驗證、部署、交付等階段中的流動,同時通過軟件應用程序的全面所有權予力跨職能團隊完成從設計到生產(chǎn)支持等各環(huán)節(jié)的工作。
DevOps鼓勵軟件開發(fā)者和IT運維人員之間所進行的溝通、協(xié)作、集成和自動化,借此有助于改善雙方在交付軟件過程中的速度和質(zhì)量。
DevOps團隊更側(cè)重于通過標準化開發(fā)環(huán)境和自動化交付流程改善交付工作的可預測性、效率、安全性,以及可維護性。理想情況下,DevOps可以為開發(fā)者提供更可控的生產(chǎn)環(huán)境,幫助他們更好地理解生產(chǎn)基礎架構(gòu)。
DevOps鼓勵團隊自主進行自己應用程序的構(gòu)建、驗證、交付和支持。
那么核心原則到底是什么?
下文將介紹最重要的三大基本原則。
2. 基礎架構(gòu)即代碼
人總會犯錯,因為人腦實在是不擅長處理重復性的任務,相比Shell腳本,人類的速度實在是太慢了。畢竟我們都是人類,因此有必要像處理代碼那樣考慮和處理有關基礎架構(gòu)的概念!
基礎架構(gòu)即代碼(IaC)是大部分通用DevOps實踐的前提要求,例如版本控制、代碼審閱、持續(xù)集成、自動化測試。這一概念涉及計算基礎架構(gòu)(容器、虛擬機、物理機、軟件安裝等)的管理和供應,以及通過機器可處理的定義文件或腳本對其進行的配置,交互式配置工具和手工命令的使用已經(jīng)不合時宜了。
這一原則對DevOps的重要性怎么強調(diào)都不為過,它可以真正將軟件開發(fā)相關的實踐應用給服務器和基礎架構(gòu)。
云計算使得復雜的IT部署可以繼續(xù)效仿傳統(tǒng)物理拓撲。我們可以相對輕松地對復雜虛擬網(wǎng)絡、存儲和服務器的構(gòu)建實現(xiàn)自動化。服務器環(huán)境的方方面面,上至基礎架構(gòu)下至操作系統(tǒng)設置,均可編碼并存儲至版本控制倉庫。
2.1 概述
以非常概括的方式來看,基礎架構(gòu)和運維所需實現(xiàn)的自動化程度可通過下圖這種架構(gòu)來表示:
上述架構(gòu)圖中作為示例的工具主要面向不同層的構(gòu)建工作,實際上DevOps工具鏈的作用遠不止如此。
我覺得在這里可以略微深入地談談DevOps的工具鏈了。
2.2 DevOps工具鏈
DevOps實際是一種文化上的變遷,代表了開發(fā)、運維、測試等環(huán)節(jié)之間的協(xié)作,因此DevOps工具是非常多種多樣的,甚至可以由多種工具組成一個完整的DevOps工具鏈。此類工具可以應用于一種或多種類別,并可體現(xiàn)出軟件開發(fā)和交付過程的不同階段:
編碼:代碼開發(fā)和審閱,版本控制工具、代碼合并工具
構(gòu)建:持續(xù)集成工具、構(gòu)建狀態(tài)統(tǒng)計工具
測試:通過測試和結(jié)果確定績效的工具
打包:成品倉庫、應用程序部署前暫存
發(fā)布:變更管理、發(fā)布審批、發(fā)布自動化
配置:基礎架構(gòu)配置和部署,基礎架構(gòu)即代碼工具
監(jiān)視:應用程序性能監(jiān)視、最終用戶體驗
雖然可用工具有很多,但其中一些環(huán)節(jié)是組織內(nèi)部應用DevOps工具鏈不可或缺的。
諸如Docker(容器化)、Jenkins(持續(xù)集成)、Puppet(基礎架構(gòu)構(gòu)建)、Vagrant(虛擬化平臺)等常用、廣泛使用的工具都是2016年的DevOps熱門工具。
基礎架構(gòu)組件的版本控制、持續(xù)集成和自動化測試
基礎架構(gòu)的版本控制能力(而非基礎架構(gòu)的構(gòu)建腳本或配置文件)及對其進行自動化測試的能力極其重要。
DevOps最終會將30年前軟件工程領域所采用的同一套XP實踐帶至生產(chǎn)端。
此外基礎架構(gòu)元素應該能向軟件交付物一樣進行持續(xù)集成。
2.3 收益
DevOps的收益有很多,包括但不限于:
可重復性與可靠性:時至今日,構(gòu)建生產(chǎn)用計算機只需要運行腳本或必要的puppet命令即可。通過恰當?shù)厥褂肈ocker容器或Vagrant虛擬機,只需運行一條命令即可配置好包含操作系統(tǒng)層以及所需軟件和配置的生產(chǎn)用計算機。當然,隨著各種變更或軟件開發(fā)、持續(xù)集成,并自動測試,這套構(gòu)建腳本或機制也會進行持續(xù)集成。
最終幸虧有了XP或敏捷,我們在軟件開發(fā)端所使用的同一套實踐也能讓運維端獲益。
生產(chǎn)力:一鍵部署,一鍵供應,一鍵創(chuàng)建新環(huán)境……整個生產(chǎn)環(huán)境可以通過一條命令或一鍵點擊的方式創(chuàng)建。這樣的一條命令也許會運行長達數(shù)小時,但在這過程中運維人員可以從事其他更有趣的工作,而無需等待一條命令執(zhí)行完畢后繼續(xù)輸入下一條命令,畢竟這樣的過程有時候可能需要花費幾天時間才能完成……
恢復時間!:一鍵點擊即可恢復生產(chǎn)環(huán)境,就是這么簡單。
確保基礎架構(gòu)的同質(zhì):徹底避免運維人員每次構(gòu)建環(huán)境或安裝軟件時最終獲得的結(jié)果與預期有所差異,這是確保基礎架構(gòu)絕對同質(zhì)(Homogeneous)并且可再現(xiàn)的唯一可行方法。以此為基礎,通過對腳本或Puppet配置文件使用版本控制機制,我們甚至可以重建出與上周、上個月,或軟件特定版本發(fā)布時完全一致的生產(chǎn)環(huán)境。
維持整齊劃一的標準:基礎架構(gòu)標準甚至可以不復存在,代碼本身就是標準。
讓開發(fā)者自行完成大部分工作:如果開發(fā)者自己突然可以在自己的基礎架構(gòu)上一鍵點擊重建生產(chǎn)環(huán)境,他們也就可以自行完成很多與生產(chǎn)環(huán)境有關的任務,例如更好地理解生產(chǎn)失敗,提供更恰當?shù)呐渲茫瑢崿F(xiàn)部署腳本等。
這只是我個人感覺IaC可提供的部分收益,相信還有很多其他收益。
3. 持續(xù)交付
持續(xù)交付是一種可以幫助團隊以更短的周期交付軟件的方法,該方法確保了團隊可以在任何時間發(fā)布出可靠的軟件。該方法意在以更快速度更高頻率進行軟件的構(gòu)建、測試和發(fā)布。
通過對生產(chǎn)環(huán)境中的應用程序進行更高頻次的增量更新,這種方法有助于降低交付變更過程中涉及的成本、時間和風險。足夠簡單直接并且可重復的部署流程對持續(xù)交付而言至關重要。
注意:持續(xù)交付 ≠ 持續(xù)部署?- 有時候很多人會把持續(xù)交付誤認為成持續(xù)部署。持續(xù)部署是指每個變更可以自動部署到生產(chǎn)環(huán)境。持續(xù)交付是指團隊確保每個變更可以部署至生產(chǎn)環(huán)境,但也許并不需要實際部署,這通常可能是出于業(yè)務方面的原因。只有成功實現(xiàn)持續(xù)交付的前提下,才能進行持續(xù)部署。
持續(xù)交付的主要想法在于:
部署越頻繁,對部署流程就會越熟悉,自動化機制就能獲得更好的結(jié)果。如果同一件事每天需要執(zhí)行3次,很快你將變的無比嫻熟,但很快也會因為日復一日解決同樣的問題而感到厭煩。
部署越頻繁,所部屬的變更集就越微不足道,而這些微不足道的內(nèi)容最有可能出錯,甚至可能導致丟失對整個變更集的控制力。
部署越頻繁,TTR(修復/解決所需時間)指標就會越出色,從業(yè)務用戶處獲得有關功能的各類反饋的速度越快,作出改進以便完美滿足對方需求的過程也會越簡單(這方面TTR與TTM其實非常相似)。
(來源:Ops Meta-Metrics: The Currency You Pay For Change?)
但持續(xù)交付并不僅僅是盡可能頻繁地構(gòu)建可發(fā)布、生產(chǎn)就緒版本的軟件產(chǎn)品那么簡單。持續(xù)交付包含3個關鍵實踐:
從實踐中學習
自動化
更頻繁的部署
3.1 從實踐中學習
持續(xù)交付的關鍵在于要能從實踐中學習。真理并不存在于開發(fā)團隊中,而在于業(yè)務用戶中。然而無論花多長時間,沒人能真正清楚地表達自己的想法,或者將自己的想法用清晰的文檔概括出來。也正是因此,敏捷方法論強調(diào)將功能提供給用戶,并不惜一切代價從用戶處獲得盡可能多的反饋。
持續(xù)交付與持續(xù)部署類似,需要盡可能減少前置時間,這也是盡快從用戶處獲得“真理”的關鍵。
但真理絕對不會來自正規(guī)形式的用戶反饋。我們絕不能盡信自己的用戶或寄希望于通過正規(guī)形式的反饋了解用戶。我們只能相信自己的度量。
癡迷于度量是精益創(chuàng)業(yè)(Lean Startup)活動中一個重要的概念,但這一概念對DevOps同樣重要。我們應該度量一切!確定最恰當?shù)亩攘恐笜丝梢宰寛F隊了解某種方法最終能否成功或失敗,了解怎樣做可以獲得更好的結(jié)果,以及哪些最成功的做法同時也蘊含著一定的風險。為了幫助團隊做出更明智的決策,在確定要衡量的指標時,一定要抱著“寧多勿少”的原則。
不需要“考慮”,只需要“知道”!“知道”的唯一方法就是度量,度量一切:響應時間、用戶思考時間、展示次數(shù)、API調(diào)用次數(shù)、點擊率等,但這些并非需要度量的全部。找出所有能讓你更進一步了解用戶對功能看法的度量指標,對所有這些指標進行度量!
這種方法可以表示為如下形式:
3.2 自動化
自動化已經(jīng)在上文2. 基礎架構(gòu)即代碼一節(jié)進行了討論。
在這里我想強調(diào)的是,在沒有將與基礎架構(gòu)有關的所有供應和任務實現(xiàn)妥善、全面的自動化之前,持續(xù)交付根本無從談起。
這一點很重要,因此有必要再重復一遍:環(huán)境的搭建和生產(chǎn)就緒版本軟件的部署只需要一鍵點擊,只需要運行一條命令,整個過程應該自動完成。否則根本無法設想能一天多次部署同一個軟件。
在下文的3.5 零停機部署一節(jié)中,還將介紹有助于自動化交付的其他重要技術。
3.3 更頻繁的部署
DevOps的信條在于:
“越是困難的事,需要更頻繁地進行!”
敏捷思維中,困難任務更要迎難而上,更頻繁地去做,這中想法非常重要。
自動化測試、重構(gòu)、數(shù)據(jù)庫遷移、面向客戶的產(chǎn)品規(guī)格、規(guī)劃、發(fā)布 - 所有這些活動都要盡可能頻繁地進行。
原因主要有三點:
首先,隨著要做的工作量逐漸增加,這些任務也會變的愈加困難,但如果能拆解為小塊,則會變的相對容易些。
以數(shù)據(jù)庫遷移為例:一些涉及大量表的大規(guī)模數(shù)據(jù)庫遷移工作很麻煩,容易出錯。但如果一次只遷移一部分,則可以相對較容易地成功完成整個遷移任務。此外還可以輕松地將多個小規(guī)模的遷移任務安排成一定的序列,在將一個艱難的大任務拆解為一系列容易實現(xiàn)的小目標后,處理起來就簡單多了。(這也是數(shù)據(jù)庫重構(gòu)的本質(zhì))
第二個原因在于反饋。大部分敏捷思維關注的是設置反饋環(huán)路,借此讓我們更快速地學習了解。反饋已經(jīng)是極限編程(Extreme Programming)中一個非常重要,蘊含巨大價值的概念。在諸如軟件開發(fā)等復雜流程中,我們需要更頻繁地檢查自己的最新進展,并進行必要的糾正。為此我們必須盡一切可能創(chuàng)建反饋環(huán)路,并提高反饋的頻率,這樣才能更快速地酌情做出調(diào)整。
第三個原因是實踐。對于任何活動,越頻繁地從事就越能獲得完善。實踐可以幫助我們理清整個流程,讓我們更熟悉代表有事情出錯的征兆。只要認真琢磨自己從事的工作,就能提煉出近一步完善所需的實踐。
對于軟件開發(fā),也有可能實現(xiàn)一定程度的自動化。一旦有人將某件事做了多次,就可以更容易地確定該如何進行自動化,更重要的是,這樣的人在對這些事情實現(xiàn)自動化方面將有更大的動機。此時自動化尤為重要,因為可以加快速度并降低出錯的概率。
那么這就產(chǎn)生了一個問題:使用DevOps方法時,該選擇怎樣的交付頻率?
這個問題沒有標準答案,而是取決于產(chǎn)品、團隊、市場、公司、用戶、運維需求等各種因素。
我認為最佳答案應該是:如果不能實現(xiàn)至少每兩周一次交付,或在沖刺階段結(jié)束時交付,那么連敏捷都談不上,DevOps又從何談起呢?
DevOps鼓勵我們盡可能頻繁的交付。在我看來,你需要對團隊進行培訓,讓他們能夠做到盡可能頻繁的交付。我在我的團隊中使用的一種較為可行的方法是在QA環(huán)境中每天交付兩次。交付過程是完全自動化的:每天兩次,中午和午夜各一次,計算機啟動起來,構(gòu)建軟件組件,運行集成測試,構(gòu)建并啟動虛擬機,部署軟件組件,對其進行配置,運行功能測試等。
3.4 持續(xù)交付的前提需求
在改為使用持續(xù)交付方式之前,需要滿足哪些要求?
我草擬的需求清單如下:
對軟件組件的開發(fā)和平臺的供應和設置進行持續(xù)集成。
TDD - 測試驅(qū)動的開發(fā)。這一點還有待商榷……但始終還是需要面對:TDD是目前唯一能通過單元測試對代碼和分支進行可接受程度覆蓋的方法(單元測試使得問題的修復過程比集成測試或功能測試容易很多)。
代碼審閱!至少要進行代碼審閱……如果能進行結(jié)對編程(Pair programming)當然就更好了。
軟件的持續(xù)審計 - 例如使用Sonar。
在生產(chǎn)級環(huán)境實現(xiàn)功能測試的自動化。
更強大的非功能測試自動化(性能、可用性等)。
獨立于目標環(huán)境的自動化打包和部署。
另外在管理重大功能和演進時,還需要具備健全的軟件開發(fā)實踐,例如零停機部署技術。
3.5 零停機部署
“零停機部署(ZDD)可在不中斷現(xiàn)有服務的情況下部署新版系統(tǒng)。”
通過ZDD方式部署應用程序時,可在確保用戶不會遭遇應用程序停機的前提下將新版應用引入生產(chǎn)環(huán)境。從用戶和公司的角度來看,這應該是最佳部署方式,因為可以在不造成任何中斷的情況下引入新功能并修復Bug。
下文將介紹4種技術:
功能開關(Feature Flipping)
摸黑啟動(Dark launch)
藍/綠部署(Blue/Green Deployment)
金絲雀發(fā)布(Canari release)
功能開關
功能開關可供我們在軟件運行過程中啟用/禁用相應的功能。這種技術其實非常容易理解和使用:為生產(chǎn)版本提供一個能徹底禁用某項功能的配置,并只在對應功能徹底完工可以正常工作后才將該屬性激活。
舉例來說,若要將某個應用程序內(nèi)的一個功能全局禁用或激活:
if Feature.isEnabled('new_awesome_feature')
? ? # Do something new, cool and awesome
else
? ? # Do old, same as always stuff
end
或者如果要真對具體用戶實現(xiàn)類似目的:
if Feature.isEnabled('new_awesome_feature', current_user)
? ? # Do something new, cool and awesome
else
? ? # Do old, same as always stuff
end
摸黑啟動
摸黑啟動的目的在于通過生產(chǎn)環(huán)境進行負載模擬!
在測試環(huán)境中,通常很難為軟件模擬出成百上千萬用戶規(guī)模的負載。
如果不進行切實的負載測試,就無法知道基礎架構(gòu)能否承受住最終面臨的壓力。
此時并不需要模擬負載,而是可以實際部署這樣的功能,然后看看在不影響可用性的前提下到底會發(fā)生什么。
Facebook將這種做法稱之為功能的“摸黑啟動”。
假設我們要將一個有5億用戶使用的靜態(tài)搜索字段變成一個包含自動補全功能的字段,借此讓用戶可以更快速獲得搜索結(jié)果。為該功能構(gòu)建一個Web服務,并且希望模擬所有用戶同時輸入文字,向該Web服務生成大量請求的場景。
此時即可通過摸黑啟動策略為現(xiàn)有表單添加一個隱藏的后臺進程,通過該進程將輸入的搜索關鍵字發(fā)送給新增的自動補全服務,并自動發(fā)送多次。
就算新增的Web服務徹底崩潰了,也不會造成任何實質(zhì)損害。網(wǎng)頁上可以完全忽略服務器錯誤。而就算該服務崩潰了,我們至少還可以對該服務進行優(yōu)化和完善,直到能承受如此大量的負載。
這就等于在現(xiàn)實世界中進行了一次負載測試。
藍/綠部署
藍/綠部署是指為下一版產(chǎn)品構(gòu)建另一個完整的生產(chǎn)環(huán)境。開發(fā)和運維團隊可以在這個單獨的生產(chǎn)環(huán)境中放心地構(gòu)建下一版產(chǎn)品。
當下一版產(chǎn)品全部完成后,可以修改負載均衡器的配置,以透明的方式將用戶自動重定向至新發(fā)布的下一版。
隨后可將上一版的生產(chǎn)環(huán)境回收,用于構(gòu)建下下一版的產(chǎn)品。
以此類推。
(來源:Les Patterns des Géants du Web – Zero Downtime Deployment?)
這是一種相當有效簡單的方法,但問題在于這種方式需要雙倍的基礎架構(gòu)以及更多的服務器等。
假設一下Facebook希望將包含成千上萬臺服務器的環(huán)境“照原樣再來一套”……
其實還有更好的方法。
金絲雀發(fā)布
從本質(zhì)來看,金絲雀發(fā)布與藍/綠部署非常類似,但無需準備額外的一套生產(chǎn)環(huán)境。
這種方式的目標在于以增量的方式將用戶切換至新版本:隨著越來越多的服務器從當前版本遷移至下一版,相同比例的用戶也會被同時遷移。
通過這種方式,每個生產(chǎn)環(huán)境都能獲得與負載需求相匹配的服務器數(shù)量。
首先,只將少量服務器和少部分用戶遷移至下一版,借此還可以在無須冒險影響所有用戶的前提下對新版進行測試。
當所有服務器最終從當前版遷移至下一版后,發(fā)布工作已經(jīng)完成,又可以從頭開始準備下下一版了。
(來源:Les Patterns des Géants du Web – Zero Downtime Deployment?)
4. 協(xié)作
敏捷軟件開發(fā)破除了需求分析、測試和開發(fā)之間的一些隔閡。部署、運維和維護等其他活動與軟件開發(fā)過程中的其他環(huán)節(jié)也存在類似的分隔。DevOps方法意在破除所有這些隔閡,鼓勵開發(fā)和運維人員之間的協(xié)作。
如果沒有培養(yǎng)出正確的文化,就算有最棒的工具,DevOps對你而言也不過是另一個熱門詞匯罷了。
DevOps文化的主要特征在于開發(fā)和運維角色之間日益增加的協(xié)作。這是一種在團隊內(nèi)部以及組織層面上很重要的文化變遷,通過這樣的變遷才能促進更好的協(xié)作。
這種方式解決了一個非常重要的問題,而這個問題完全可以用下面這個網(wǎng)絡流行話來體現(xiàn):
(來源:DevOps Memes @ EMCworld 2015?)
團隊合作對DevOps是如此的重要,大部分方法論所要實現(xiàn)的最終目標總的來說可以通過兩個C來實現(xiàn):協(xié)作(Collaboration)和溝通(Communication)。雖然單純做到這些距離真正的DevOps工作環(huán)境還有很大的差距,但任何公司只要能堅持這兩個C,就等于邁出了最正確的第一步。
但為什么會那么難做到?
4.1 混亂之墻
因為有一堵混亂之墻:
在傳統(tǒng)開發(fā)周期中,開發(fā)團隊將新發(fā)布的軟件“隔墻扔給”運維人員,意味著自己的工作已經(jīng)順利完成。
運維人員接手開發(fā)者的成果,準備開始進行部署。運維人員手工修改由開發(fā)者提供的部署腳本,當然更多時候這些腳本都是運維人員自己維護的。
運維人員還需要手工修改配置文件,以反映生產(chǎn)環(huán)境的需求,而生產(chǎn)環(huán)境往往與開發(fā)或QA環(huán)境有很大差異。
就算最理想的情況,運維人員可能只是做了一些在上一個環(huán)境中已經(jīng)做過的重復工作,而最糟糕的情況,可能會引入或發(fā)現(xiàn)新的Bug。
隨后IT運維團隊開始討論他們所認為的,目前最正確的部署流程,然而由于開發(fā)和運維在腳本、配置、流程,甚至環(huán)境等方面的差異,基本上等同于要從零開始將所有工作重新執(zhí)行一遍。
當然這一過程中不可避免會遇到問題,他們聯(lián)系開發(fā)者希望進行排錯。運維稱開發(fā)者提供的代碼本身有問題,開發(fā)者則回應稱代碼在自己的環(huán)境中一切正常,因此錯誤肯定源自運維端。
由于配置、文件位置,以及面臨這種狀態(tài)所執(zhí)行的操作與自己的預期等因素存在較大差異,開發(fā)者甚至很難對這樣的問題進行診斷。變更窗口留下的時間所剩無幾,當然也沒什么足夠靠譜的方法將環(huán)境回滾至上一個正常狀態(tài)。
那么原本應該一帆風順的部署過程,為什么最后卻變成了“眾志成城”的應急演習?必須經(jīng)歷大量指責和錯誤才能最終讓生產(chǎn)環(huán)境恢復可用狀態(tài)?
這種情況經(jīng)常發(fā)生,經(jīng)常!
DevOps來救場了
通過在共同的業(yè)務目的情境中讓開發(fā)和運維角色與流程變的一致,DevOps有助于促進IT的統(tǒng)一。開發(fā)和運維都需要明確,自己是統(tǒng)一業(yè)務流程的一份子。DevOps思維確保了無論組織結(jié)構(gòu)是怎樣的,個體決策與行為需要盡力為統(tǒng)一的業(yè)務流程提供支持和促進作用。
亞馬遜CTOWerner Vogel甚至在2014年說過:
“誰開發(fā),誰運行。”
4.2 軟件開發(fā)流程
下圖簡要描述了敏捷軟件開發(fā)流程通常的樣子。
最開始,業(yè)務代表與產(chǎn)品負責人以及架構(gòu)團隊合作定義軟件,這一過程可能會使用Story Mapping和用戶故事,或者使用更完整的規(guī)范。
隨后開發(fā)團隊通過短暫的開發(fā)沖刺開發(fā)出軟件,并在每個沖刺結(jié)束后將生產(chǎn)就緒版本的軟件發(fā)布給業(yè)務用戶,進而收集反饋并盡可能頻繁地調(diào)整方向。
最后,經(jīng)歷過每個新的里程碑后,將軟件部署給整個業(yè)務線更廣泛的用戶群體。
DevOps造成的最大挑戰(zhàn)在于需要理解運維人員是軟件的另一個用戶群體!因此他們也應該被全面納入軟件開發(fā)流程中。
在預定的時間里,運維應該給出自己的非功能需求,就如同業(yè)務用戶給出自己的功能需求一樣。開發(fā)團隊應該按照同等程度的重要性和優(yōu)先級處理這種非功能需求。
在實現(xiàn)的過程中,運維應該持續(xù)提供反饋和非功能測試規(guī)范,就像業(yè)務用戶針對功能特性提供反饋一樣。
最后,運維和業(yè)務用戶一樣,成為了軟件的用戶。
通過采用DevOps方法,運維可以全面融入軟件開發(fā)流程中。
4.3 共享工具
在傳統(tǒng)的大型企業(yè)中,運維團隊和開發(fā)團隊分別使用專用的,沒有什么交集的工具集。
運維人員通常并不想了解開發(fā)團隊所使用的SCM系統(tǒng)以及持續(xù)集成環(huán)境。他們認為這些并非自己的本職工作,害怕自己在觸及這些系統(tǒng)后會被開發(fā)者的各種請求所淹沒。畢竟他們?yōu)榱苏樟仙a(chǎn)系統(tǒng)就有忙不完的工作了。
另一方面,開發(fā)者通常無法訪問生產(chǎn)系統(tǒng)的日志和監(jiān)視日志,有時這是因為沒有這樣的意愿,有時則是因為制度或安全方面的顧慮。
這種狀況需要改變!DevOps應運而生。
這個目標其實很難實現(xiàn)。舉例來說,出于制度或安全方面的原因,日志可能會被實時匿名化,同時需要對監(jiān)管工具進行必要的保護,以避免未經(jīng)培訓或本應被禁止的開發(fā)者更改生產(chǎn)環(huán)境的配置。因此實現(xiàn)這一目標需要付出大量時間和成本資源。但這樣做所能獲得的收益遠大于所需進行的投入,這種方法對整個公司的投資回報非常明顯。
4.4 協(xié)同工作
DevOps的一種基本哲學是認為,開發(fā)者和運維人員必須定期進行密切的合作。
這就意味著他們必須將對方視作重要的利益相關者,并積極主動地尋求合作。
受到XP實踐中“現(xiàn)場客戶”的啟發(fā),敏捷開發(fā)者受此激勵可以與業(yè)務進行更緊密的合作,自律的敏捷者還可以更進一步將這樣的實踐運用給更廣泛的利益相關者,例如可以讓開發(fā)者與所有其他相關者進行合作,包括運維和支持人員。
這是一條雙行道:運維和支持人員也必須愿意與開發(fā)者進行密切的合作。
此外還可以通過協(xié)作:
讓運維人員參與敏捷儀式(每日Scrum、沖刺規(guī)劃、再次沖刺等)
讓開發(fā)者參與生產(chǎn)環(huán)境的推出任務
在開發(fā)和運維之間打造統(tǒng)一的持續(xù)改進目標
5. 結(jié)論
DevOps是一次革命,主要是為了消除擁有大規(guī)模IT部門的大型企業(yè)中,開發(fā)團隊和運維團隊之間由于歷史原因產(chǎn)生的隔閡與孤立所造成的混亂現(xiàn)狀。
在我15年的職業(yè)生涯中,2/3的時間就職于此類大行機構(gòu),其中大部分是金融機構(gòu),每天我都在見證者這堵混亂之墻的存在。例如我經(jīng)常會聽到這樣的說法:
“在我的Tomcat上工作很正常,很抱歉,但我完全不懂你所用的Websphere,幫不上你了。”(開發(fā)者說)
“我們真的不能從生產(chǎn)數(shù)據(jù)庫中給你提取這張表,里面包含了與客戶有關的機密數(shù)據(jù)。”(運維人員說)
每天都會遇到其他很多類似的對話……天天如此!
好在DevOps日漸成熟,越來越多傳統(tǒng)企業(yè)也在開始逐漸走上正途,開始接受DevOps的原則和實踐。但還有很多企業(yè)無動于衷。
那么對于那些小規(guī)模的,開發(fā)和運維職能之間通常不會產(chǎn)生那么大分歧的企業(yè)呢?
這樣的企業(yè)應用DevOps原則和實踐,例如自動化部署、持續(xù)交付和功能開關,一樣能獲益匪淺。
我認為DevOps原則可以總結(jié)為:
DevOps實際上是向著大規(guī)模敏捷(Scaling Agility)邁出的另一步!