什麼是 CI/CD?

什麼是 CI/CD?

什麼是 CI/CD?

在軟件開發中常常會提到持續集成Continuous Integration(CI)和持續交付Continuous Delivery(CD)這幾個術語。但它們真正的意思是什麼呢?
在本文中,我將解釋這些和相關術語背後的含義和意義,例如持續測試Continuous Testing和持續部署Continuous Deployment。
什麼是 CI/CD?
工廠裏的裝配線以快速、自動化、可重複的方式從原材料生產出消費品。一樣,軟件交付管道以快速、自動化和可重複的方式從源代碼生成發佈版本。如何完成這項工做的整體設計稱爲「持續交付」(CD)。啓動裝配線的過程稱爲「持續集成」(CI)。確保質量的過程稱爲「持續測試」,將最終產品提供給用戶的過程稱爲「持續部署」。一些專家讓這一切簡單、順暢、高效地運行,這些人被稱爲運維開發DevOps踐行者。
什麼是 CI/CD?
「持續」用於描述遵循我在此提到的許多不一樣流程實踐。這並不意味着「一直在運行」,而是「隨時可運行」。在軟件開發領域,它還包括幾個核心概念/最佳實踐。這些是:web

  • 頻繁發佈:持續實踐背後的目標是可以頻繁地交付高質量的軟件。此處的交付頻率是可變的,可由開發團隊或公司定義。對於某些產品,一季度、一個月、一週或一天交付一次可能已經足夠頻繁了。對於另外一些來講,一天可能須要屢次交付也是可行的。所謂持續也有「偶爾、按需」的方面。最終目標是相同的:在可重複、可靠的過程當中爲最終用戶提供高質量的軟件更新。一般,這能夠經過不多甚至無需用戶的交互或掌握的知識來完成(想一想設備更新)。
  • 自動化流程:實現此頻率的關鍵是用自動化流程來處理軟件生產中的方方面面。這包括構建、測試、分析、版本控制,以及在某些狀況下的部署。
  • 可重複:若是咱們使用的自動化流程在給定相同輸入的狀況下始終具備相同的行爲,則這個過程應該是可重複的。也就是說,若是咱們把某個歷史版本的代碼做爲輸入,咱們應該獲得對應相同的可交付產出。這也假設咱們有相同版本的外部依賴項(即咱們不建立該版本代碼使用的其它交付物)。理想狀況下,這也意味着能夠對管道中的流程進行版本控制和重建(請參閱稍後的 DevOps 討論)。
  • 快速迭代:「快速」在這裏是個相對術語,但不管軟件更新/發佈的頻率如何,預期的持續過程都會以高效的方式將源代碼轉換爲交付物。自動化負責大部分工做,但自動化處理的過程可能仍然很慢。例如,對於天天須要屢次發佈候選版更新的產品來講,一輪集成測試integrated testing下來耗時就要大半天可能就太慢了。

什麼是 CI/CD?
將源代碼轉換爲可發佈產品的多個不一樣的任務task和做業job一般串聯成一個軟件「管道」,一個自動流程成功完成後會啓動管道中的下一個流程。這些管道有許多不一樣的叫法,例如持續交付管道、部署管道和軟件開發管道。大致上講,程序管理者在管道執行時管理管道各部分的定義、運行、監控和報告。
什麼是 CI/CD?
軟件交付管道的實際實現能夠有很大不一樣。有許多程序可用在管道中,用於源代碼跟蹤、構建、測試、指標採集,版本管理等各個方面。但總體工做流程一般是相同的。單個業務流程/工做流應用程序管理整個管道,每一個流程做爲獨立的做業運行或由該應用程序進行階段管理。一般,在業務流程中,這些獨立做業是以應用程序可理解並可做爲工做流程管理的語法和結構定義的。數組

