1. 程式人生 > >基於 KubeSphere CI/CD 將 Spring Boot 專案釋出至 Kubernetes

基於 KubeSphere CI/CD 將 Spring Boot 專案釋出至 Kubernetes

本示例基於開源的 KubeSphere 容器平臺 演示如何通過 GitHub 倉庫中的 Jenkinsfile 來建立流水線,流水線共包括 8 個階段,最終將一個 Hello World 頁面部署到 Kubernetes 叢集中的不同 namespace。

流水線概覽

下面的流程圖簡單說明了流水線完整的工作過程:

流程說明:

  • 階段一. Checkout SCM: 拉取 GitHub 倉庫程式碼
  • 階段二. Unit test: 單元測試,如果測試通過了才繼續下面的任務
  • 階段三. sonarQube analysis:sonarQube 程式碼質量檢測
  • 階段四. Build & push snapshot image: 根據行為策略中所選擇分支來構建映象,並將 tag 為 SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER
    推送至 Harbor (其中 $BUILD_NUMBER 為 pipeline 活動列表的執行序號)。
  • 階段五. Push latest image: 將 master 分支打上 tag 為 latest,並推送至 DockerHub。
  • 階段六. Deploy to dev: 將 master 分支部署到 Dev 環境,此階段需要稽核。
  • 階段七. Push with tag: 生成 tag 並 release 到 GitHub,並推送到 DockerHub。
  • 階段八. Deploy to production: 將釋出的 tag 部署到 Production 環境。

建立憑證

使用 project-regular 登入 KubeSphere,進入已建立的 devops-demo 工程,開始建立憑證。

1、本示例程式碼倉庫中的 Jenkinsfile 需要用到 DockerHub、GitHub 和 kubeconfig (kubeconfig 用於訪問接入正在執行的 Kubernetes 叢集) 等一共 3 個憑證 (credentials) 。
2、然後建立一個 Java 的 Token 並複製。

3、最後在 KubeSphere 中進入 devops-demo 的 DevOps 工程中,與上面步驟類似,在 憑證 下點選 建立,建立一個型別為 祕密文字 的憑證,憑證 ID 命名為 sonar-token,金鑰為上一步複製的 token 資訊,完成後點選 確定。

至此,4 個憑證已經建立完成,下一步需要在示例倉庫中的 jenkinsfile 修改對應的四個憑證 ID 為使用者自己建立的憑證 ID。

修改 Jenkinsfile

第一步:Fork專案

登入 GitHub,將本示例用到的 GitHub 倉庫 devops-java-sample Fork 至您個人的 GitHub。

第二步:修改 Jenkinsfile

1、Fork 至您個人的 GitHub 後,在 根目錄 進入 Jenkinsfile-online。

2、在 GitHub UI 點選編輯圖示,需要修改如下環境變數 (environment) 的值。

修改項 含義
DOCKER_CREDENTIAL_ID dockerhub-id 填寫建立憑證步驟中的 DockerHub 憑證 ID,用於登入您的 DockerHub
GITHUB_CREDENTIAL_ID github-id 填寫建立憑證步驟中的 GitHub 憑證 ID,用於推送 tag 到 GitHub 倉庫
KUBECONFIG_CREDENTIAL_ID demo-kubeconfig kubeconfig 憑證 ID,用於訪問接入正在執行的 Kubernetes 叢集
REGISTRY docker.io 預設為 docker.io 域名,用於映象的推送
DOCKERHUB_NAMESPACE your-dockerhub-account 替換為您的 DockerHub 賬號名
(它也可以是賬戶下的 Organization 名稱)
GITHUB_ACCOUNT your-github-account 替換為您的 GitHub 賬號名,例如 https://github.com/kubesphere/ 則填寫 kubesphere (它也可以是賬戶下的 Organization 名稱)
APP_NAME devops-java-sample 應用名稱
SONAR_CREDENTIAL_ID sonar-token 填寫建立憑證步驟中的 SonarQube token憑證 ID,用於程式碼質量檢測

注: Jenkinsfile 中 mvn 命令的引數 -o,表示開啟離線模式。本示例為適應某些環境下網路的干擾,以及避免在下載依賴時耗時太長,已事先完成相關依賴的下載,預設開啟離線模式。

3、修改以上的環境變數後,點選 Commit changes,將更新提交到當前的 master 分支。

建立專案

