---
# System prepended metadata

title: Gitlab CI/CD 入門

---

# Gitlab CI/CD 入門
## 簡介
+ 什麼是 CI/CD
CI (Continuous Integration)、CD (Continuous Delivery/Deployment) 目的是從測試、建置到部署自動化，取代原來人工需要做的事情。
  + CI (Continuous Integration): 專注在持續整合，透過程式碼的自動化測試和建置，將穩定品質的程式碼合併，越早頻繁整合，整合難度的就越低且能確保最新版本是可運行的
  + CD (Continuous Delivery/Deployment): 專注在持續部屬和交付，依照需要的環境進行建置和部屬
![](https://i.imgur.com/pLTIQfj.png)

+ Gitlab CI/CD 架構
  + Gitlab Server
  + Watcher: 監聽新 commit，Gitlab CI/CD 已於背後實作
  + CI/CD configuration file: 定義執行腳本，預設為 .gitlab-ci.yml
  + Gitlab Runner: 負責執行腳本的的 instance (VM, docker...)
  + Gitlab API or 3rd party integration (optional)
![](https://i.imgur.com/2lmYh8Y.png)

## 動手做
+ Runner 設定，將自己的電腦化為 runner
    + [Windows Runner](https://docs.gitlab.com/runner/install/windows.html)，下載 exe 檔後 rename 為 gitlab-runner.exe 置於 C:\GitLab-Runner 資料夾下
    + Runner 註冊
    ```shell=
    cd C:\GitLab-Runner
    .\gitlab-runner.exe install
    .\gitlab-runner.exe start
    .\gitlab-runner.exe register 
    ```
    + Runner Register Configuration
      ![](https://i.imgur.com/kb9Mllb.png)
      + Enter the GitLab instance URL (如圖)
      + Enter the registration token (如圖)
      + Enter a description for the runner: runner 名稱
      + Enter tags for the runner: runner tag，可以影響腳本要用哪個 runner 跑
      + Enter optional maintenance note for the runner: 詳細描述，可留空
      + Enter an executor: shell
      + ==更正 config.toml: 將 pwsh 改成 powershell==
    + 至 gitlab 頁面確認 runner 狀態
    ```shell=
    cd C:\GitLab-Runner
    .\gitlab-runner.exe status
    .\gitlab-runner.exe verify
    ```
+ 腳本撰寫
  + fork veena repository，並新增 .gitlab-ci.yml (deafult file name)
  + 牛刀小試：Hello World
    + yaml 語法
    + 可在與 runner 類似的環境測試語法，確保 runner 看得懂語法
    + 腳本執行結果的 exit code 必須為 0 該 stage 才會成功
    + 不可以有與使用者互動的語法，不然會執行失敗
    + 利用 tags 匹配挑選 runner
    ```yaml=
    stages:
      - hello

    hello:
      stage: hello
      tags: 
        - kyo-cicd
      script:
        - cd C:\
        - echo "hello world" > hello.txt
    ```
  + stages 及 pipeline： multiple stage
    + 有順序性
    + 可平行執行 stage
    + 失敗即不再往前執行
    + 可設定該 stage 自動執行、手動執行或特定條件執行
    + 每個 stage 皆為獨立，如需要保留結果到下個 stage，需暫存至某地（如 artifacts, docker hub 等等）
    ![](https://i.imgur.com/KoHbQ1f.png)
    ```yaml=
    stages:
      - test
      - build-dev
      - deploy-dev

    test:
      stage: test
      tags:
        - kyo-cicd
      script:
        - npm install    
        - echo "test completed"

    build:
      stage: build-dev
      tags:
        - kyo-cicd
      script:
        - echo "build code" > build-dev.txt
      artifacts:
        paths:
          - build-dev.txt
        expire_in: 10 day

    deploy:
      stage: deploy-dev
      tags:
        - kyo-cicd
      script:
        - Copy-Item build-dev.txt C:\deploy-dev.txt
    ```
  + 環境變數
    + 設定於 Gitlab GUI
    ![](https://i.imgur.com/y708IhJ.png)
    + 設定於 Gitlab yaml
    + [Gitlab 預設有的環境變數](https://docs.gitlab.com/ee/ci/variables/)
    ```yaml=
    variables:
      AUTHOR: Kyo
    ...
        - echo $PASSWORD$CI_JOB_ID > build-dev.txt
    ...
        - Copy-Item build-dev.txt C:\$AUTHOR.txt
    ```
  + template
    ```yaml=
    ...
    .deploy-template:
      tags:
        - kyo-cicd
      script:
        - Copy-Item build-dev.txt C:\$AUTHOR-$ENV.txt
    ...
    deploy:
      stage: deploy
      variables: 
        ENV: dev
      extends:
        - .deploy-template
    ...
    ```

+ 動手做到此為止，==請至 gitlab 頁面移除測試用 runner== 

## 補充
+ Runner 環境
  + Runner 類型
    + Instance
      + 環境必須設定到所有指令 runner 都看得懂 (如: git, ssh, 對應的 sdk 及 runtime 等等)
    + Image (Recommend: Alpine image)
      + [register runner 時，executor 選擇 docker](https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#register-a-runner-that-uses-the-docker-executor)
      + 無法撰寫 image 看不懂的指令
      + C#: mcr.microsoft.com/dotnet/sdk:6.0-alpine
      + Node.js: node:lts-alpine
  + Runner 層級
    + Group Runner
    + Shared Runner
    + Project Runner
  + 環境類型
    + 如果用到 git 指令，runner 需要安裝 [Git client](https://git-scm.com/download/win)
    + 如果用到 ssh 指令，ruuner 需安裝 Openssh client，目標機器需安裝 [Openssh Server](https://www.hostwinds.com/tutorials/how-to-install-and-configure-openssh-windows-server-2016)，且必須先設定好 key pair 配對。 
+ API 與第三方整合
  + Webhook: Settings > Webhook
  + Gitlab API: User Settings > Access Tokens > Call gitlab API with token (User Settings
Access Tokens)
  + 第三方整合: Settings > Integration > Slack notification, Jira.. etc

## 目前常見作法
1. CI/CD pipeline 過程中將最新程式 build 成 image 推到 docker hub
2. 通知 k8s 或 load balancer 從 docker hub pull 最新的 image 來完成更版
2.1. 為避免 runner 權限過大，有些公司會將部署 k8s 權限交由 ArgoCD 控管
![](https://i.imgur.com/GrDSbSV.png)


==Gitlab CI/CD 細節上還有很多參數可以用，設計的好壞也會影響部署速度，同時也提供 API 與程式或第三方整合，都等著你去發現==

+ Ref 
 https://linyencheng.github.io/2022/05/30/devops-gitlab-ci-and-gitlab-runner/
 https://ithelp.ithome.com.tw/articles/10238855
 https://ithelp.ithome.com.tw/articles/10241701
 https://docs.gitlab.com/ee/ci/variables/