這些做業被用於一個或多個功能(構建、測試、部署等)。每一個做業可能使用不一樣的技術或多種技術。關鍵是做業是自動化的、高效的,而且可重複的。若是做業成功,則工做流管理器將觸發管道中的下一個做業。若是做業失敗,工做流管理器會向開發人員、測試人員和其餘人發出警報,以便他們儘快糾正問題。這個過程是自動化的,因此比手動運行一組過程可更快地找到錯誤。這種快速排錯稱爲快速失敗fail fast,而且在抵達管道端點方面一樣有價值。
什麼是 CI/CD?
管道的工做之一就是快速處理變動。另外一個是監視建立發佈的不一樣任務/做業。因爲編譯失敗或測試未經過的代碼能夠阻止管道繼續運行,所以快速通知用戶此類狀況很是重要。快速失敗指的是在管道流程中儘快發現問題並快速通知用戶的方式,這樣能夠及時修正問題並從新提交代碼以便使管道再次運行。一般在管道流程中可經過查看歷史記錄來肯定是誰作了那次修改並通知此人及其團隊。
什麼是 CI/CD?
管道的幾乎全部部分都是應該自動化的。對於某些部分,有一些人爲干預/互動的地方多是有意義的。一個例子多是用戶驗收測試user-acceptance testing(讓最終用戶試用軟件並確保它能達到他們想要/指望的水平)。另外一種狀況多是部署到生產環境時用戶但願擁有更多的人爲控制。固然,若是代碼不正確或不能運行,則須要人工干預。網絡

有了對「持續」含義理解的背景,讓咱們看看不一樣類型的持續流程以及它們在軟件管道上下文中的含義。
什麼是 CI/CD?
持續集成(CI)是在源代碼變動後自動檢測、拉取、構建和(在大多數狀況下)進行單元測試的過程。持續集成是啓動管道的環節(儘管某些預驗證 —— 一般稱爲上線前檢查pre-flight checks —— 有時會被歸在持續集成以前)。架構

持續集成的目標是快速確保開發人員新提交的變動是好的,而且適合在代碼庫中進一步使用。
什麼是 CI/CD?
持續集成的基本思想是讓一個自動化過程監測一個或多個源代碼倉庫是否有變動。當變動被推送到倉庫時,它會監測到更改、下載副本、構建並運行任何相關的單元測試。
什麼是 CI/CD?
目前,監測程序一般是像 Jenkins 這樣的應用程序,它還協調管道中運行的全部(或大多數)進程,監視變動是其功能之一。監測程序能夠以幾種不一樣方式監測變動。這些包括:app

  • 輪詢:監測程序反覆詢問代碼管理系統,「代碼倉庫裏有什麼我感興趣的新東西嗎?」當代碼管理系統有新的變動時,監測程序會「喚醒」並完成其工做以獲取新代碼並構建/測試它。
  • 按期:監測程序配置爲按期啓動構建,不管源碼是否有變動。理想狀況下,若是沒有變動,則不會構建任何新內容,所以這不會增長額外的成本。
  • 推送:這與用於代碼管理系統檢查的監測程序相反。在這種狀況下,代碼管理系統被配置爲提交變動到倉庫時將「推送」一個通知到監測程序。最多見的是,這能夠以 webhook 的形式完成 —— 在新代碼被推送時一個掛勾hook的程序經過互聯網向監測程序發送通知。爲此,監測程序必須具備能夠經過網絡接收 webhook 信息的開放端口。
    什麼是 CI/CD?
    在將代碼引入倉庫並觸發持續集成以前,能夠進行其它驗證。這遵循了最佳實踐,例如測試構建test build和代碼審查code review。它們一般在代碼引入管道以前構建到開發過程當中。可是一些管道也可能將它們做爲其監控流程或工做流的一部分。

例如,一個名爲 Gerrit 的工具容許在開發人員推送代碼以後但在容許進入(Git 遠程)倉庫以前進行正式的代碼審查、驗證和測試構建。Gerrit 位於開發人員的工做區和 Git 遠程倉庫之間。它會「接收」來自開發人員的推送,而且能夠執行經過/失敗驗證以確保它們在被容許進入倉庫以前的檢查是經過的。這能夠包括檢測新變動並啓動構建測試(CI 的一種形式)。它還容許開發者在那時進行正式的代碼審查。這種方式有一種額外的可信度評估機制,即當變動的代碼被合併到代碼庫中時不會破壞任何內容。框架

什麼是 CI/CD?
單元測試(也稱爲「提交測試」),是由開發人員編寫的小型的專項測試,以確保新代碼獨立工做。「獨立」這裏意味着不依賴或調用其它不可直接訪問的代碼,也不依賴外部數據源或其它模塊。若是運行代碼須要這樣的依賴關係,那麼這些資源能夠用模擬mock來表示。模擬是指使用看起來像資源的代碼存根code stub,能夠返回值,但不實現任何功能。運維

