6月10日,優維科技與數人雲、中生代聯合舉辦了devops&sre超越傳統運維之道(北京站)。devops&sre上海站将于7月15日舉辦,敬請期待!
任發科老師在此次活動中分享了《如何打造易用的devops工具鍊》,以下為演講實錄。
任發科 網名常新居士。曾任職于唯品會、會唐網、亞馬遜和thoughtworks,是qcon,top100summit,tid優秀講師,近年主要關注和從事devops工具鍊設計與實作,并長期從事和關注高效研發團隊的元件和管理,譯作有《devops,軟體架構師行動指南》等
為什麼講這個主題
之前很多分享都是集中在devops工具的設計領域,講方法論的比較少。最近看到一些程式員做的東西,缺乏邏輯性,做出來的東西效果不好,感覺很違和,是以今天我們講講工具的易用性。
目前,我們公司devops的整個理念是傳承自亞馬遜,跟目前的devops并不是100%重合。不過,devops隻是一種理念,一種描述,并沒有明确的定義,從2011年到2016年,devops相關的很多東西一直在不斷變化。
就傳統運維來說,devops有兩個最大的不同點:一是把開發運維結合在一起,開發和運維應該傳遞一個運作系統。運作系統承載了運作的業務,是以,系統是從一個運作的版本進入到另一個運作的版本。
在此基礎上,差別于devops所強調的相關團隊協同合作,我們更強調開發承擔運維、測試的工作,也就是誰建構誰運維,讓開發做上線部署、運作監控、系統穩定性優化等等工作,而營運人員應該更專業化,提供專業性的支援和相關運維工具。
隐藏在問題背後的共性
就是今天要講的如何打造易用的devops工具鍊,而這個工具鍊是多個工具組成的生态。
實際上“易”字代表了兩個意思:一是簡易,工具的設計架構本身要足夠簡單,友善拓展配合。二是易用,對于使用者來說,不會造成過多負擔,能快速解決問題。
簡易、易用為什麼重要
我們在devops工具鍊的研發過程中,分析了許多相關工具,遇到一些問題,這裡是一些思考,希望能對大家有所借鑒。
如果從産品使用者體驗去看,當講到易用性大家都是知道的。
作為使用者,我們每天都在使用各種網際網路工具。但2c和2b的應用是不一樣的,易用性表現的也有所不同,2c強調的是讓使用者減少思考和決策,保持粘性,解決痛點。而2b要解決效率,如怎樣更快、低成本地解決相關業務的問題,直接影響業務效率。
易用性是如何對我們産生影響的?能夠影響簡單易用的有兩種方面:業務和使用者。而影響方面則具體在架構、設計和傳遞等方面。
全生命周期管理
現在大家都關注軟體研發和營運的全生命周期管理。從這個角度看,現階段多數devops工具鍊其實都不算完善。基于工具鍊去分析公司的能力,可以分為三個梯隊,第一梯隊是亞馬遜、谷歌、臉書、推特等公司。
第一梯隊已經在業務發展的過程中建構起完善的it支援生态,但它們從來不講自己做devops。隻有第二和第三梯隊在以概念為抓手來實施devops,而第二梯隊已經基于自動化運維或者開源工具構築了一定的持續傳遞能力。
舉例來說,2006年初亞馬遜的整個工具鍊其實就已經基本就位,當時尚未有devops的概念,而今天,圍繞研發和運維已經有近50個獨立的工具或系統。
由于今天演講的時間限制,我們不可能涵蓋devops的方方面面,是以,我們将主要關注在部署流水線相關的工具上,這是我們探讨的主要業務關注點。
部署流水線
關于部署流水線,有一些關鍵的點需要注意:
每一次隻生成一次二進包,接下來的階段無論是手工、驗收、部署等所有測試,都是前面生成的二進制包做的。
即便在如今十分完善的部署流水線設定上,還需要引入人工的節點。尤其是關鍵業務系統,因為有一個更新的過程,所有要卡一個人工稽核的節點,甚至人工稽核的階段,在測試時需要讓運維和測試人員能夠手動選取版本。
當操作人員看到建構版本時,需要看到連同建構的全部狀态,如版本之前的活動的進展狀态。
技術人員
這是我們工具的主要使用者。當分析技術人員時,會發現他們都自視甚高,尤其是研發人員,在自己眼中什麼都能做,比如項目管理時,研發人員的預估永遠是樂觀的:沒問題,都可以完成。
在一些事情上,技術人員的标準很低,當交代給研發人員一些任務時,若沒有産品把關,研發出來的東西很難用。如果經常和技術人員打交道會發現他們的一句口頭禅是:能用就行。
研發人員特别強的一點是可以并行處理大量的資訊,在工作中非常适合進行批量處理。但有一些事情會極度較真。如大括号的問題:在php或者java時是放下面還是放在後面。
經驗十則之如何打造靈活易用的devops工具鍊
經驗一:實作上分離,服務上整合
做工具鍊要實作“實作上分離,服務上整合” 。如上圖,建構、環境管理以及其他一些工作,如果在實踐時運用jenkins,jenkins本身非常強大,可以将所有的事情都放在一個工具裡去做。但當系統或者公司規模龐大時,就應該摒棄jenkins了。因為系統需要做到關注點分離,需要獨立發展每一個工作。
部署流水線最重要的事情是:建構和部署。流水線隻是将其串起來的工作流和在此之上加一些決策邏輯。但超出流水線之外的仍有很多工具,比如環境定義,能夠做到配置化的環境管理。
每次推送的都是運作中的系統而不是可工作的軟體,是以就可以看到有些系統有自己的複雜性。
如建構,建構絕不是依托于jenkins的腳本,其本身可能非常複雜,尤其是當系統分子產品後,一個系統有2—3個子產品之間的依賴,而這些子產品又依賴于一些第三方庫,就會發現非常麻煩,建構的過程非常複雜,本就可以作為一個獨立系統去做。
當需要整合時有兩種方式:
1、視圖的方式整合,如上圖,此視圖非常适合。git,jenkins可以将它放到一個圖形界面上使用。
2、各個工具對外提供api,通過服務化的方式進行互相排程。
總結下第一個經驗帶來了什麼:
在做系統時,要記住每個系統隻做一件事,并且将它做好,如做建構就隻做建構,做釋出部署就隻做部署。10個系統做10件事,遠比1個系統做10件事更好,因為複雜程度更低,更好配置,前提是業務真的達到10個系統的需求。
從工作到現在,所遇到的大部分一站式系統都是反人類的,因為功能太多,隻有在真正需要的時候才給出一站式解決方案,需要合的時候再合才是正确的。
在亞馬遜做供應商內建工作時,經常提到one stop shop即一站式。一個系統解決某個方面的所有問題,但隻解決一個層面的問題,整個流程工作很多,絕對不拿到一個系統裡做,因為太複雜。
經驗二:設計上的關注點分離
設計上需要關注點分離,這個部署系統可以把所有部署邏輯集中在一起,明确往哪個機器上做哪些任務、工作,然後中間進行管控,這很容易實作。缺點是不适合擴充。
更好的辦法是中間控制的部分隻管任務和狀态,至于如何部署讓agent去做,挂載另一台機器就可以自動運作,不需要控制,如此整個系統設計就相對簡單。
經驗三:簡單性>完美性
案例:要記住簡單性要勝過完美性,在設計層面包括架構,如上圖,這是一個線上系統的輪值排班功能,現需要進行減員。
研發人員給出的第一個方案:人員的詳細資訊是放在ipd裡面,有一個查詢的api,每次建立排版系統表時,系統裡隻儲存人員的id,展示時調用api提出資訊,好處是人員的資訊可以修改,如名字,也能實時的反應出來。
這個方案不考慮曆史資訊,比如說之前排版如何,人員執行狀況如何,這些都不考慮。排班情況是在現有的時間和規則基礎上,來推演後面排班是什麼樣的計劃,這個方案是可以接受的,但是有一個巨大的問題,當去做考核時,因為沒有曆史資訊以及值班情況都無法查詢。
研發人員給出的方案二無法接受,因為當删掉一個人時,所有東西都會被删除。如不要實時查詢,緩存資料即可。曆史資料按照跑批沉澱,如按照周去沉澱,在生成排班表時将資訊抓取,落到曆史庫裡,基本資訊常用資訊也會同步儲存。
但有個問題是沉澱階段資料仍可能不一緻,比如說一天的排班,abc三個人在當天或者當周都有排版,此時将b删除後,前階段還沒有沉澱的仍會被修改,資料仍然不精确。
研發人員給出的方案三:解決方案是在修改的瞬間發起一次沉澱,把開頭到現在跑批,沉澱進去,剩下的東西不去管,進行更新,因為更新屬于未來,再跑批時再進行沉澱,這是非常精确的方案,但方案複雜度會比較大。
研發人員給出的方案四:資料精确性是否真的重要,是否可以允許有一些誤差,比如拉曆史資料隻是為了看報告,一個輪值的性能名額,錯一天或者錯一周對結果績效沒有根本性的影響。
是以接下來想能不能在一個有限的範圍内讓資料變得更精确,如縮短沉澱周期,從一周跑一次沉澱變成一天跑一次,一天跑一次變成一個小時跑一次,如此随時都可以沉澱,不準确的範圍和可能性就相對較小了。
方案三和方案四孰優孰劣?需要根據自身的訴求去看,看是否需要非常精确的資料,一般的情況下選擇方案四就可以了,因為一是沒有必要,二是越精确的方案,它的複雜性就越大。
再舉一例:簡單性要比完美性、一緻性更優先考慮
如果ipd删了一個人(因離職等),因為想要省事,讓ipd調用排班系統的api,然後将其删除,但這不是一個好方法,因為耦合性太強。ipd系統根本不知道是否有排班這件事。讓ipd關注不相關的排班業務,這是錯誤的方式。
方案二是輪詢資訊,讓排班系統調用api輪詢檢視人員是否發生變化。但這也不是一個好的方法,對ipd壓力過大,也沒有必要。
實際在技術上有更好的辦法——加消息隊列,在兩個系統間加消息隊列,把人員修改變成更新事件,如此兩個系統都不知道對方的存在。這個方案的好處是,如果人員資訊是非常重要的資料,那麼發出來的事件消費者可以是任何系統,排班系統可以、其他系統也可以
研發人員給出的方案四:就是根本不去做通知,如果一個人離職,他的經理一定會修改排班計劃,雖然修改可能會有時間滞後性,也有一定的影響但影響不大,因為可以替換其他人去進行值班。而且整個排班系統裡面如果一個人在規定時間内沒有響應,随時上報經理,立刻進行修改,是以人肉修改的方式其實是最簡單的方式。
此時再考究方案三和方案四哪個更好?依然是方案四,即便名字變了,也可以在系統裡增加一個名字修改功能,甚至可以不把名字納入資料系統,因為郵件位址和工号是不會變更的。
經驗四:關注進階使用的情況
有80%的情況,用簡單的工具就可以解決,比如說部署,點一下按鈕就可以部署了。但有20%的情況是需要批量處理的,甚至在程式的層次上,有時候要進行邏輯驗證或二次開發,而這個時候圖形化的解決方案是無法勝任的。
是以核心系統服務化是非常重要的,核心系統服務化後,web site可以交給日常處理,不需要太多業務知識,同時要有基于dsl的指令行工具,它的特點是擴充性很好,可以再此之上再做程式設計,執行效率高,比如一百台的機器到界面上如何部署,在指令行敲幾個指令篩選出來,這樣更快。
防止來自腳本的誘惑
當提供指令行時,一定要防止腳本過多,如果腳本處理的業務不是單一的,不要作為系統的一部分,隻作為一個幫助性的工具,因為devops強調的是整個工具鍊需要狀态上報和資料沉澱,如裡面有4部分的事,不知對錯,效率依然很低,若是單一的,就能知道模型在做什麼,就可以成為系統的一部分被調用。
經驗五:just work
just work經常被提到,如當使用電視、遙控器、手機時,隻關注怎麼用,背後的實作邏輯和電子電路的原理,不需要關心。
從這個層面上去看,兩個界面對比,上面的界面暴露了太多的實作細節,而下面隻關注重點階段,這是兩個工作流的實作方式。
上面界面另外一個巨大的問題是,測試通過和不通過跟人工測試是屬于兩個抽象層面的。人工測試和容量測試、單元測試及部署才是一個層面的,但是測試通過與否是一個邏輯上的判斷,不應該在此界面上顯示出來。
在這個層面上,不需要了解太多的細節,關鍵在于發生了什麼事,上報beta版,上報自動化測試環境,至于中間是不是人肉測試過,不需要關心。到promotion的角度,才是應該呈現出來的。
經驗六:重在當下
拿優維科技的産品界面舉例,重在當下是說如果做部署的話,昨天發生的部署不在關心範疇之内,隻關心目前發生了什麼,最近一次發生什麼,是六個小時前發生還是一個月前發生即可,業務系統是否正常。曆史清單則不需要告訴我,可以将其隐藏當需要時才出現。
經驗七:隐藏非關鍵資訊
當一個工具鍊從一個階段到另一個階段promotion時通常也不關心中間邏輯。隻有在出錯的情況下才去關注細節,如在測試時測試失敗,這時去看到底是哪一個階段失敗了。
是以隐藏關鍵資訊就是出錯時才進行提醒細節性資訊,如果沒有出錯,就不需要,因為整個工具鍊的資訊是非常豐富的。
經驗八:業務為線,不要堆砌功能
整個工具的設計,不僅僅适用于工具鍊,隻要是2b的功能,那麼就不要堆砌功能,上圖裡會發現裡面有将近200個菜單,業務人員使用時非常痛苦,處理一個業務需要在不同的菜單重複進行切換和設定。
是以需要寫文檔來幫助業務人員,如第一步到哪些菜單等等,這就是堆砌功能。可以發一個圖把所有的功能羅列出來,自然而然變成一個樹狀圖,反映到左側的清單裡頭。
這是一個展現方式比較好的頁面編輯器,一個業務界面。在邏輯層面上,左邊的菜單可以收起來,這是需要關注的幾個概念。
在workspace裡,建立出來進入到工程開發以後,收起來以後就進入到workspace内部了,以項目為單元,以檔案為基本的組成部分去調試、開發、編輯,是非常實用,沒有過多功能堆砌,一眼就能看到要用的。
上圖是專題編輯界面,也是一個比較好的界面,抛棄了那種樹狀圖功能的導航,在主要業務上,把不必要的資訊隐藏,把必要的資訊漏出,自然而然關注到業務問題的解決。
經驗九:突出使用、分離配置
當使用一個工具鍊的時候,包括jenkins,會發現會發現10%的時間在配置流程,一旦配置好90%的時間是不變的隻是在使用,工具要有這樣的特點——用的多變的少,把使用的部分重點突出。
把配置的部分做的簡單一些,把功能隐藏起來,因為隻有10%的時間去配置,而且配置完就基本無需理會了,使用即可。
經驗十:簡化操作
整個2b工具鍊的研發,無論是devops或者其他,都是在解決效率和業務問題。每一次建構一個版本,之後基于這個版本做測試就需要整個生命周期的變化,是以要建立一個全流程追蹤的體系。
在追蹤體系裡,同源的問題很重要,同源不僅僅是提供相同的制品叫同源,如建構一個1.01版本部署到生産環境時,還是這個制品,這不叫同源,是僞同源,因為建構時是基于2.2.1版本,是以生産時上的公共庫是2.1版本,不是2.3.0版本。是以依賴處理時,要把資訊保留,用什麼建構,就上什麼版本,如此才叫同源。
想的更多一些,将來運作所用的目标系統可能是32位,可能是64位,需要在建構的時候明确未來要在哪個平台上運作,當從平台上去拉制品的時候,應該拉過來的是對應的32位或者64位。
如此帶來一個問題,系統要記錄這些資訊并且把它鎖住,否則你應該再去選擇,鎖住這個情況,當去部署,上面提到,有一些情況下需要手動去選擇什麼部到某一環境,如測試、生産。
如果有此情況,選産品1.0版跟其他相關建構,産生關聯時必須鎖定不能被選擇,這是簡化操作。可能有100個包都不能編輯,整個部署隻有一個或者兩個可以變,其他不變。
總 結
devops其實沒有大家想象的那麼複雜,當然,也并不簡單。亞馬遜的整個體系工具鍊大概是50個左右工具。
最近數人雲和其他一些網際網路企業都在學習谷歌的sre,而我本人也關注devops很長時間。無論是亞馬遜的經驗,還是谷歌的經驗,在落地時都需要一些改進,要進行調整。
比如谷歌的單根代碼庫,谷歌曾經有人去其它公司推單根代碼庫,但是沒有做起來,因為其從最開始就選擇了一個非常有挑戰性的方法,在這個基礎上做了很多很牛的事情。
但根本上,想解決的問題實際上就是代碼共享和依賴處理等等問題,但是其實有更簡單的解決方案,在那個年代,亞馬遜用另外一套解決方案做的也很好。
谷歌的流程很強,亞馬遜也同樣如此,但在借鑒的背後我們需要思考與變更。