進職場學到的Git - (1) Gitlab CI/CD

Posted by MingLun Allen Wu on Friday, July 17, 2020

前言

Gitlab CI/CD 是一套自動化工具,目的是在程式開發的過程中,能夠快速的驗證開發結果、根據產出盡快修正產品,將一些重複性高的工作交給自動化工具來達成。

研究所時期使用 Gitlab 來進行程式碼管控,只會做基本的 Push, Pull,完全不知道原來 Gitlab 內建有這麼強大的功能!

本篇筆記的兩個重點:

  1. 何謂 CI/CD
  2. 如何設定 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 」的方針執行,舉例來說 ,以下工作的執行順序將是:

  1. Show_PIP_List (Stage: Processing)
  2. Test (Stage: Processing)
  3. 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

註冊

詳細流程請參閱官方文件,寫得非常清楚 :

Registering Runners

開始註冊之前可以先到 Gitlab Repo 中的 Setting -> CI/CD -> Runners 頁面,此頁面包含稍後會使用到的資訊 :

  1. 開始註冊流程

    sudo gitlab-runner register
    
  2. 輸入當前的 Gitlab URL (在剛剛開啟的頁面會提示)

    Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
    https://gitlab.com
    
  3. 輸入當前 Repository 的 Token (在剛剛開啟的頁面會提示)

    Please enter the gitlab-ci token for this runner
    xxx
    
  4. 輸入當前這台機器的敘述 (未來可以再做更動)

    Please enter the gitlab-ci description for this runner
    [hostname] my-runner
    
  5. 輸入當前這台機器的標籤 (某些 CI/CD 任務可以指定特定標籤的 Runner 運行)

    Please enter the gitlab-ci tags for this runner (comma separated):
    my-tag,another-tag
    
  6. 最後要選擇 Executor,這會影響到運行時的機制,最常見的做法是選擇 docker. (細節我們在下篇文章探討)

    Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
    docker
    
  7. 如果是選擇使用 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 過程中所做的紀錄,實際上我對於這個領域還非常不熟悉,如果你願意與我分享更多資訊,非常歡迎直接聯絡我!



See Also