關於DevOps CI/CD Pipeline,看這篇就夠了 | IDCF

2021-05-06 09:00:35

提到DevOps,很多人就想到了CI/CD Pipeline,甚至很多個人或者企業認為完成了CI/CD Pipeline就等於實現了DevOps,雖然這種觀點有失偏頗,但是從側面反映了CI/CD Pipeline在DevOps中扮演著舉足輕重的地位。CI/CD 是DevOps 的兩大關鍵核心能力。CI/CD Pipeline的真正實現會加速企業向DevOps轉型的程序。本文將揭開CI/CD Pipeline的神祕面紗,來一探究竟。

一、什麼是 CI/CD Pipeline

Pipeline 指管道或者流水線,類似於工廠裡的生產線,原料從一端輸入,中間經過多個工作中心,一個工作中心的輸出作為下一個工作中心的輸入,最終在另一端輸出高品質的產品。CI/CD Pipeline 指CI/CD的流水線,在輸入端輸入原始碼,經過既定工作流,最後在輸出端輸出對使用者有價值的產品。從字面就能看出側重點持續、流水線。

CI/CD Pipeline的簡單示意圖如下。

image.png

開發人員提交完程式碼,經過一系列的流程,最後生產出有價值的應用程式。

二、為什麼需要 CI/CD Pipeline

DevOps的出現就是為了解決實際問題:打破橫亙於開發人員與運維人員之間的壁壘。CI/CD Pipeline 可以幫助實現這個目的:開發人員在程式碼提交之後,就有CI/CD 流程來對所開發程式碼的功能性,健壯性,安全性等進行驗證,如果驗證失敗,就返回至開發人員處,繼續修改;如果通過既定流程,就可以進行生產部署。

當然,整個流程必須是完備的,測試環節必須是嚴謹的,開發環境,測試環境,生產環境應儘量保持一致,以此來避免環境不一致導致的上線失敗。且整個過程中所有的變更,包括程式碼變更,部署指令碼變更,環境設定變更都是可追蹤的,便於出現問題之後進行回溯與覆盤。這樣,開發人員就不會擔心程式碼不能夠及時部署到生產線,而運維也不必擔心新上線的程式碼會導致系統崩潰。

此外,CI/CD pipeline 有助於縮短應用程式的釋出週期,提高應用程式的釋出頻率,快速獲得市場反饋,及時作出響應。這種良性迴圈有助於應用程式搶佔市場,給企業帶來效益。

《鳳凰專案: 一個IT運維的傳奇故事》中比爾團隊的故事就是對上述過程的一個很好佐證:當比爾團隊將鳳凰專案的部署流程梳理清楚之後,進行了"流水線"(書中雖不叫CI/CD Pipeline,但是內容卻是一樣,可以認為是CI/CD Pipeline的雛形)改造,在大大提高鳳凰專案發布頻率的同時,業務部門與IT部門之間的矛盾也變得越來越少,公司盈利了,也就避免公司被拆分,IT部門被外包的風險。

基於此,CI/CD Pipeline 一般具有以下幾個特點:

  • 標準化的步驟:應用程式交付流水線中的構建,測試等步驟,一個都不能少,而且環環相扣。
  • 可自動部署:從程式碼提交那一刻起,一切流程都應該是自動的,自動化的好處毋庸置疑:節省時間,減少人為干預,避免人為誤操作;"一鍵式"部署讓部署變得簡單。
  • 適用多種語言:CI/CD Pipeline 應該適用於大多數甚至全部語言型別的應用程式,java,php,python。可能只需針對不同語言做少量調整。而不需要每種語言對應自己的CI/CD Pipeline。
  • 具備可移植能性:應用程式在不同部署環境下(比如從公有云到私有云,從AWS的Kubernetes 平臺到IBM的Kubernetes 平臺)遷移的時候,Pipeline 可以在不改動或者少量改動的前提下,完成遷移,這樣提高了靈活性,減少了工作量。

三、CI/CD Pipeline 包含的階段

一般來講應用程式交付流水線有如下圖所示的幾個階段:

image.png

3.1 計劃階段

此階段主要是專案經理或產品經理從使用者處獲取應用程式的相關資訊,從而制定開發計劃,來對後期開發進行指導。在敏捷盛行的今天,很多公司在此階段都用敏捷來進行開發管理,以迭代的方式來完成使用者故事的開發。

3.2 編碼階段

這個階段主要是開發人員通過IDE來進行程式碼開發,開發人員藉助於安裝在IDE內的一些外掛,來編寫符合公司編碼規範和安全需求的程式碼。

3.3 構建階段

構建階段是可以算是CI/CD Pipeline的真正開始階段,開發人員在本地完成程式碼開發,並將程式碼提交到原始碼控制工具(比如git),此時會觸發CI流程,進行程式碼掃描,編譯,單元測試及覆蓋率測試等工作。如果流程是成功的,那麼程式碼就會被合入主幹分支(合併可以是手動,也可以是自動,這取決於專案的開發模式與規定)。而一旦某個環節出現失敗,都會使得整個流程中斷,並將相應資訊反饋至開發人員處。

