例項化 DevOps 原則

ThoughtWorks發表於2017-03-11

【摘要】

  • DevOps原則所追求的願景,就是“讓業務所要求的那些變化能隨時上線可用”;
  • DevOps的起源表明,其原則是從Agile與Lean的實踐當中提煉而來,因此與Agile和Lean的原則並無二致;
  • 本文所討論的DevOps原則可以用“人、產品、流程和工具”這4個維度來進行組織。

【正文】

“你在做使用者故事拆分?這不是在做DevOps。”這是筆者在2016年以諮詢師的身份,參與一家大型跨國金融企業的Agile和DevOps轉型時所聽到的話。在這家企業,Agile和DevOps明顯指的是不同的東西:前者專指每日站會、計劃會、回顧會等Scrum的實踐和使用者故事實踐;後者專指自動化、工具鏈和基礎設施等實踐。過了一段時間,筆者把本文所列舉的一些DevOps原則發到一個相關微信群裡面,得到了這樣的反饋:“怎麼滿眼都是敏捷和精益?”“感覺DevOps被一群不操作Op的人給玩兒壞了。”

這些經歷讓筆者開始關心這些問題:既然Dev指的是“開發”,Ops指的是“運維”,那麼到底什麼是DevOps?它的原則是什麼?它和敏捷、精益的關係是什麼?讓我們先觀察一下DevOps的起源

DevOps的起源可以分為兩條線

第一條線是:比利時獨立諮詢師Patrick Debois

2007年他在比利以諮詢師的身份,參與了一個政府資料中心遷移中的測試工作。他在做測試時,需要頻繁往返於Dev團隊和Ops團隊之間。Dev團隊已經實踐了敏捷,而Ops團隊還是傳統運維的工作方式。看到Ops團隊每天忙於救火和疲於奔命的狀態,他在想:能否把敏捷的實踐引入Ops團隊呢?

第二條線是:當時雅虎旗下的圖片分享網站Flickr

這家公司的運維部門經理John Allspaw和工程師Paul Hammond,於2009年6月23日在美國聖荷西舉辦的Velocity 2009大會上,發表了一個引燃DevOps的演講。這個演講的題目在當時很搶眼--《每天部署10次以上:Flickr公司的Dev與Ops的合作》

這個演講有一個核心議題:Dev和Ops的目標到底是不是衝突?傳統觀念認為Dev和Ops的目標是有衝突的——Dev的工作是新增新特性,而Ops的工作是保持系統執行的穩定和快速;而Dev在新增新特性時所帶來的程式碼變化,會導致系統執行不穩定和變慢,從而引發Dev與Ops的衝突。然而從全域性來看,Dev和Ops的目標是一致的,即都是“讓業務所要求的那些變化能隨時上線可用”。

這樣搶眼的題目和鮮明的觀點,自然抓住了當時還在比利時的Debois。他在“推特”上發帖:“可惜沒法去現場參加。”朋友Paul Nasrat回帖說:“為什麼不在比利時搞一個你自己的Velocity大會?”這兩條線使得Debois擼起袖子,於2009年10月30至31日,在比利時的第二大城市根特,以社群自發的形式舉辦了一個名為DevOpsDays的大會。這次大會吸引了不少開發者、系統管理員和軟體工具程式設計師。這兩天大家聊得太開心了,會議結束還不過癮,回去繼續在“推特”上聊。限於推特140個字元的制約,Debois把DevOpsDays中的Days去掉,而建立了#DevOps#這個“推特”聊天主題標籤,DevOps誕生了。

Flickr公司的兩位演講者所表達的“Dev和Ops的共同目標是讓業務所要求的那些變化能隨時上線可用”這一觀點,其實就是DevOps的願景。而要達到這一點,可以使用一個現成的工具:精益。源自豐田生產方式的“精益”的願景就是“Shortest lead time”,即用最短的時間來完成從客戶下訂單到收到貨物的全過程。這恰好能幫助實現DevOps的上述願景。《持續交付》的作者之一Jez Humble也體會出精益在DevOps中的重要性,以至於他把DevOps的CAMS框架修訂為CALMS,其中增加的L指的就是Lean(精益),這一點下文還會提及。