CI/CD 流水線會根據示例專案的 yaml 模板檔案,最終將示例分別部署到 Dev 和 Production 這兩個專案 (Namespace) 環境中,即 kubesphere-sample-devkubesphere-sample-prod,這兩個專案需要預先在控制檯依次建立,參考如下步驟建立該專案。

第一步:建立第一個專案

1、使用專案管理員 project-admin 賬號登入 KubeSphere,在之前建立的企業空間 (demo-workspace) 下,點選 專案 → 建立,建立一個 資源型專案,作為本示例的開發環境,填寫該專案的基本資訊,完成後點選 下一步。

  • 名稱:固定為 kubesphere-sample-dev,若需要修改專案名稱則需在 yaml 模板檔案 中修改 namespace
  • 別名:可自定義,比如 開發環境
  • 描述資訊:可簡單介紹該專案,方便使用者進一步瞭解

2、本示例暫無資源請求和限制,因此高階設定中無需修改預設值,點選 建立,專案可建立成功。

第二步:邀請成員

第一個專案建立完後,還需要專案管理員 project-admin 邀請當前的專案普通使用者 project-regular 進入 kubesphere-sample-dev 專案,進入「專案設定」→「專案成員」,點選「邀請成員」選擇邀請 project-regular 並授予 operator 角色。

第三步:建立第二個專案

同上,參考以上兩步建立一個名稱為 kubesphere-sample-prod 的專案作為生產環境,並邀請普通使用者 project-regular 進入 kubesphere-sample-prod 專案並授予 operator 角色。

說明:當 CI/CD 流水線後續執行成功後,在 kubesphere-sample-devkubesphere-sample-prod 專案中將看到流水線建立的部署 (Deployment) 和服務 (Service)。

建立流水線

第一步:填寫基本資訊

1、進入已建立的 DevOps 工程,選擇左側選單欄的 流水線,然後點選 建立。

2、在彈出的視窗中,輸入流水線的基本資訊。

  • 名稱:為建立的流水線起一個簡潔明瞭的名稱,便於理解和搜尋
  • 描述資訊:簡單介紹流水線的主要特性,幫助進一步瞭解流水線的作用
  • 程式碼倉庫:點選選擇程式碼倉庫,程式碼倉庫需已存在 Jenkinsfile

第二步:新增倉庫

1、點選程式碼倉庫,以新增 Github 倉庫為例。

2、點選彈窗中的 獲取 Token。

3、在 GitHub 的 access token 頁面填寫 Token description,簡單描述該 token,如 DevOps demo,在 Select scopes 中無需任何修改,點選 Generate token,GitHub 將生成一串字母和數字組成的 token 用於訪問當前賬戶下的 GitHub repo。

4、複製生成的 token,在 KubeSphere Token 框中輸入該 token 然後點選儲存。

5、驗證通過後,右側會列出此 Token 關聯使用者的所有程式碼庫,選擇其中一個帶有 Jenkinsfile 的倉庫。比如此處選擇準備好的示例倉庫 devops-java-sample,點選 選擇此倉庫,完成後點選 下一步。

第三步:高階設定

完成程式碼倉庫相關設定後,進入高階設定頁面,高階設定支援對流水線的構建記錄、行為策略、定期掃描等設定的定製化,以下對用到的相關配置作簡單釋義。

1、構建設定中,勾選 丟棄舊的構建,此處的 保留分支的天數 和 保留分支的最大個數 預設為 -1。

說明:

分支設定的保留分支的天數和保持分支的最大個數兩個選項可以同時對分支進行作用,只要某個分支的保留天數和個數不滿足任何一個設定的條件,則將丟棄該分支。假設設定的保留天數和個數為 2 和 3,則分支的保留天數一旦超過 2 或者保留個數超過 3,則將丟棄該分支。預設兩個值為 -1,表示不自動刪除分支。

丟棄舊的分支將確定何時應丟棄專案的分支記錄。分支記錄包括控制檯輸出,存檔工件以及與特定分支相關的其他元資料。保持較少的分支可以節省 Jenkins 所使用的磁碟空間,我們提供了兩個選項來確定應何時丟棄舊的分支:

  • 保留分支的天數:如果分支達到一定的天數,則丟棄分支。
  • 保留分支的個數:如果已經存在一定數量的分支,則丟棄最舊的分支。

2、行為策略中,KubeSphere 預設添加了三種策略。由於本示例還未用到 從 Fork 倉庫中發現 PR 這條策略,此處可以刪除該策略,點選右側刪除按鈕。

