可替代 Jenkins:Drone 進一步簡化 CI-CD

創建一家成功的軟件公司需要什麼?交付有價值的軟件並快速交付的能力。我們如何保證這種高速服務?持續交付 (CD) 流程,由完善的持續集成 (CI) 機制支持,以提供完美交付,尤其是當平臺組件的數量和依賴性增加時。

這張圖片完美地總結了良性 CI/CD 循環,任何 DevOps 都應該將其貼在辦公桌上:

在本文中,我們將關注循環的左側,即產品從代碼到測試的過程。

使用源代碼時,git 是唯一的選擇。事實上,在 BOOM,我們使用來管理代碼生命週期(但 git 選項還包括 Gitea 或 Bitbucket)。每個項目都有自己的存儲庫,可以由具有不同角色的各種團隊成員訪問。我們使用 “開發” 分支構建臨時版本,使用主分支構建生產版本。

到目前爲止,一切都很好。但是應該如何管理對 git 存儲庫執行的操作(例如拉取請求和合並)?如何在各種環境中以受控的方式部署代碼呢?

答案是 CI/CD 工具

在 BOOM,一開始,我們將 Github Actions 用於 CI,將 Ansible/AWX 用於 CD。當涉及的軟件組件很少時,此解決方案有效,但一旦您的路線圖在數量和依賴性方面指向分佈式軟件模型,它就會變得有限。但隨着時間的推移,編寫庫(例如日誌庫)或包(例如反應組件庫)具有多個軟件組件的需求變得更加緊迫,需要對整個生態系統進行維護和更有效的管理。

在我過去的生活中,我對 Jenkins 有過很深的體驗,無論它的優點還是缺點。但在 BOOM,我們充滿好奇,渴望嘗試新技術,看看它們是否符合我們的需求。因此,我們決定與工程團隊一起評估和嘗試各種解決方案,包括一些 SaaS,其中考慮了以下方面:

在我們測試了許多工具(CircleCI、TravisCI、TeamCity、Bamboo)的評估期之後,我們決定將 Drone CI (https://www.drone.io) 作爲我們 CI/CD 的核心部分。

Drones 爲我們提供了我們所需要的一切,特別是:

Drones 基本概念與其他 CI 工具非常相似。在 git 存儲庫上執行的任何操作都會通過 webhook Drone 觸發。如果爲特定存儲庫定義了管道(例如存儲庫根目錄中存在 .drone.yml 文件),Drone 將對其進行分析並執行請求的操作。該決定是通過以下觸發器定義做出的:

在這個特定場景中,當且僅當目標分支是 “develop” 或“master”,並且事件是 “pull_request” 或“push”時,管道纔會運行。

每個管道都是使用一系列步驟構建的,每個步驟都用語法描述,例如:

這很容易閱讀。使用鏡像 maven:3.6.3-jdk-11 我們執行 mvn clean 和 mvn install。以下無需解釋:

但是這些動作是在哪裏執行的呢?源代碼在哪裏?

正如我們在開始時所說,在 git 存儲庫上執行的定義明確的操作會通過 webhook 觸發 Drone。Drone 負責克隆 git 存儲庫內容,與所有容器共享它,爲每個容器安裝一個特定路徑(/drone/src),並在那裏設置一個主容器。因此,在這個文件夾中添加文件可以在一個階段完成,稍後在另一個階段找到相同的文件,例如前面的 mvn 命令的構建結果可以用於執行單元測試:

也許另一個可用於執行集成測試:

如上例所示,我們使用簡單的 docker 容器來執行各種步驟,其中大部分是標準容器。也可以通過添加新步驟來構建複雜的管道,直到達到預期的結果。

Drone 的強大功能之一是服務的概念。有時,執行特定任務(例如:集成測試)需要支持服務,例如 redis 實例或 postgres 實例。任何使用 SaaS 服務的人都需要使用 docker-in-docker (dind) 功能。使用 Drone,您只需定義一個服務:

Drone 將負責啓動所需的 postgres 實例,然後在管道結束後將其殺死。接下來需要做什麼?只需指示測試步驟使用這個 postgres 實例。

如果沒有可用的插件滿足您的需求,您可以編寫自己的插件。但是什麼是 Drones 插件?很簡單:它是一個容器運行代碼!儘管 Go 是編寫插件的首選語言,但也可以使用另一種語言。

我們來看看這一步:

並假設您將標籤爲 1.1.0 的容器 my-plugin 推送到首選鏡像存儲庫中。

執行此步驟時,Drone 將下載您的插件並運行在定義的 Dockerfile 中找到的內容:

但是在步驟中定義的值上設置了兩個環境變量,稱爲 DRONE_FOO 和 DRONE_BAR。當然,這對於簡單的插件來說效果很好,但是當它們更復雜時,最好使用 drone-plugin-starter[1] 並用 Go 編寫它。

讓我們回到管道中的測試階段。如前所述,可以爲單元和集成測試添加測試步驟。但是同樣的策略也可以應用於添加執行其他類型測試的步驟,例如 cypress 測試、postman 測試等。爲這些場景編寫步驟是再次啓動一個合適的容器並在其中 “運行” 命令。但是測試報告呢?與 Jenkins 不同,後者使用一個合適的插件將測試結果附加到運行的管道並通過 Jenkins UI 訪問它,Drone 只是一個管道執行器。它提供了一個不錯的 UI,但它提供了與構建嚴格相關的信息,僅此而已。那麼如何收集測試結果並將其提供給工程團隊呢?

我們找到的解決方案是一個名爲** Allure Docker Service[2] **的開源項目,它提供了一種基於項目存儲和組織測試結果的方法。它由 API 層(負責管理內容攝取和管理)和允許輕鬆直觀地瀏覽報告的 UI 組成。它可以接受各種格式的報告(junit、testng、allure 等),並提供每個項目的趨勢視圖和每個運行和測試用例的詳細視圖。執行以下任務很有用:

換一種說法,

例如,在 cypress 測試的具體情況下,這是我們在管道中使用的代碼片段:

第一步運行 cypress 測試並將結果以 allure 原生格式存儲在 /drone/src/cypress-results/allure 下,而第二步將結果發送到我們系統上的 allure-service。

這似乎是一種解決方法,可以彌補 Drone 只是一個管道執行器這一事實,但根據我的經驗,最好的操作方式是讓每個平臺組件負責一項任務。大型應用程序(例如 Jenkins)在實施更改時可能會出現所有問題都崩潰的問題。同時,鬆散耦合的組件使得改變一個元素而不改變其他一切成爲可能。

CI 管道的最終結果應該是可以在任何環境(暫存、預生產、生產等)中使用的工件。目前,我們的平臺 [3] 有三種神器:

Docker 鏡像存儲在 ECR 上,而我們使用 Nexus 存儲庫管理器 OSS 來存儲 npm 包和 java 庫。Drone 可以很容易地創建這些工件並將它們推送到適當的位置。例如,在處理 docker 鏡像時,使用以下步驟就綽綽有餘了:

因此,將使用 pom.xml 中的版本將新版本的鏡像推送到您的 ECR 上。

在本文中,我們描述了爲什麼選擇 Drone 作爲我們的 CD,以及我們如何將它與其他工具一起使用,爲我們的工程團隊提供一流的體驗。過程非常有趣,並不總是那麼容易,但我們能夠克服各種問題並利用我們建立的生態系統。

GoCN 最具規模和生命力的 Go 開發者社區

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/IxzkZefFowLDiK6-9kX1HQ