從上面DevOps的起源中能夠看出三點:

  1. DevOps源自草根社群,最初並沒有什麼自上而下設計出來的理論框架;
  2. DevOps背後的原則,就是上面兩條線中所涉及的敏捷和精益的原則;
  3. DevOps的願景是讓業務所要求的那些變化能隨時上線可用。

一旦瞭解了上面第2點,就不會有前文中所說的“Agile和DevOps是不同的東西”和“感覺DevOps被一群不操作Op的人給玩兒壞了”這樣的說法。

因為DevOps源自草根,沒有什麼框架,所以如何定義DevOps成了DevOps社群裡面的一個大難題。一些DevOps從業者,紛紛設定自己的DevOps框架。其中比較有名的框架有上文提到的Damon Edwards所定義並被Jez Humble所修訂的CALMS,和Gene Kim所定義的The Three Ways

CALMS:

  • Culture – 文化:公司各個角色一起擔當業務變化,實現有效協作和溝通;
  • Automation – 自動化:在價值鏈中儘量除去手工步驟;
  • Lean – 精益:運用精益原則更頻繁地交付價值;
  • Metrics – 度量:度量並使用資料來優化交付週期;
  • Sharing – 分享:分享成功和失敗的經驗來相互學習。

The Three Ways:

  • The First Way: System Thinking (系統思考:強調全域性優化,避免區域性優化);
  • The Second Way: Amplify Feedback Loops (經過放大的反饋迴路:建立從開發過程下游至上游的反饋環);
  • The Third Way: Culture of Continual Experimentation And Learning(持續做試驗和學習的文化:持續做試驗,承擔風險、從失敗中學習;通過反覆實踐來達到精通)。

