孫敬雲 --Worktile高階系統架構師,WTC成員
1.研發的困境
網際網路的環境
網際網路這個環境比較特別,包括現在不只是網際網路,就算是被網際網路賦能的這些“網際網路+”的企業也在改變,使用者在發生變化,使用者構成的群體在發生變化,群體造成場景的變化,場景營造新需求,需求養成新使用者習慣,新使用者習慣造就一批新使用者,周而復始。我們一直在追趕使用者,但從使用者的角度來說,他一直都期望有一個好的產品和一個穩定的服務。相信在座各位既是技術從業者也是普通的使用者,大家會發現自己總是想嘗試一些新的東西和好的東西。
軟體交付的困境
進度不可控: 我們的研發團隊會面臨一個問題,一些傳統的行業也好,或者現在在實行Sprnit的團隊也好,你會發現研發 進度非常不可控 。你有時候感覺一切都很可控,完成任務的時候前80%也覺得沒問題,一定能交付。但一旦到了後20%,測試報出海量的bug,運維問你怎麼部署?好多東西還沒有定,越來越忙。尤其是上線的晚上,一定要搞一個通宵才能把所有的問題解決。這種複雜的困境是技術不可控的;
流程不可靠: 我們公司總是有各式各樣的流程發生,但你會發現這個流程走著走著總是需要有一些 關鍵角色 蹦出來,必須有一些企業大牛或團隊經理站出來說這個事情應該怎樣做,或者說今天誰誰沒來,這個流程沒法往下做。
環境不穩定: 線上怎麼就出問題了?測試環境好好的,本地就沒問題,是不是因為線上沒有按照我說的做?環境這個問題在哪個公司都會遇到。
溝通不順利:研發同學跟運維同學在爭論,研發同學說上線之後跑指令碼,運維跑完了上線出了問題。研發同學就問他“你跑指令碼了嗎?”他說“跑了”,“是部署前跑的還是部署後跑的?”他說“你沒有跟我說這個。”這就是溝通不順暢,這個本來是可以避免的。
我們需要一種工程手法,讓軟體在很短的週期內穩定部署上線。 關鍵詞是 “很短” 和 “穩定” ,甚至一鍵部署到任何版本任何環境中,甚至這些操作都在視覺化的環境進行。我們在研發團隊中說,凡是要定目標做計劃,怎麼辦?我們今天每個人給自己定一個目標: 從今天開始每個團隊一天部署三次 。大家覺得不可能,安排計劃Sprint兩天就夠嗆了,怎麼可能一天上線三次?
舉一個真實的例子
匯豐銀行在2014年的時候全年release24次,這個數字相當於 兩週有一個 release的版本,很高效。但是2018年全年release12000次,這是什麼概念?你今天一天release 幾十 次,大家覺得這不可能,開發程式碼能寫完嗎?這就是一種思維方式的轉變。
如果我們今天說一定要達成這個目標,不管可能不可能,給我一個執行方案和參考的借鑑點。
概念的組合
我們把這個事情分為四個步驟:
第一步 ,自動化的流水線,這是穩定可重複使用的。
第二步 ,支援構建流水線所需要的技術平臺和工具。
第三步 ,執行這些平臺完成流水線所需要的人和角色。
第四步 ,支援能夠把這些所有東西全部落地並有穩定持續改善方案的文化與規則。
2.DevOps是什麼?
DevOps在維基百科上的定義
DevOps是一種重視軟體開發人員和IT運維技術人員之間溝通合作的文化、運動或慣例,透過自動化軟體交付和架構變更的流程,來使得構建、測試、釋出軟體能夠更加地快捷、頻繁和可靠。
所以前面所有的都是定語,只有最後一句最關鍵,就是 :頻繁可靠的釋出軟體,這就是我們的終極目標。
針對剛才定義的原始闡述,從這個環形圖上的工作方式,一直在持續演進,好像看起來沒有什麼特別的,這個神奇點在哪?
如果你跟別人說你今天看了一篇分享是DevOps,或者你去搜DevOps,會發現所包含的含義和相關的含義特別多,包括 精益思想、自動化、持續整合、持續部署、價值流、三步工作法、持續交付、分級部署、敏捷思想、敏捷開發、團隊合作 。
在我看來這是大家對於美好事物的一種期望,期望DevOps能承擔更多。即使我們今天不提DevOps這個詞,把敏捷這個詞說出來,你也會說敏捷包含這些部分,換個詞也是這樣。我認為我們 千萬不要陷入於這個詞的含義是什麼 ,我是想談 工程化 ,談 工程化背後美好的東西。
“持續交付”和“DevOps”
我們挑兩個特別容易被網上的人或大家所對比的詞彙,一個是 持續交付 ,一個是 DevOps 。
持續交付也好,DevOps也好,他們的共同點是秉持交付思想,他們都崇尚精益思想,他們都喜歡自動化,他們都以快速和穩定的變更為目標,這是兩個共同點。持續交付偏向於將不同的過程集中起來,並且更快更頻繁地執行這個過程。
雖然我們對比了這兩個詞,但我希望大家不要過度陷入於概念本身,不是說我今天學的究竟是DevOps還是持續交付,這個沒有意義。我們要把好的思想帶回專案組,帶回團隊,能不能落地是我們的關注點,我們不要過多對比概念。
基礎參與人
凡是涉及人的話題,一定是比較特別的,你只要不把人的範圍說清楚,這個事情就別想落地。只要你沒說這個事情讓他做,他就不會主動問你,如果你主動問你說明這個人是優秀員工。
把敏捷開發單獨四個字列出來,持續部署跟持續交付看似範圍一樣,但持續交付指的是我有交付能力,但我沒說一定要部署到線上環境。持續部署講的是現在既然已經完成了構建的流水線,那麼就從頭走到尾就結束了,這個講的是自動化。DevOps講的是什麼?範圍好像一模一樣,但 DevOps不強調每一個角色應該幹什麼,而是將所有的角色彙集在一起 ,有點像敏捷思想裡面的 角色互換 ,大家誰都能幹這個事情,不用指定這個事情,大家可以角色互換一起來做,所以 DevOps不強調每一個人誰是誰,而是強調這些人彙集到一起之後,你能夠將開發編譯測試一次性完成 ,這是他們的區別點。
3.DevOps工程化
工程化這個詞不知道大家怎麼理解,你在寫程式碼的時候,我們說你的程式碼結構好,你的框架設計得好,這其實是一個工程,因為它落地。我們今天談的DevOps工程化也指的這個含義,到現在為止都是一些比較抽象的概念,它是一些比較好的理念,沒有具體的落地點,你無法感受到它真正的好。
如果你的團隊想要去實施DevOps,從我的觀點來說它由 四部分 組成。
流水線: 流水線一定要自動化,自動化的流水線必須是可靠、可重複、高效的流水線,你的流水線一定要視覺化,全程可見,出了問題可以提示你,將你的部署交付給他,完成到哪一步,完成的效果怎麼樣,我們需要有實時反饋和實時監督。
技術平臺和工具: 這個技術平臺我列了 容器 和 叢集 ,有人可能說我們公司也做了流水線,也做了自動化,沒有用容器做也挺好的。不知道有沒有人最近關注國際和國內比較流行的詞彙,最近我發現有兩種思維比較大,一個是微服務,一個是雲原生。
大家知道雲原生是什麼意思嗎?你的服務無論部署在哪一個雲服務的提供商上,它都可以正常去跑,這是一個基金會發起的非常好的倡議。你在百度雲上做的好好的,可以拿到阿里雲、華為雲去做,程式碼一行都不用變。如果你的部署方式基於物理機而不是容器,將來想做雲原生就很難,雲原生一定是歷史趨勢,我建議如果想實施,你可以提前往前多走一步,直接到容器化。使用容器有這麼幾點。一是既然使用容器一定要有標準化,你的容器是怎麼構建的,裡面包含哪些東西,需要啟動的方式是怎樣的,需要怎樣的執行,這都是需要你自己規劃跟設計的。
有了容器就要有私有映象倉庫,往DockerHub去推,如果被別人拿下來可能會造成程式碼洩露的問題,所以我們要搭建私有映象倉儲。再往下要有叢集,當前的叢集非常多,而且都非常成熟,從今年開始聊Kubernetes的人越來越多,因為去年它已經贏得了叢集的勝利。自從發表了1.3,現在有1.4,馬上要釋出1.5,現在越來越強大了,叢集這個事情越早越好,我相信有夢想的工程師都想創造出一個QPS幾十萬的服務。當這一瞬間突然來的時候,你的服務能不能扛得住?你的基礎設施夠不夠穩定?這就造成了極大的挑戰,這時候就需要叢集幫你管理一切。
如果有叢集,要提前構想微服務怎麼搭,怎麼充分利用叢集的價值。如果用微服務也好,用叢集也好,部署管理怎麼做,每一份要怎麼布,怎麼做熔斷機制,怎麼做監控報警,怎麼做擴容,所有的這些東西都需要自己提前考慮,需要提前想清楚。
人和角色: 主要分兩類, 開發測試 和 運維 。開發跟測試放在一起,因為我認為這兩個角色按道理來說是屬於一個工種。在谷歌其實是沒有測試這個職業的,他們都叫QA,都是質量控制幫你把控質量。在百度的時候也沒有測試的概念,QA前線大到什麼程度?開發了程式碼就不讓你上線,就懷疑有問題,因為我有資料,我發現你的執行速度慢了一毫秒,你將影響我們多少使用者?這些使用者加到一起是多少小時?你能承擔起嗎?他們一說我就沒話了,承擔不起就不上了,不上了老闆找誰?因為已經答應了上線。所以開發跟測試一定要搞好關係,我們是一起的,你一定要讓我上,你讓我上了請你吃飯,我們倆是一家人。這個是玩笑話,這兩個角色不要對立,它們是一起的,要共同搭建分支策略。大家一定會聽過標準程式碼分支管理,它們需要共同搭建持續整合。你提交任何一個程式碼進行持續整合,保證整個程式碼的質量持續穩定交付,就是需要持續整合作為保證和前提。
文化規則: 講到團隊文化,大家可能會覺得很虛,覺得不切實際,好像離我們很遠。
舉個例子 ,一個好的團隊文化,尤其是DevOps團隊或敏捷團隊,一定要講角色的互換。今天你做這件事情,明天可以做另一件事情。我們不是說缺了誰就不能上線,缺了誰公司就沒法轉,我們應該靈活轉變自己。現在有一個非常好的職位叫DevOps工程師,什麼都能幹,甚至DevOps工程師要強到什麼程度?他需要出來講課培訓DevOps,有時候客戶一諮詢,我解答不了,可能DevOps工程師寫著寫著程式碼就去回答問題了。
說完了整個架構圖,我們再從頭看一下 流水線的概念 。
這是DevOps和持續交付裡面標準的流水線。
程式編譯 --這個不用多說,無論開發哪個語言,除了指令碼語言之外,多數的語言都有編譯環節,原檔案要編譯要編譯成另外一種形態才能執行。
單元測試 --我建議大家有空都要寫單元測試,單元測試是非常好的東西,因為你寫了單元測試之後就會發現,你跟QA的關係會變得非常好,你就沒必要麻煩他了。
整合測試 --每一塊獨立的東西測試沒問題,放到一起之後測能不能正常工作?
效能測試 --你今天上的東西對於我們現在已經有的東西效能是有提升還是有損耗?
日誌測試 --很多東西表現沒問題,但日誌中總是報奇怪的錯誤,有些人意識好,可能會打各種各樣的debug。如果你有了日誌分析這一步,一定會發現潛在地方有潛在的漏洞,也許到了線上會變更成嚴重的問題,這個東西在寫單元測試的時候可能考慮不到,我們需要這幾步來保證持續整合的正確性。到這為止是持續整合的核心。
映象 --將現在所有的東西放到一起,打成最終的映象,把映象上傳到雲端,專業術語叫製品庫。
預釋出、驗收、部署上線 --驗收是預釋出環境做迴歸測試,沒有問題就可以直接上線,這個地方可以手動也可以自動,我們只講流水線不講到底指持續部署還是持續交付。
實戰入門
演示時用到的技術如果大家沒有接觸過也沒關係,一步一步來就好了。
Gitlab、Docker、Kubernetes、Helm、Harbor、Jenkins這些都是比較標準的,只是入門,我們只是加強這個意識。
首先我們要進行程式碼分支規範。主幹分支切開發分支,完成之後向開發分支提程式碼,這時候會觸發持續整合,驗證向分支提交程式碼是否安全是否對,剛才的東西跑沒跑過,跑過要加入程式碼質量跟程式碼的review,沒有問題往下走,開發分支結束,我們把東西提交到個人分支上,把程式碼部署到某一個環境,假如說是測試環境。
這是持續部署的簡單示意圖
Github發起通知Jenkins Job1,Job1告訴Job2,在Job2中上傳映象,把映象傳到Helm裡,通過Kubernetes部署到Pod節點中,完成部署。我們把Job2開啟,Job2被觸發。為什麼我剛才把Job1跟Job2分開?因為對應的不一樣。Job1對應專案程式碼,Job2對應部署程式碼,我們現在把它們解耦分開,現在Job2可以複用,可以構建非常多的專案。
在構建的時候需要製作映象、上傳映象、部署映象,每一步都可以用指令碼語言實現,通過Jenkins、file串聯起來,入門的時候做好這塊就可以了。
這套流水線能不能用在不同的環境上?可以,要做環境的配置管理,需要你在叢集裡面做一些操作,在Kubernetes的檔案裡說明這裡面需要部署多少的資源,需要使用多少東西。Chart檔案可以幫你輔助,把不同的環境區分開。
講完了工具講文化,實施之後進一步落地DevOps怎麼辦?資源管理必不可少,分成幾步: 監控報警、行為規範、常用指令碼、操作指南 。每一步都很重要,怎麼去監控?監控要注意哪些事項?怎麼定義行為規範?指令碼很重要,指令碼越多越好,能自動化不要手動,多寫一些文件,供別人使用,新人文件也好,甚至是操作指南,或者線上文件怎麼布,用文件記錄下來總沒有壞處。
相信一小時之後,你可能就已經忘記我說的是什麼了,沒關係我不在意,但你一定要記住這張圖。
如果你的團隊想實施DevOps,四個因素一定要有:
自動化流水線
技術平臺和工具
人和角色
文化和規則 。
這四個一個都不能缺,缺一個都不能叫DevOps團隊,只能叫感覺還不錯的團隊 。
總結
沒有最好的實踐,只有最合適的實踐,每個公司落地的方案都不盡相同。希望大家在不斷探索更好的過程中,找到自己團隊適合的DevOps解決方案。
認真可以把一件事做對,用心可以把一件事做好。
文章來源:Worktile敏捷部落格
歡迎訪問交流更多關於技術及協作的問題。
文章轉載請註明出處。