本文來自Rancher Labs程序員
持續集成和持續交付(CI/CD)是DevOps背後的助推力之一。若是你的企業正在考慮使用DevOps,那麼CI/CD絕對是須要考慮的其中一部分。可是CI/CD到底意味着什麼?爲何它如此重要呢?爲了對你的DevOps工具包和IT部署進行戰略規劃,深刻理解CI/CD相當重要。本文中,咱們將探討CI/CD所需解決的難點、須要的工具以及預期的收益。數據庫
首先,咱們從大局着手。DevOps旨在建立一個流暢的工做流程,並儘量減小越區切換和創建快速反饋迴路。這意味着什麼呢?工做會從第一步開始一直向前推動,而且在理想狀態中,無需倒退再進行修復,由於它們應該可以驗證和修復問題。爲此,開發人員須要快速的反饋迴路。該反饋經過快速自動化測試提供,而且該測試將驗證代碼在進入下一階段以前可否按照預期工做。安全
爲了減小越區切換,成員較少的小組將使用較小的功能而且掌控整個流程:建立請求、提交、QA以及部署。其重點是快速推出小段代碼,由於變動越小,診斷、修復和補救就越容易。網絡
持續集成(CI)實現了從第一步到最後一步的快速流程,並經過持續交付(CD)將其擴展到實際生產部署。咱們將其稱爲CI/CD。如今,咱們開始深刻了解它們。架構
首先,咱們關注CI/CD的CI(持續集成)部分。實際上,大部分公司僅執行了CI。而完成整個CI/CD,須要該企業已是一個成熟的DevOps企業。app
說到集成,咱們指的是程序員在其本地計算機上開發的代碼(包括更新或添加新特性)集成到代碼庫中。這一過程會面臨如下3個挑戰:運維
接下來,咱們將討論能夠解決以上幾個痛點的3個工具。工具
隨着代碼從開發人員轉移到運維人員,它會根據測試結果不斷進行調整。全部的更改都會被版本控制系統捕捉。版本控制是一個軟件工具能夠幫助開發者管理源代碼更改。在特殊類型的數據庫中它會一直跟蹤全部更改。性能
理想狀態下,軟件系統的全部部分都會被捕獲到,包括:測試
一般狀況下,在同一個項目中會有多個開發人員一塊兒工做,多是幾我的也多是上百個程序員,所以這可能會致使混亂。爲了避免讓穩定性遭受破壞或減輕在版本控制主分支中引入錯誤的風險,每一個開發人員應該並行處理系統的不一樣部分。他們經過本地計算機上的「分支機構(branch)」執行這一操做。
可是在分支機構上工做自己並非解決方案,每一個開發人員正在處理的代碼必須集成到不斷擴充的代碼庫中。
開發人員在分支機構中工做而無需提交主分支的時間越長,與每一個人在master中所作的更改進行集成和合並的難度就越大。因此,因爲開發人員在不提交代碼的狀況下處理代碼的時間越長,得到代碼的難度就越大,所以從邏輯上來講就應該增長提交代碼的頻率。可是更好的方法是,使其持續集成。
下圖描繪瞭如何可視化不一樣分支。藍色是master分支,其餘顏色都是在本身的分支上工做的單個開發人員,這些分支最終合併到master分支中。
不過,就算有分支機制也並不是一路順風。即便開發人員天天提交代碼,衝突仍然會發生。由於其餘團隊成員會繼續作出更改,而沒有考慮各方的訴求。實際上,集成問題常常須要返工,包括手動合併衝突的更改。可是比起開發團隊整週或一個月都在埋頭工做而不處理衝突,找出並解決一天工做中的衝突要簡單不少。所以,儘管沒法避免集成問題,但CI能夠大大減小集成問題。
QA的部分工做是找出錯誤並確保代碼是可部署的。傳統流程中,在部署完成後會由一個單獨的團隊來負責QA。由於開發人員一般每一年僅執行幾回測試,所以在引入更改幾個月後他們才瞭解到錯誤。到那時,因果之間的聯繫可能已經很難查證,致使診斷愈來愈困難。可是自動化測試解決了這個問題。
使用部署流水線以後,每次將代碼添加到版本控制中都會觸發一系列測試。流水線會自動構建和測試代碼以確保它能夠按預期工做,而且一旦集成到代碼庫中就能夠繼續工做。雖然在測試環境中代碼能夠完美執行,但它仍有可能在生產環境中不幸失敗,由於生產中的環境和全部依賴項都會影響代碼性能。依賴項並不屬於app中的一部分,但仍須要運行它。例如數據庫、數據/對象存儲以及服務和應用程序可能須要調用的API。所以,開發和測試環境必須模仿生產環境。另外,必須對全部依賴項進行代碼測試。
簡而言之,部署代碼時有3個測試階段,每一個階段都會額外增長複雜性:
(1)驗證代碼自己是否按照預期工做;
(2)在代碼庫中繼續進行驗證;
(3)驗證性能在具備全部依賴項的類生產環境中保持不變。
若是代碼天天都被提交到版本控制中,則能夠對其進行自動化測試,而且在引入代碼之日會標記出任何構建、測試或集成錯誤,從而能夠當即進行修復。這確保代碼老是處於可部署和可運送的狀態,稱爲綠色構建。
自動測試容許開發人員提升測試和集成的頻率——從週期性執行到持續測試集成,並在約束最少的狀況下發現問題。最糟糕的狀況也不過是一天的工做都浪費了。
關因而否改在版本控制中存儲敏感信息(如 access token、密鑰和密碼)進行了一些討論。一方面,有人認爲應該將一切(包括secret)都存儲在這裏,從而將這一方法推向極限。可是有人認爲這是不良作法,並認爲敏感信息應該單獨存儲。
版本控制容許開發人員比較、合併和還原之前的修訂。經過容許他們在出現問題時將生產中的系統快速還原到之前的版本,從而將風險降到最低。爲此,不管版本多小,全部更新和更改都必須在版本控制中進行跟蹤。若是不是這樣,生產中的代碼將開發和測試環境中的代碼不匹配,從而致使不一致。
簡而言之,版本控制是事實的單一來源,包含了系統的預期狀態以及全部之前的狀態。經過將全部生產環境中的組件放置到版本控制中,開發人員能夠重複可靠地重現工做軟件系統中的全部組件。這是啓用所謂的不可變基礎架構的關鍵,咱們將在稍後討論。
即便使用了持續集成,將代碼部署到生產中的過程依舊是手動、乏味且容易出錯的。若是真是這樣,那麼顯然不會頻繁地將代碼部署到生產中。IT部門會盡量避免執行艱鉅而危險的任務,這會致使要部署的代碼與生產中運行的代碼之間差別愈來愈大,進一步加具危險,而後造成一種惡性循環。那麼解決這一惡性循環的答案是啓用CI/CD中的CD部分。
CD擴展了CI,確保在將代碼推廣到整個用戶羣以前讓代碼在生產環境中可以平滑運行。最多見的CD方法是金絲雀和藍綠部署。
進行藍綠部署期間,IT會與當前版本一塊兒部署一個新的組件或應用程序版本。新版本(綠)被部署到生產中並對其進行測試,與此同時當前版本(藍)依舊可使用。若是新版本的代碼運行良好,那麼全部用戶將會切換到新版本中。
金絲雀部署也有兩個版本:當前版本和更新版本。IT開始將一小部分用戶請求路由到新版本。代碼和用戶的行爲會被持續監控。若是錯誤率或用戶投訴並無增長,則路由到新版本的請求份額將逐漸增長(例如,1%、10%、50%最後到100%)。一旦全部請求都發送到新版本中,那麼舊版本就會自動退休或刪除。
如今,咱們已經研究了CI、CD及其各自的工具和方法,下面咱們來討論環境和基礎架構。CI / CD須要一種創新的方法。
如咱們所見,自動化測試使開發人員能夠本身執行QA。爲了確保一切都能在生產中正常運行,他們必須在整個開發和測試過程當中使用相似於生產的環境。
傳統上,開發人員必須向Ops團隊請求(手動)設置的測試環境。此過程可能須要數週,有時甚至數月。此外,手動部署的測試環境一般會出現配置錯誤,或者與生產環境有很大差別,所以即便代碼經過了全部預部署測試,仍然會致使生產問題。
CI / CD的關鍵部分是爲開發人員提供按需相似於生產的環境,使其能夠在本身的工做站上運行。爲何這很重要?開發人員只有在相同的條件下進行部署和測試時,才能知道代碼在生產中的行爲。若是他們在不一樣的環境中測試代碼,則當最終將代碼部署到生產環境中時,他們可能會發現代碼不兼容,那麼此時對客戶形成了重大影響,再解決問題已經爲時已晚。
在討論版本控制系統時,咱們談到了將環境與全部其餘應用程序組件進行編碼的需求,接下來讓咱們進一步討論這些環境。
若是在版本控制中定義了環境規範並進行了編碼,那麼在容量增長(水平擴展)時複製環境就像按一個按鈕同樣簡單(儘管以後它頗有可能經過Kubernetes自動化了)。
擴展意味着在高峯時段增長計算能力。例如,Netflix的使用率在每一個星期五晚上達到峯值,而後在午夜以後的某個時間再次恢復正常。爲了確保享受無緩衝的視頻,Netflix複製了其流控制組件(已在版本控制中進行了編碼),以知足需求。而後,流量恢復後全部所謂的副本都被破壞,使流容量恢復正常。
爲了實現這一點,相當重要的是,每當實施基礎架構或應用程序更新時,這些基礎架構或應用程序都會自動複製到其餘地方並置於版本控制中。這將確保不管什麼時候建立新環境,它都將與整個流水線(從dev到QA到生產)的環境匹配。例如,若是Netflix要更新其流服務而忘了捕獲版本控制的更改,它將在高峯時段複製有故障或過期的組件,從而致使問題甚至服務中斷。
因爲掌握了版本控制中的環境編碼,所以手動更改環境不是最佳實踐,由於任何手動操做都容易出錯。而應該將更改放入版本控制中,並從頭開始從新建立環境(和代碼)。這稱爲不可變基礎架構。這些與CI / CD部分中討論的應用於基礎架構的原則相同。
你也許聽過牛與寵物的比喻。這個比喻放在這裏十分合適。之前,基礎設施被視爲寵物。若是有問題,你會盡力解決它,以便它能夠生存。今天,基礎設施被視爲牛。若是它沒法正常工做或須要更新,請殺死它並啓動新環境。這很是強大,而且大大下降了問題潛入系統的風險。
傳統上,軟件發佈是由市場啓動日期驅動的。所以,要發佈的新功能會在宣佈日期的前一天部署到生產中。可是,咱們知道將特性或更新發布到生產中老是有風險的,尤爲是若是你一次發佈整個特性時。所以,將部署與發佈捆綁在一塊兒將使IT部門老是須要爲失敗膽戰心驚。試想一下,若是在普遍推廣的前一天發生了重大問題,IT團隊就會感到恐慌,而且會在客戶和媒體中引發巨大不良反響。
更好的方法是使部署與發佈解耦。儘管這兩個詞常常互換使用,但它們是兩個獨立的過程。部署意味着將軟件版本安裝到任何環境(包括生產環境)中。它不必定必須與發佈相關聯。另外一方面,發佈意味着向客戶羣提供新功能。在整個功能開發過程當中頻繁進行生產部署的目的是下降服務中斷的風險,該風險由IT部門承擔。另外一方面,什麼時候向客戶展現新功能應該是業務決策,而不是技術決策。
部署週期長會決定新功能發佈的頻率。若是IT能夠按需部署,那麼公開新功能的速度應該成爲業務和市場營銷的決定。
總而言之,CI要求將代碼連續集成到代碼庫中,以在發生錯誤時捕獲錯誤,從而最大程度地減小返工。要實現這種方法,須要三個工具:版本控制,以跟蹤全部更改並使整個團隊均可以使用最新的源代碼版本;master,負責本身分支的開發人員天天合併更新;部署流水線將觸發一系列測試,基本上是自動進行QA。
CD擴展了CI,以驗證代碼是否處於可部署狀態,並自動將其釋放到生產環境中。爲此,須要一個成熟的DevOps組織,該組織必須先掌握CI,而後才能嘗試使用CD。
若是實施得當,CI(/ CD)將大大提升你的IT團隊的生產力。你的系統或應用程序在不斷改進,同時將部署風險降至最低,從而加強了生產力和員工滿意度的積極循環。此外,快速推出新功能和更新可推進創新,進而更快,更頻繁地爲用戶帶來價值。顯然,隨着愈來愈多的組織採用這些DevOps方法,因爲傳統方法沒法與CI / CD競爭,所以對那些沒有采用DevOps方法的企業,壓力會愈來愈大。
也有自動安全性測試以及探索性和其餘手動或資源密集型測試。咱們的目標是儘早捕獲更多錯誤,並使用這些更耗時的測試來驗證高層次的需求,並將產品徹底集成到儘量接近生產的環境中。