(圖片來自:http://t.cn/RijRjYS)

本文試著從“人、產品、流程和工具”4個維度,來梳理DevOps的一些原則。為什麼會有這4個維度?

先看前三個維度:“人”、“產品”和“流程”。在一百多年前的工業經濟時代,由於物質匱乏,所以當時占主導地位的泰勒科學管理理論將“流程”這個維度放到了第一位,讓企業首先通過標準化的“流程”達到規模化的製造能力,來滿足供不應求的市場。市場上可購買的商品少,人們對“產品”的質量、設計也就不介意了,所以“產品”排在了第二位。而標準化的流程把工人的素質標準降到了最低,只要帶著一雙手來,在流水線上重複一個動作就好了,不需要動腦子,因此“人”排在了最後的位置。

一百年後,工業經濟霸主的地位已被知識經濟所取代。在具有知識密集特點的敏捷軟體開發的上下文中,這三個維度的順序顛倒了:“人”的優先順序最高,因為只有依靠“人”的創造力才能應對多變的業務需求;給使用者提供價值的“產品”依舊排第二位,因為這是企業賴以生存的根基;而“流程”可以為了“人”來高效地實現“產品”而進行定製,所以優先順序最低。而強調自動化的DevOps離不開好用的“工具”,“工具”又可以依據流程來定製,因而可以補在“流程”的後面。

(圖片來自:http://t.cn/RijRMrp)

下面所描述的DevOps原則,來源於敏捷、精益和DevOps的一些具體實踐。雖然沒有涵蓋DevOps的所有實踐,但已經包括筆者最近一年在DevOps的實踐中所感悟的主要內容,而且今後會繼續完善。

一般的文章對於“原則”的闡述都比較抽象,有點像上面提到的CALMS和The Three Ways這兩個框架的定義方式那樣——僅僅把幾個名詞或短語放到那裡。對於不熟悉Agile、Lean和DevOps的人來說,看了上述框架還是不知道DevOps到底是做啥的。

為了讓DevOps原則的描述更加具體生動,筆者參考敏捷宣言的寫法和例項化需求的做法(即用具體的實際例子來編寫驗收條件),使用了“高於”和“而非”的句式來對比兩個具體實踐的例項,且儘量用一些具體的實踐來代表相應的原則,如“部署流水線”等。其中,“高於”表示右邊的實踐雖然不如左邊的好,但還是有價值的。“而非”表示右邊的實踐並不值得推薦。這就是本文標題中“例項化”的由來。

1. 人

領導者身體力行持續改進 高於 關注工具和基礎設施

很多企業(包括筆者所輔導的企業)都在實踐DevOps。要想讓DevOps這顆樹苗茁壯成長,企業要為其提供一個良好的土壤——即企業文化。而企業文化,是企業領導者引導塑造的。DevOps對於國內大部分企業來說,都是一個前所未有的新事物。必須通過不斷做試驗,才能找到培育它生長的土壤方,做試驗就是為持續改進做準備。筆者所輔導的企業,工程師被專案進度壓得喘不過氣來,根本沒有時間學習新工具和新方法,更別提做試驗了。

(圖片來自:http://www.yes123.com.tw/)

所以只有領導者身體力行,不僅自己親自做試驗和進行持續改進,並給工程師足夠的時間來做試驗和持續改進,這樣所創造出良好的環境,才能讓那些自動化工具和基礎設施在企業內部得到有效利用。

試驗並改進流程 而非 指責人的過失

豐田公司有一句口號:“對流程苛,對人員柔”,意思是說:每位員工都會盡力做好工作的,那些在工作中所出現的問題都是流程的問題。因為根據這種有問題的流程來工作,無論是誰都會出同樣的問題。前面說過,DevOps對於國內大部分企業都是新事物,需要做試驗來“摸著石頭過河”,做試驗就有失敗的時候,此時就要調整流程,而不是怪罪於人,否則企業沒有人會去繼續嘗試DevOps。

產品思維 高於 專案思維

根據這一個原則可以定義“人”的組織結構——團隊結構,即可以按照產品而不是專案來組建團隊。這樣的產品團隊包括了Dev、Ops、BA、Tester、PO和Architect等各種角色,他們相互配合且不依靠團隊以外的其他角色就能獨立自主地交付軟體產品,這個產品團隊負責該產品從生到死的全生命週期,並且只要產品還在,這個團隊就不會解散。這種設定會讓團隊的不同角色目標一致,比起從目標不一致的各種職能團隊(比如Dev團隊、Tester團隊和BA團隊)抽調人員拼湊成臨時的專案團隊,磨合期更短,更加有戰鬥力。

2. 產品

質量和安全內建 而非 晚期度量和檢查

產品需要質量和安全來保證價值。人們長期認為“高質量”意味著“高成本”,因為要維護高質量,需要在產品出廠前做大批量檢測,並銷燬那些次品,這就花費了高昂的成本。但豐田公司卻說“高質量是免費的”。這是怎麼做到的呢?這其實就是前文提到的豐田公司“對流程苛”的結果。豐田公司通過持續改進流程,“一次就把事情做對”,這樣就能在脫離後期大規模檢查的情況下保證高質量,同時其成本也趨近於零。

客戶反饋 高於 按期交付

產品是否實現了價值,只有通過客戶的反饋才能知道。很多團隊往往過分關注交付期限,而忽視客戶反饋。這樣做的後果,就是雖然按期交付,但是產品卻不是客戶所期望的,造成返工或專案失敗。

基於不可變容器的微服務 高於 單塊應用

產品需要能快速地開發、測試和部署才能有效地交付價值。對於複雜度高的大型產品,如果可以由多個微服務組合而成,每個微服務都能獨立地開發、測試、部署和上線。這比起必須整合各個模組才能進行手工測試的單塊應用來說,更能實現各個微服務之間的並行研發,加快每個微服務的開發下游至上游的反饋環的反饋速度,進而縮短專案進度,讓價值交付得更快。不可變容器指的是軟體產品被封裝到一個類似docker這樣的容器內上線,且上線後不可手工修改其配置。如果一定要修改,也只能通過部署流水線把要修改的內容重新打包成另一個新的不可變容器來上線。這樣做的好處是能夠實現部署和釋出自動化以及進行更好的版本控制,消除線上手工配置所帶來的無法審計的風險。這一實踐是本文寫作時期的推薦實踐,該實踐今後還會繼續演進。

3. 流程

管理層實踐Improvement Kata和Coaching Kata進行流程持續改進 高於 用結果導向進行管理

佛家說:“菩薩畏因,眾生畏果”。傳統按結果導向進行管理的一個弊病,就是團隊成員會把注意力放到結果上,而不是產生這樣結果的原因——即過程改進之上。這樣的後果就是,大家會把精力放到如何讓報表好看,而不是真正地提高團隊成員的持續改進能力來真正達到所期望的結果。企業管理層可以參考《豐田套路》一書來帶頭實踐Improvement Kata和Coaching Kata,讓企業產生持續改進的文化。其中,Improvement Kata是通過一系列“確定目標—>考察現狀—>識別困難—>制定方案—>觀察成效”的PDCA反饋環來做持續改進;Coaching Kata是通過導師“一對一帶學徒”的方式來讓企業全員掌握持續改進的方法。

全域性優化 而非 區域性優化

由於大部分按職能組織團隊的企業內部都存在部門割據的問題,導致大家都在做本職能部門內的區域性優化,而沒人做部門間的整體優化。有些部門間的扯皮時間甚至長達數月,嚴重影響了產品的交付。這提醒我們,全域性優化來提高企業整體競爭力,才是各個部門賴以生存的保障。

單件流 高於 庫存

單件流指的是,正在製作的產品的各個模組,能從最初的對其增加價值的加工步驟,直接傳遞到下一個增值加工步驟進行加工,並最終被傳遞到客戶手中,在這個過程中,各個步驟之間沒有發生等待或者排隊的現象。而如果在各個步驟的傳遞過程中發生了等待或排隊,那就等同於建立了庫存。

軟體開發中常見的庫存包括排隊等候開發的需求、排隊等候測試的程式碼、排隊等待修復的缺陷和排隊等待上線的產品特性;隱藏很深的庫存可能由諸如那些有固定期限(比如每月一次)的“使用者驗收測試”的流程造成——月初幾天就開發測試完畢的產品特性必須要被存放近一個月,等到月底“使用者驗收測試”後才能繼續往下游走。軟體開發中的上述庫存就是讓專案延期的最大原因。而企業如果能做到單件流,那麼就相當於消滅了庫存,讓價值在不同環節之間流動得最快,進而實現了前文所提到的全域性優化。

4. 工具

自動化 高於 手工

按照固定流程所進行的手工工作,比如手工迴歸測試和手工部署工作,無趣、緩慢且無法審計。如果能將其程式碼化,且用版本控制系統管理起來,並加以自動化,這既能節省以後手工執行的大量時間,又能體驗到開發測試和部署指令碼工作的樂趣。

基礎設施及程式碼 高於 手工配置

傳統Ops的部署工作有些需要用滑鼠在介面上點來點去,效率很低;效率高一些的Ops用了自動化指令碼,但很多指令碼都沒有進行版本控制,更別提針對指令碼的自動化測試了。 如果能夠將基礎設施的維護工作都通過編寫程式碼並加以版本控制來完成,那麼會帶來很多好處,比如Ops可以不用通過訪問生產環境,就能知道生產環境上的配置情況;非運維人員如Dev,就有機會去學習這些運維配置程式碼並且加以修改,提升整個團隊的DevOps能力;另外工具能方便地讀取這些程式碼,來自動化地維護基層設施,大幅度提升Ops的工作效率。

部署流水線 而非 每日構建

程式設計師每天都會用程式碼提交來為軟體系統增加價值。而如何有效地保證每次提交的程式碼質量過關而不會有損現有系統的價值呢?這就需要一個程式碼構建系統自動地驗證程式碼在編譯、測試和打包等工作的過程中,是否符合質量要求。有些團隊還在每晚做一次程式碼構建,這個昔日的“最佳”實踐如今已經不再被推薦。一個團隊程式設計師們每天程式碼的提交會有很多,如果晚上構建發現了錯誤,第二天從這些眾多提交中發現誰導致的錯誤,將是一個很困難的事情。推薦的做法是每一次程式碼提交,都能自動觸發部署流水線來檢查該提交是否通過了自動化單元、驗收和效能等測試。一旦發現問題,就能輕鬆定位是誰在哪個環節出現了什麼問題。

總結

DevOps的原則來自從業者們在日常工作中運用敏捷、精益原則的具體實踐。這些原則可以按照“人、產品、流程和工具”4個維度來組織。這些原則和實踐的目的,都是要實現DevOps的願景——讓業務所要求的那些變化能隨時上線可用。

下圖是本文例項化DevOps原則的一個視覺化總結。

相關文章