3.4 測試階段

程式碼被部署到測試環境並展開一系列的測試工作,包括手動的,自動的;功能的,效能的,安全的。需要注意的是,此階段測試所需環境最好與生產環境保持一致,避免因環境不一致導致的上線失敗。

3.5 版本準備階段

測試階段驗證成功以後,可以認為程式碼已具備上生產的能力,測試通過的版本被標記為可以上生產,只需要手動或者自動操作(取決於專案規定)就可以將版本推播至生產線上。

3.6 部署階段

將應用程式部署到生產線上。可以採用手動或者自動的方式來完成部署,同時可以採用藍綠部署,金絲雀部署等方式來實現"零宕機"、安全部署。

3.7 維護階段

應用程式上線後,運維團隊需要確保應用程式執行環境的穩定,在存取量高的時刻能夠自動擴容來應對峰值,存取量低的時候縮容以減少資源消耗。

3.8 監控階段

監控應該包含兩方面的:應用程式的監控和Pipeline的監控,藉助於監控工具來獲取一些有效資料,然後反饋給開發團隊,或者運維團隊,以此來進一步提高應用程式及Pipeline的穩定性,安全性。

CI/CD Pipeline 幾乎等同於應用程式交付流水線,它與之相對應階段的關係如下圖所示。應用程式交付流程從計劃階段開始,而CI/CD Pipeline開始於應用程式開發階段。

image.png

四、CI/CD Pipeline 的實現

CI/CD Pipeline 也可以用三步工作法來實現:

  • 第一步:實現從輸入端原始碼到輸出端產品的正向流程,將原始碼構建,測試,版本準備,部署,運維幾個步驟串起來;

image.png

  • 第二步:實現從各個階段至開發階段的持續反饋;

image.png

  • 第三步:在執行過程中與開發,安全等團隊合作進行持續改進。比如,讓部署流程、檢測報告、監控資訊視覺化。

image.png

CI/CD Pipeline 的實現要依賴於一些工具,這也就是為什麼很多人說DevOps是工具的合集的一個重要原因。雖然觀點不全面,但是工具確實是實現DevOps不可缺少的一環。

工具的選擇可以遵循以下幾個原則:

  • 擁抱開源

擁抱開源儼然已成為IT行業的一種新趨勢,開源意味著免費,這可以進一步降低企業成本,另外開放的原始碼對軟體問題的追根溯源有很大幫助,最重要的一點是,可以藉助於開源來快速推出有價值的商用產品,比如藉助於開源的Linux,Redhat公司推出企業級的Linux產品;藉助於開源的Docker和Kubernetes,亞馬遜,微軟,谷歌,IBM等公司都加速完成了自己企業級雲產品的商用。

  • 社群強大,使用者數多

開源工具的選擇必須要考慮社群的大小和使用者的多少,社群大,使用者多,開源工具的迭代就快,功能就強大,出問題也能找到相應的解決方法。比如 Jenkins,強大的中英文社群,超過千萬的使用者,讓其變成了最後歡迎的一款持續整合工具。

  • 豐富的API

CI/CD Pipeline 是工具的集合,工作中心與工作中心的就是工具與工具之間的互動,也就是API的相互呼叫,如果一款工具具有豐富的API,那麼就比較容易將其整合進CI/CD Pipeline。比如Github,就有關於release,commit,pull request等各種API。

  • 易學易用

一款工具能夠快速上手,容易使用,就能夠加速CI/CD Pipeline的開發,降低CI/CD Pipeline的維護難度,大大減少了工作量。

五、CI/CD Pipeline 發展趨勢

CI/CD Pipeline 一直在發展演進,其主要的發展變化有以下幾點:

5.1 雲原生

CI/CD Pipeline 的發展方向跟應用程式是一樣的:雲原生。有一些雲原生的CI/CD Pipeline工具,比如Jenkins,Tekton等已經出現,它們能夠進一步提高CI/CD Pipeline的效率,加速雲原生應用程式的構建。

5.2 GitOps 和ChatOps

GitOps 和 ChatOps 將佔據重要的戲份。GitOps 和ChatOps 可以將團隊,工具,流程,自動化等組成一個高效的、透明的工作流,工作進度一目瞭然,所有變更可控、可回溯跟蹤,產品的研發效率會隨著團隊之間溝通協調效率的增加而提高。

Github Action就是GitOps的一個典型例子。Slack 的bot 就是ChatOps的一個典型例子。

5.3 平臺化

平臺化的好處毋庸置疑:通過將工具,流程的有效整合,使得軟體開發生命週期的整個流程透明化,資料視覺化,部署流程自動化,為持續反饋,持續改進提供重要依據。