在大多數組織中,開發人員負責建立單元測試以證實其代碼正確。事實上,一種稱爲測試驅動開發test-driven develop(TDD)的模型要求將首先設計單元測試做爲清楚地驗證代碼功能的基礎。由於這樣的代碼能夠更改速度快且改動量大,因此它們也必須執行很快。ide

因爲這與持續集成工做流有關,所以開發人員在本地工做環境中編寫或更新代碼,並通單元測試來確保新開發的功能或方法正確。一般,這些測試採用斷言形式,即函數或方法的給定輸入集產生給定的輸出集。它們一般進行測試以確保正確標記和處理出錯條件。有不少單元測試框架都頗有用,例如用於 Java 開發的 JUnit。
什麼是 CI/CD?
持續測試是指在代碼經過持續交付管道時運行擴展範圍的自動化測試的實踐。單元測試一般與構建過程集成,做爲持續集成階段的一部分,並專一於和其它與之交互的代碼隔離的測試。函數

除此以外,能夠有或者應該有各類形式的測試。這些可包括:工具

  • 集成測試 驗證組件和服務組合在一塊兒是否正常。
  • 功能測試 驗證產品中執行功能的結果是否符合預期。
  • 驗收測試 根據可接受的標準驗證產品的某些特徵。如性能、可伸縮性、抗壓能力和容量。
    全部這些可能不存在於自動化的管道中,而且一些不一樣類型的測試分類界限也不是很清晰。可是,在交付管道中持續測試的目標始終是相同的:經過持續的測試級別證實代碼的質量能夠在正在進行的發佈中使用。在持續集成快速的原則基礎上,第二個目標是快速發現問題並提醒開發團隊。這一般被稱爲快速失敗。
    什麼是 CI/CD?
    除了測試是否經過以外,還有一些應用程序能夠告訴咱們測試用例執行(覆蓋)的源代碼行數。這是一個能夠衡量代碼量指標的例子。這個指標稱爲代碼覆蓋率code-coverage,能夠經過工具(例如用於 Java 的 JaCoCo)進行統計。

還有不少其它類型的指標統計,例如代碼行數、複雜度以及代碼結構對比分析等。諸如 SonarQube 之類的工具能夠檢查源代碼並計算這些指標。此外,用戶還能夠爲他們可接受的「合格」範圍的指標設置閾值。而後能夠在管道中針對這些閾值設置一個檢查,若是結果不在可接受範圍內,則流程終端上。SonarQube 等應用程序具備很高的可配置性,能夠設置僅檢查團隊感興趣的內容。
什麼是 CI/CD?
持續交付(CD)一般是指整個流程鏈(管道),它自動監測源代碼變動並經過構建、測試、打包和相關操做運行它們以生成可部署的版本,基本上沒有任何人爲干預。

持續交付在軟件開發過程當中的目標是自動化、效率、可靠性、可重複性和質量保障(經過持續測試)。

持續交付包含持續集成(自動檢測源代碼變動、執行構建過程、運行單元測試以驗證變動),持續測試(對代碼運行各類測試以保障代碼質量),和(可選)持續部署(經過管道發佈版本自動提供給用戶)。
什麼是 CI/CD?
版本控制是持續交付和管道的關鍵概念。持續意味着可以常常集成新代碼並提供更新版本。但這並不意味着每一個人都想要「最新、最好的」。對於想要開發或測試已知的穩定版本的內部團隊來講尤爲如此。所以,管道建立並輕鬆存儲和訪問的這些版本化對象很是重要。

在管道中從源代碼建立的對象一般能夠稱爲工件artifact。工件在構建時應該有應用於它們的版本。將版本號分配給工件的推薦策略稱爲語義化版本控制semantic versioning。(這也適用於從外部源引入的依賴工件的版本。)

