前言
Gitlab CI/CD
是一套自動化工具,目的是在程式開發的過程中,能夠快速的驗證開發結果、根據產出盡快修正產品,將一些重複性高的工作交給自動化工具來達成。
研究所時期使用 Gitlab
來進行程式碼管控,只會做基本的 Push, Pull,完全不知道原來 Gitlab
內建有這麼強大的功能!
本篇筆記的兩個重點:
- 何謂 CI/CD
- 如何設定
Gitlab
內建的 CI/CD 功能
何謂 CI/CD
CI 及 CD 概念上相同,在程式碼進行更動後,自動運行「預先定義好的流程」:
按照目的來劃分:
Continuous Integration - 檢驗程式碼的正確性:
在開發程式的過程中,為了避免Bug影響到整個系統,通常修改完模組後會做一些測試。 這些重複性高的測試就能透過 pipeline來自動檢驗。目的是協助開發者進行檢驗,避免開發時把「有問題」的程式碼整併回重要的主支中。
Continuous Deployment - 將正確的程式碼部署到正式環境中運行 :
在確定開發完成後,可以透過自動的 pipeline來將更新後的程式碼重新啟動、Build新的系統、部署到正式的伺服器上。
Gitlab CI/CD Pipeline
在前一小節提到,CI/CD 其實是在程式碼更動後,自動進行預先定義好的 Pipeline,接下來要介紹 Pipeline 的重要概念。
在 Pipeline 中有兩個概念 Stage 及 Job:
Job
Job 是 Pipeline 中最基礎的單位,每一個 Job 可以是數行 Script,其中可能也會執行某些預先寫好的 Script File. 當執行完所有定義好的 Script 沒有發生錯誤,就算是成功完成這項 Job.
Stage
一個 Stage 中包含了一至多項的 Job,通常 Stage 是用來區分「不同的工作階段」,較常見的區分方法是: build(建構系統)、validate(驗證系統)、deploy(部署至主要伺服器)。
而在執行 Job 時是先以「先 Stage 後 Job 」的方針執行,舉例來說 ,以下工作的執行順序將是:
- Show_PIP_List (Stage: Processing)
- Test (Stage: Processing)
- Download (Stage: Download)
當前一項 Stage 中的任一項 Job 執行失敗時,將不會執行下一個 Stage. (舉例來說如果執行 Test
時失敗了, Download
將不會被執行)
How to set pipeline?
在了解 Pipeline 的概念後,在 Gitlab
中預設以 Repo 中的 .gitlab-ci.yml
檔案來做為 CI/CD 流程的設定檔。
我們透過簡單的範例來說明 .gitlab-ci.yml
的結構 :
before_script: # 執行測試前所要執行的程式碼。 (例如安裝套件)
- export PATH=$PATH:/home/allen_wu/miniconda3/envs/pytorch/bin/
stages: # 定義不同的階段(stage),每一個stage可以包含許多job.
- preprocessing
- download
Show_PIP_list: # 第一項Job (名稱可以自訂)
stage: preprocessing # 隸屬的 Stage
script:
- ls -al # 第一項Job 的第一項步驟 (Bash指令)
- pip list # 第一項Job 的第二項步驟 (Bash指令)
Test: # 第二項Job (名稱可以自訂)
stage: preprocessing
script:
- echo "Test" # 第二項Job的第一項步驟 (Bash指令)
Download: # 第三項Job (名稱可以自訂)
stage: download
script:
- echo "Download" # 第三項Job的第一項步驟 (Bash指令)
當你在 Repository Push 了此份 .gitlab-ci.yml
後,整個 CI/CD 流程就設定完成了。但是此時當你將程式碼 Push 至 Repo 時可能會發現一件奇怪的事情 : 我的任務都顯示 “Pending” !
這是因為雖然設定了 CI 流程,卻沒有設定 Runner,也就是執行的機器。
完整的 CI /CD 流程如下:
在 Gitlab
偵測到 Code 的更動後,會將更動後的 Code 傳到 “Runner” 上執行特定的任務 (也就是 .gitlab-ci.yml
所定義的任務),所以接下來我們必須要設定一台可供執行任務的主機,你可以租用雲端主機,或是直接使用手邊的主機作為Runner。
建立 Gitlab Runner
安裝
可以參考此篇官方文章,根據做為Runner的主機的作業系統選擇安裝方式:
Install GitLab Runner using the official GitLab repositories
以 Ubuntu 為例,透過下列指令即可安裝:
# For Debian/Ubuntu/Mint
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
# For Debian/Ubuntu/Mint
sudo apt-get install gitlab-runner
註冊
詳細流程請參閱官方文件,寫得非常清楚 :
開始註冊之前可以先到 Gitlab Repo 中的 Setting -> CI/CD -> Runners
頁面,此頁面包含稍後會使用到的資訊 :
開始註冊流程
sudo gitlab-runner register
輸入當前的 Gitlab URL (在剛剛開啟的頁面會提示)
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com ) https://gitlab.com
輸入當前 Repository 的 Token (在剛剛開啟的頁面會提示)
Please enter the gitlab-ci token for this runner xxx
輸入當前這台機器的敘述 (未來可以再做更動)
Please enter the gitlab-ci description for this runner [hostname] my-runner
輸入當前這台機器的標籤 (某些 CI/CD 任務可以指定特定標籤的 Runner 運行)
Please enter the gitlab-ci tags for this runner (comma separated): my-tag,another-tag
最後要選擇 Executor,這會影響到運行時的機制,最常見的做法是選擇
docker
. (細節我們在下篇文章探討)Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell: docker
如果是選擇使用
docker
做為 Excutor,需要指定一個預設的 Docker Image.Please enter the Docker image (eg. ruby:2.6): python:latest
當我們的 Runner 選擇 docker
作為 Excutor 時,運行 CI 任務時會先建立一個 Docker 環境,當我們回頭去看 .gitlab-ci.yml
時,會發現第一行有一個 images: python:latest
,這代表指定執行任務時使用的 Docker Image。
而步驟 7 是指當 .gitlab-ci.yml
沒有指定 Docker Image 時該使用哪一項Docker Image. ( Executor 的更多細節我們在下一篇文章探討)
當你註冊完成後你應該會在 Gitlab 的 Setting → CI/CD → Runners
頁面中看到剛剛所註冊的 Runner:
測試 CI/CD 是否正常運行
在確認完成後我們實際送上一個 Commit,當我們點擊 Gitlab 頁面的 Repository -> Commits
時,可以看到在每個 Commit 的右邊都出現 CI/CD 的狀態:
此時基本的 Gitlab CI/CD
機制已經建構完成! 每次上傳程式碼後,Gitlab
會自動協助進行程式碼的檢核,可以在Gitlab
的頁面確認每次開發是否有發生異常。
後記
本篇筆記介紹了何為 CI/CD 以及如何使用 Gitlab
內建的工具進行 CI/CD。然而進行深度學習的模組開發時,常會遇到「模型」檔案體積龐大,此時使用 Docker 作為 Executor 在建立過程中常會遇到網路不穩導致CI中斷的問題。
在下篇筆記中我們會介紹安裝 Gilab Runner
時的 Executor 有何不同?、如何選用其他 Executor 來解決 CI 中斷的問題,以及實際在開發過程中該怎麼使用「CI/CD功能」結合「分支」、「Merge Requests」! 我們下次見!
這篇筆記是我在實際部署 CI/CD 過程中所做的紀錄,實際上我對於這個領域還非常不熟悉,如果你願意與我分享更多資訊,非常歡迎直接聯絡我!