六、CI/CD Pipeline 的一些反模式

6.1 與開發沒有關係

開發人員對於Pipeline的認識不足,開發模式不做任何改變。程式碼提交頻率沒有提升,可能是三天一次,甚至是一個新功能提交一次。這樣就不能充分發揮Pipeline所帶來的優勢,產品釋出頻率就不高。此外,開發認定的工作範圍只是到提交完程式碼的那一刻,不去關心整體流程的成功與否,不去獲得持續反饋資訊。一旦出問題了,就直接找運維。一次次的 "穿新鞋,走老路" 也就導致DevOps 轉型的失敗。

6.2 構建時間太長

為了保證程式碼品質,實現一鍵式部署,Pipeline會整合所有的步驟,Pipeline就顯得格外臃腫,一次構建需要幾十分鐘,甚至幾個小時(比如採用appscan完成程式碼的動靜態掃描)。開發人員不願意提交一次程式碼,等待如此長時間的構建。就會降低程式碼提交頻率,一次提交多個變更。由此,Pipeline成了提高產品釋出頻率的瓶頸,持續整合和持續部署就更無從談起了。Pipeline應支援產品隨時隨地部署,可以一天完成多次部署要求。就好比一條路,不限制上面跑的是人還是車,跑多快,有多少。

6.3 反饋資訊簡單

當某個步驟的失敗導致整個流程終止時,僅僅用一句構建失敗來通知相關人員。這種不明確的通知就需要相關人員齊上陣一起查處問題的根源,這是一種浪費。構建過程中產生的資訊應儘量詳細,比如程式碼編譯失敗,單元測試失敗,映象檢測有漏洞等。如果是微服務,還應該明確是哪個服務。這樣在第一時間就有相應的責任人去快速修復。

6.4 漏洞是安全團隊的事情

當掃描出安全漏洞時,都認為是安全團隊的工作範疇。報告在,沒人管。其實,安全的範圍很大,錯誤的設定資訊,程式碼中的敏感資訊,都算是漏洞。不同層面的漏洞應該有不同的團隊來負責,比如與應用程式程式碼相關的應該是開發團隊負責,與基礎設施相關的應該是運維團隊負責,而且兩個團隊應該與安全團隊協調合作,共同修復漏洞。

6.5 不合理的人工干預

當修復緊急故障的程式碼覆蓋率不達標,但又不得不上線時,通過降低,甚至取消程式碼覆蓋率檢測來使Pipeline成功;當Pipeline在最後一步失敗時,為了節省時間,避免重新構建時,通過手動修改流程或者設定來完成Pipeline。這種為了節省時間而引入的不合理的人工干預,破壞了Pipeline的完整性,人工干預是不可追蹤的,引起的故障很難回溯。Pipeline 是一個流程,既然是流程,就應該根據流程走。

6.6 害怕失敗

害怕構建失敗,失敗就意味著程式碼有問題,大家集體炸鍋。為了每次構建都得到綠色的結果,調低檢測閾值,剪掉經常出錯的步驟,最後是開發happy,運維happy,測試happy,大家集體happy。其實,失敗是持續改進的推動力。持續改進的Pipeline才是實用的Pipeline。

七、結束語

可以看到,"流程 + 工具 + 自動化 ≈ CI/CD Pipeline" 。也就不難理解,為什麼會有DevOps就是流程,就是工具的集合,就是自動化等這些誤區的存在。DevOps是一場文化運動,CI/CD Pipeline是這場運動在企業落地實踐的強有力手段。

附錄

下圖是基於Kubernetes平臺的一個CI/CD Pipeline 範例,僅供參考。

圖中出現的工具均為開源工具,但不是說圖中出現的工具就是最好的,必選的,工具的選擇需根據前述原則來進行。
最下面的屬於監控系統,通知系統,每套環境都用到了,而且貫穿整個流程。所以只畫一次。
CI 流程如果成功,既可以手動也可以自動部署測試環境;同樣的,如果測試環境測試成功,既可以手動也可以自動部署生產環境。以此完成CD流程。

image.png

image.png

作者:馬景賀

馬景賀,人稱小馬哥,花名逍遙子。曾做過LTE 4G網路協定開發,後轉向 DevOps,對於Cloud Native DevSecOps進行佈道,喜歡研究docker,kubernetes,istio等Cloud Native相關技術,樂於分享,運營著DevOps SIG公眾號。曾在大連DevOps社群活動上,舉辦DevOps Workshop活動。

參考資料

來源:CIO Talk

5月每週四晚8點,【冬哥有話說】品質與測試專場。公眾號留言「品質」可獲取地址

  • 0506 朱少民 《如何最大化軟體測試效能》
  • 0513 神祕嘉賓 神祕話題
  • 0520 陳霽 《沒錯,去QA是提高品質最有效的方法!》
  • 0527 施慧斌 《DevOps實踐之持續測試》