語義版本號有三個部分:主要版本major、次要版本minor 和 補丁版本patch。(例如,1.4.3 反映了主要版本 1,次要版本 4 和補丁版本 3。)這個想法是,其中一個部分的更改表示工件中的更新級別。主要版本僅針對不兼容的 API 更改而遞增。當以向後兼容backward-compatible的方式添加功能時,次要版本會增長。當進行向後兼容的版本 bug 修復時,補丁版本會增長。這些是建議的指導方針,但只要團隊在整個組織內以一致且易於理解的方式這樣作,團隊就能夠自由地改變這種方法。例如,每次爲發佈完成構建時增長的數字能夠放在補丁字段中。
什麼是 CI/CD?
團隊能夠爲工件分配分銷promotion級別以指示適用於測試、生產等環境或用途。有不少方法。能夠用 Jenkins 或 Artifactory 等應用程序進行分銷。或者一個簡單的方案能夠在版本號字符串的末尾添加標籤。例如,-snapshot 能夠指示用於構建工件的代碼的最新版本(快照)。可使用各類分銷策略或工具將工件「提高」到其它級別,例如 -milestone 或 -production,做爲工件穩定性和完備性版本的標記。
什麼是 CI/CD?
從源代碼構建的版本化工件能夠經過管理工件倉庫artifact repository的應用程序進行存儲。工件倉庫就像構建工件的版本控制工具同樣。像 Artifactory 或 Nexus 這類應用能夠接受版本化工件,存儲和跟蹤它們,並提供檢索的方法。

管道用戶能夠指定他們想要使用的版本,並在這些版本中使用管道。
什麼是 CI/CD?
持續部署(CD)是指可以自動提供持續交付管道中發佈版本給最終用戶使用的想法。根據用戶的安裝方式,多是在雲環境中自動部署、app 升級(如手機上的應用程序)、更新網站或只更新可用版本列表。

這裏的一個重點是,僅僅由於能夠進行持續部署並不意味着始終部署來自管道的每組可交付成果。它實際上指,經過管道每套可交付成果都被證實是「可部署的」。這在很大程度上是由持續測試的連續級別完成的(參見本文中的持續測試部分)。

管道構建的發佈成果是否被部署能夠經過人工決策,或利用在徹底部署以前「試用」發佈的各類方法來進行控制。
什麼是 CI/CD?
因爲必須回滾/撤消對全部用戶的部署多是一種代價高昂的狀況(不管是技術上仍是用戶的感知),已經有許多技術容許「嘗試」部署新功能並在發現問題時輕鬆「撤消」它們。這些包括
什麼是 CI/CD?
在這種部署軟件的方法中,維護了兩個相同的主機環境 —— 一個「藍色」 和一個「綠色」。(顏色並不重要,僅做爲標識。)對應來講,其中一個是「生產環境」,另外一個是「預發佈環境」。

在這些實例的前面是調度系統,它們充當產品或應用程序的客戶「網關」。經過將調度系統指向藍色或綠色實例,能夠將客戶流量引流到指望的部署環境。經過這種方式,切換指向哪一個部署實例(藍色或綠色)對用戶來講是快速,簡單和透明的。

當新版本準備好進行測試時,能夠將其部署到非生產環境中。在通過測試和批准後,能夠更改調度系統設置以將傳入的線上流量指向它(所以它將成爲新的生產站點)。如今,曾做爲生產環境實例可供下一次候選發佈使用。

同理,若是在最新部署中發現問題而且以前的生產實例仍然可用,則簡單的更改能夠將客戶流量引流回到以前的生產實例 —— 有效地將問題實例「下線」而且回滾到之前的版本。而後有問題的新實例能夠在其它區域中修復。
什麼是 CI/CD?
在某些狀況下,經過藍/綠髮布切換整個部署可能不可行或不是指望的那樣。另外一種方法是爲金絲雀canary測試/部署。在這種模型中,一部分客戶流量被從新引流到新的版本部署中。例如,新版本的搜索服務能夠與當前服務的生產版本一塊兒部署。而後,能夠將 10% 的搜索查詢引流到新版本,以在生產環境中對其進行測試。

若是服務那些流量的新版本沒問題,那麼可能會有更多的流量會被逐漸引流過去。若是仍然沒有問題出現,那麼隨着時間的推移,能夠對新版本增量部署,直到 100% 的流量都調度到新版本。這有效地「更替」了之前版本的服務,並讓新版本對全部客戶生效。
什麼是 CI/CD?
對於可能須要輕鬆關掉的新功能(若是發現問題),開發人員能夠添加功能開關feature toggles。這是代碼中的 if-then 軟件功能開關,僅在設置數據值時才激活新代碼。此數據值能夠是全局可訪問的位置,部署的應用程序將檢查該位置是否應執行新代碼。若是設置了數據值,則執行代碼;若是沒有,則不執行。

這爲開發人員提供了一個遠程「終止開關」,以便在部署到生產環境後發現問題時關閉新功能。
什麼是 CI/CD?
在暗箱發佈dark launch中,代碼被逐步測試/部署到生產環境中,可是用戶不會看到更改(所以名稱中有暗箱dark一詞)。例如,在生產版本中,網頁查詢的某些部分可能會重定向到查詢新數據源的服務。開發人員可收集此信息進行分析,而不會將有關接口,事務或結果的任何信息暴露給用戶。

這個想法是想獲取候選版本在生產環境負載下如何執行的真實信息,而不會影響用戶或改變他們的經驗。隨着時間的推移,能夠調度更多負載,直到遇到問題或認爲新功能已準備好供全部人使用。實際上功能開關標誌可用於這種暗箱發佈機制。
什麼是 CI/CD?
DevOps 是關於如何使開發和運維團隊更容易合做開發和發佈軟件的一系列想法和推薦的實踐。從歷史上看,開發團隊研發了產品,但沒有像客戶那樣以常規、可重複的方式安裝/部署它們。在整個週期中,這組安裝/部署任務(以及其它支持任務)留給運維團隊負責。這常常致使不少混亂和問題,由於運維團隊在後期纔開始介入,而且必須在短期內完成他們的工做。一樣,開發團隊常常處於不利地位 —— 由於他們沒有充分測試產品的安裝/部署功能,他們可能會對該過程當中出現的問題感到驚訝。

這每每致使開發和運維團隊之間嚴重脫節和缺少合做。DevOps 理念主張是貫穿整個開發週期的開發和運維綜合協做的工做方式,就像持續交付那樣。
什麼是 CI/CD?
持續交付管道是幾個 DevOps 理念的實現。產品開發的後期階段(如打包和部署)始終能夠在管道的每次運行中完成,而不是等待產品開發週期中的特定時間。一樣,從開發到部署過程當中,開發和運維均可以清楚地看到事情什麼時候起做用,什麼時候不起做用。要使持續交付管道循環成功,不只要經過與開發相關的流程,還要經過與運維相關的流程。

說得更遠一些,DevOps 建議實現管道的基礎架構也會被視爲代碼。也就是說,它應該自動配置、可跟蹤、易於修改,並在管道發生變化時觸發新一輪運行。這能夠經過將管道實現爲代碼來完成。
什麼是 CI/CD?
管道即代碼pipeline-as-code是經過編寫代碼建立管道做業/任務的通用術語,就像開發人員編寫代碼同樣。它的目標是將管道實現表示爲代碼,以便它能夠與代碼一塊兒存儲、評審、跟蹤,若是出現問題而且必須終止管道,則能夠輕鬆地重建。有幾個工具容許這樣作,如 Jenkins 2。
什麼是 CI/CD?
傳統意義上,管道中使用的各個硬件系統都有配套的軟件(操做系統、應用程序、開發工具等)。在極端狀況下,每一個系統都是手工設置來定製的。這意味着當系統出現問題或須要更新時,這一般也是一項自定義任務。這種方法違背了持續交付的基本理念,即具備易於重現和可跟蹤的環境。

多年來,不少應用被開發用於標準化交付(安裝和配置)系統。一樣,虛擬機virtual machine被開發爲模擬在其它計算機之上運行的計算機程序。這些 VM 要有管理程序才能在底層主機系統上運行,而且它們須要本身的操做系統副本才能運行。

後來有了容器container。容器雖然在概念上與 VM 相似,但工做方式不一樣。它們只需使用一些現有的操做系統結構來劃分隔離空間,而不須要運行單獨的程序和操做系統的副本。所以,它們的行爲相似於 VM 以提供隔離但不須要過多的開銷。

VM 和容器是根據配置定義建立的,所以能夠輕易地銷燬和重建,而不會影響運行它們的主機系統。這容許運行管道的系統也可重建。此外,對於容器,咱們能夠跟蹤其構建定義文件的更改 —— 就像對源代碼同樣。

所以,若是遇到 VM 或容器中的問題,咱們能夠更容易、更快速地銷燬和重建它們,而不是在當前環境嘗試調試和修復。

這也意味着對管道代碼的任何更改均可以觸發管道新一輪運行(經過 CI),就像對代碼的更改同樣。這是 DevOps 關於基礎架構的核心理念之一。

相關文章
相關標籤/搜索