CD:工具、方法、環境、基礎架構的全面指南

持續集成和持續交付(CI/CD)是DevOps背後的助推力之一。如果你的企業正在考慮使用DevOps,那麼CI/CD絕對是需要考慮的其中一部分。但是CI/CD到底意味著什麼?為什麼它如此重要呢?為了對你的DevOps工具包和IT部署進行戰略規劃,深入理解CI/CD至關重要。本文中,我們將探討CI/CD所需解決的難點、需要的工具以及預期的收益。


深入瞭解CI/CD:工具、方法、環境、基礎架構的全面指南


首先,我們從大局著手。DevOps旨在創建一個流暢的工作流程,並儘可能減少越區切換和建立快速反饋迴路。這意味著什麼呢?工作會從第一步開始一直向前推進,並且在理想狀態中,無需倒退再進行修復,因為它們應該能夠驗證和修復問題。為此,開發人員需要快速的反饋迴路。該反饋通過快速自動化測試提供,並且該測試將驗證代碼在進入下一階段之前能否按照預期工作。


為了減少越區切換,成員較少的小組將使用較小的功能並且掌控整個流程:創建請求、提交、QA以及部署。其重點是快速推出小段代碼,因為變更越小,診斷、修復和補救就越容易。


持續集成(CI)實現了從第一步到最後一步的快速流程,並通過持續交付(CD)將其擴展到實際生產部署。我們將其稱為CI/CD。現在,我們開始深入瞭解它們。


深入探索持續集成


首先,我們關注CI/CD的CI(持續集成)部分。實際上,大部分公司僅執行了CI。而完成整個CI/CD,需要該企業已經是一個成熟的DevOps企業。


說到集成,我們指的是程序員在其本地計算機上開發的代碼(包括更新或添加新特性)集成到代碼庫中。這一過程會面臨以下3個挑戰:


  1. 跟蹤所有變更,以便在發生錯誤時仍然可以恢復到之前的狀態,以最大程度地避免服務中斷。
  2. 當多個開發人員同時在同一個項目中工作時需要管理衝突
  3. 將新代碼添加到代碼庫之前需要捕捉到錯誤


接下來,我們將討論可以解決以上幾個痛點的3個工具。


1、 版本控制


隨著代碼從開發人員轉移到運維人員,它會根據測試結果不斷進行調整。所有的更改都會被版本控制系統捕捉。版本控制是一個軟件工具可以幫助開發者管理源代碼更改。在特殊類型的數據庫中它會一直跟蹤所有更改。


理想狀態下,軟件系統的所有部分都會被捕獲到,包括:


  • 源代碼
  • 資產
  • 環境
  • 軟件開發文檔
  • 對系統中存儲的文件的任何更改


2、master和開發分支


通常情況下,在同一個項目中會有多個開發人員一起工作,可能是幾個人也可能是上百個程序員,因此這可能會導致混亂。為了不讓穩定性遭受破壞或減輕在版本控制主分支中引入錯誤的風險,每個開發人員應該並行處理系統的不同部分。他們通過本地計算機上的“分支機構(branch)”執行這一操作。


但是在分支機構上工作本身並不是解決方案,每個開發人員正在處理的代碼必須集成到不斷擴充的代碼庫中。


開發人員在分支機構中工作而無需提交主分支的時間越長,與每個人在master中所做的更改進行集成和合並的難度就越大。所以,由於開發人員在不提交代碼的情況下處理代碼的時間越長,獲得代碼的難度就越大,因此從邏輯上來說就應該增加提交代碼的頻率。但是更好的方法是,使其持續集成。


下圖描繪瞭如何可視化不同分支。藍色是master分支,其他顏色都是在自己的分支上工作的單個開發人員,這些分支最終合併到master分支中。


深入瞭解CI/CD:工具、方法、環境、基礎架構的全面指南

不過,就算有分支機制也並非一帆風順。即使開發人員每天提交代碼,衝突仍然會發生。因為其他團隊成員會繼續做出更改,而沒有考慮各方的訴求。實際上,集成問題經常需要返工,包括手動合併衝突的更改。但是比起開發團隊整週或一個月都在埋頭工作而不處理衝突,找出並解決一天工作中的衝突要簡單很多。因此,儘管無法避免集成問題,但CI可以大大減少集成問題。


