【DevOps&SRE活動實錄】經驗+案例,教你如何打造易用DevOps工具鏈!

優維科技發表於2017-06-20

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很長時間。無論是亞馬遜的經驗,還是谷歌的經驗,在落地時都需要一些改進,要進行調整。

比如谷歌的單根程式碼庫,谷歌曾經有人去其它公司推單根程式碼庫,但是沒有做起來,因為其從最開始就選擇了一個非常有挑戰性的方法,在這個基礎上做了很多很牛的事情。

但根本上,想解決的問題實際上就是程式碼共享和依賴處理等等問題,但是其實有更簡單的解決方案,在那個年代,亞馬遜用另外一套解決方案做的也很好。

谷歌的流程很強,亞馬遜也同樣如此,但在借鑑的背後我們需要思考與變更。


相關文章