說明:

支援新增三種類型的發現策略。需要說明的是,在 Jenkins 流水線被觸發時,開發者提交的 PR (Pull Request) 也被視為一個單獨的分支。

發現分支:

  • 排除也作為 PR 提交的分支:選擇此項表示 CI 將不會掃描源分支 (比如 Origin 的 master branch),也就是需要被 merge 的分支
  • 只有被提交為 PR 的分支:僅掃描 PR 分支
  • 所有分支:拉取的倉庫 (origin) 中所有的分支

從原倉庫中發現 PR:

  • PR 與目標分支合併後的原始碼版本:一次發現操作,基於 PR 與目標分支合併後的原始碼版本建立並執行流水線
  • PR 本身的原始碼版本:一次發現操作,基於 PR 本身的原始碼版本建立並執行流水線
  • 當 PR 被發現時會建立兩個流水線,一個流水線使用 PR 本身的原始碼版本,一個流水線使用 PR 與目標分支合併後的原始碼版本:兩次發現操作,將分別建立兩條流水線,第一條流水線使用 PR 本身的原始碼版本,第二條流水線使用 PR 與目標分支合併後的原始碼版本

3、預設的 指令碼路徑 為 Jenkinsfile,請將其修改為 Jenkinsfile-online。

注:路徑是 Jenkinsfile 在程式碼倉庫的路徑,表示它在示例倉庫的根目錄,若檔案位置變動則需修改其指令碼路徑。

4、在 掃描 Repo Trigger 勾選 如果沒有掃描觸發,則定期掃描,掃描時間間隔可根據團隊習慣設定,本示例設定為 5 minutes

說明:定期掃描是設定一個週期讓流水線週期性地掃描遠端倉庫,根據 行為策略 檢視倉庫有沒有程式碼更新或新的 PR。

Webhook 推送:

Webhook 是一種高效的方式可以讓流水線發現遠端倉庫的變化並自動觸發新的執行,GitHub 和 Git (如 Gitlab) 觸發 Jenkins 自動掃描應該以 Webhook 為主,以上一步在 KubeSphere 設定定期掃描為輔。在本示例中,可以通過手動執行流水線,如需設定自動掃描遠端分支並觸發執行,詳見 設定自動觸發掃描 - GitHub SCM。

完成高階設定後點擊 建立。

第四步:執行流水線

流水線建立後,點選瀏覽器的 重新整理 按鈕,可見一條自動觸發遠端分支後的執行記錄。

1、點選右側 執行,將根據上一步的 行為策略 自動掃描程式碼倉庫中的分支,在彈窗選擇需要構建流水線的 master分支,系統將根據輸入的分支載入 Jenkinsfile-online (預設是根目錄下的 Jenkinsfile)。

2、由於倉庫的 Jenkinsfile-online 中 TAG_NAME: defaultValue 沒有設定預設值,因此在這裡的 TAG_NAME 可以輸入一個 tag 編號,比如輸入 v0.0.1。

3、點選 確定,將新生成一條流水線活動開始執行。

說明: tag 用於在 Github 和DockerHub 中分別生成帶有 tag 的 release 和映象。 注意: 在主動執行流水線以釋出 release 時,TAG_NAME 不應與之前程式碼倉庫中所存在的 tag 名稱重複,如果重複會導致流水線的執行失敗。

至此,流水線 已完成建立並開始執行。

注:點選 分支 切換到分支列表,檢視流水線具體是基於哪些分支執行,這裡的分支則取決於上一步 行為策略 的發現分支策略。

第五步:稽核流水線

為方便演示,此處預設用當前賬戶來稽核,當流水線執行至 input 步驟時狀態將暫停,需要手動點選 繼續,流水線才能繼續執行。注意,在 Jenkinsfile-online 中分別定義了三個階段 (stage) 用來部署至 Dev 環境和 Production 環境以及推送 tag,因此在流水線中依次需要對 deploy to dev, push with tag, deploy to production 這三個階段稽核 3 次,若不稽核或點選 終止 則流水線將不會繼續執行。

說明:在實際的開發生產場景下,可能需要更高許可權的管理員或運維人員來稽核流水線和映象,並決定是否允許將其推送至程式碼或映象倉庫,以及部署至開發或生產環境。Jenkinsfile 中的 input步驟支援指定使用者稽核流水線,比如要指定使用者名稱為 project-admin 的使用者來稽核,可以在 Jenkinsfile 的 input 函式中追加一個欄位,如果是多個使用者則通過逗號分隔,如下所示:

···
input(id: 'release-image-with-tag', message: 'release image with tag?', submitter: 'project-admin,project-admin1')
···

檢視流水線

1、點選流水線中 活動 列表下當前正在執行的流水線序列號,頁面展現了流水線中每一步驟的執行狀態,注意,流水線剛建立時處於初始化階段,可能僅顯示日誌視窗,待初始化 (約一分鐘) 完成後即可看到流水線。黑色框標註了流水線的步驟名稱,示例中流水線共 8 個 stage,分別在 Jenkinsfile-online 中被定義。

2、當前頁面中點選右上方的 檢視日誌,檢視流水線執行日誌。頁面展示了每一步的具體日誌、執行狀態及時間等資訊,點選左側某個具體的階段可展開檢視其具體的日誌。日誌可下載至本地,如出現錯誤,下載至本地更便於分析定位問題。

驗證執行結果

1、若流水線執行成功,點選該流水線下的 程式碼質量,即可看到通過 SonarQube 的程式碼質量檢測結果,如下圖(僅供參考)。

2、流水線最終 build 的 Docker 映象也將被成功地 push 到 DockerHub 中,我們在 Jenkinsfile-online 中已經配置過 DockerHub,登入 DockerHub 檢視映象的 push 結果,可以看到 tag 為 snapshot、TAG_NAME(master-1)、latest 的映象已經被 push 到 DockerHub,並且在 GitHub 中也生成了一個新的 tag 和 release。Hello World 示例頁面最終將以 deployment 和 service 分別部署到 KubeSphere 的 kubesphere-sample-devkubesphere-sample-prod 專案環境中。

環境 訪問地址 所在專案 (Namespace) 部署 (Deployment) 服務 (Service)
Dev http://{$Virtual IP}:{$8080}
或者 http://{$內網/公網 IP}:{$30861}
kubesphere-sample-dev ks-sample-dev ks-sample-dev
Production http://{$Virtual IP}:{$8080}
或者 http://{$內網/公網 IP}:{$30961}
kubesphere-sample-prod ks-sample ks-sample

3、可通過 KubeSphere 回到專案列表,依次檢視之前建立的兩個專案中的部署和服務的狀態。例如,以下檢視 kubesphere-sample-prod專案下的部署。

進入該專案,在左側的選單欄點選 工作負載 → 部署,可以看到 ks-sample 已建立成功。正常情況下,部署的狀態應該顯示 執行中。

4、在選單欄中選擇 網路與服務 → 服務 也可以檢視對應建立的服務,可以看到該服務的 Virtual IP 為 10.233.42.3,對外暴露的節點埠 (NodePort) 是 30961

檢視服務

5、檢視推送到您個人的 DockerHub 中的映象,可以看到 devops-java-sample就是 APP_NAME 的值,而 tag 也是在 jenkinsfile-online 中定義的 tag。

6、點選 release,檢視 Fork 到您個人 GitHub repo 中的 v0.0.1 tag 和 release,它是由 jenkinsfile 中的 push with tag 生成的。

訪問示例服務

若在內網環境訪問部署的 HelloWorld 示例服務,可通過 SSH 登陸叢集節點,或使用叢集管理員登陸 KubeSphere 在 web kubectl 中輸入以下命令驗證訪問,其中 Cluster IP 和節點埠 (NodePort) 可通過對應專案下的服務中檢視:

驗證 Dev 環境的示例服務

# curl {$Virtual IP}:{$Port} 或者 curl {$內網 IP}:{$NodePort}
curl 10.233.40.5:8080
Hello,World!

驗證 Prodcution 環境的示例服務

# curl {$Virtual IP}:{$Port} 或者 curl {$內網 IP}:{$NodePort}
curl 10.233.42.3:8080
Hello,World!

KubeSphere (https://github.com/kubesphere/kubesphere) 是一個開源的以應用為中心的容器管理平臺,支援部署在任何基礎設施之上,並提供簡單易用的 UI,極大減輕日常開發、測試、運維的複雜度,旨在解決 Kubernetes 本身存在的儲存、網路、安全和易用性等痛點,幫助企業輕鬆應對敏捷開發與自動化監控運維、端到端應用交付、微服務治理、多租戶管理、多叢集管理、服務與網路管理、映象倉庫、AI 平臺、邊緣計算等業務場景。