3、部署流水線和自動化測試


QA的部分工作是找出錯誤並確保代碼是可部署的。傳統流程中,在部署完成後會由一個單獨的團隊來負責QA。因為開發人員通常每年僅執行幾次測試,因此在引入更改幾個月後他們才瞭解到錯誤。到那時,因果之間的聯繫可能已經很難查證,導致診斷越來越困難。但是自動化測試解決了這個問題。


使用部署流水線之後,每次將代碼添加到版本控制中都會觸發一系列測試。流水線會自動構建和測試代碼以確保它可以按預期工作,並且一旦集成到代碼庫中就可以繼續工作。雖然在測試環境中代碼可以完美執行,但它仍有可能在生產環境中不幸失敗,因為生產中的環境和所有依賴項都會影響代碼性能。依賴項並不屬於app中的一部分,但仍需要運行它。例如數據庫、數據/對象存儲以及服務和應用程序可能需要調用的API。因此,開發和測試環境必須模仿生產環境。另外,必須對所有依賴項進行代碼測試。


深入瞭解CI/CD:工具、方法、環境、基礎架構的全面指南

簡而言之,部署代碼時有3個測試階段,每個階段都會額外增加複雜性:

(1)驗證代碼本身是否按照預期工作;

(2)在代碼庫中繼續進行驗證;

(3)驗證性能在具有所有依賴項的類生產環境中保持不變。


如果代碼每天都被提交到版本控制中,則可以對其進行自動化測試,並且在引入代碼之日會標記出任何構建、測試或集成錯誤,從而可以立即進行修復。這確保代碼總是處於可部署和可運送的狀態,稱為綠色構建。


自動測試允許開發人員提高測試和集成的頻率——從週期性執行到持續測試集成,並在約束最少的情況下發現問題。最糟糕的情況也不過是一天的工作都浪費了。


關於版本控制的爭議


關於是否改在版本控制中存儲敏感信息(如 access token、密鑰和密碼)進行了一些討論。一方面,有人認為應該將一切(包括secret)都存儲在這裡,從而將這一方法推向極限。但是有人認為這是不良做法,並認為敏感信息應該單獨存儲。


版本控制允許開發人員比較、合併和還原以前的修訂。通過允許他們在出現問題時將生產中的系統快速還原到以前的版本,從而將風險降到最低。為此,無論版本多小,所有更新和更改都必須在版本控制中進行跟蹤。如果不是這樣,生產中的代碼將開發和測試環境中的代碼不匹配,從而導致不一致。


簡而言之,版本控制是事實的單一來源,包含了系統的預期狀態以及所有以前的狀態。通過將所有生產環境中的組件放置到版本控制中,開發人員可以重複可靠地重現工作軟件系統中的所有組件。這是啟用所謂的不可變基礎架構的關鍵,我們將在稍後討論。

持續交付:擴展CI以實現流暢的代碼部署


即使使用了持續集成,將代碼部署到生產中的過程依舊是手動、乏味且容易出錯的。如果真是這樣,那麼顯然不會頻繁地將代碼部署到生產中。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方法的企業,壓力會越來越大。


附錄:部署流水線測試套件


  • 集成測試檢查應用程序如何與其他應用程序和服務交互,以確保代碼與這些依賴項正確交互。遠程服務的虛擬或模擬版本可用於準確地重新創建生產環境。
  • 驗收測試會驗證是否滿足業務需求,以確保功能或應用程序為最終用戶提供所需的價值。
  • 性能測試可驗證該應用程序在類似生產的負載下如何在整個堆棧(代碼、數據庫、存儲、網絡、虛擬化)中工作。由架構決策或網絡、數據庫、存儲或其他系統的意外限制引起的問題應在此處解決。
  • 非功能測試包括可用性、可伸縮性、性能、容量、安全性等。這些要求取決於環境的正確配置。測試將驗證環境是否已正確構建和配置。
  • 冒煙測試驗證該應用程序可以連接到所有支持系統,例如數據庫、服務或信息傳遞系統;冒煙測試通常是手動的。


也有自動安全性測試以及探索性和其他手動或資源密集型測試。我們的目標是儘早捕獲更多錯誤,並使用這些更耗時的測試來驗證高層次的需求,並將產品完全集成到儘可能接近生產的環境中。


分享到:


相關文章: