返回文章列表

GitLab 版本控制與 CI/CD 管道自動化實務

本文闡述從 GitLab 專案創建與程式碼版本管理,到定義 CI/CD 自動化流程的完整實務。內容涵蓋使用 Git 指令將程式碼推送至 GitLab 倉庫,並透過 .gitlab-ci.yml 文件定義 Pipeline as

DevOps 基礎設施即程式碼

在現代軟體開發生命週期中,版本控制系統不僅是程式碼的儲存庫,更是自動化流程的起點。以 GitLab 為例,其整合性的平台提供了從專案創建、程式碼管理到 CI/CD 管道執行的無縫體驗。開發團隊能透過標準 Git 工作流程進行協作,並利用 .gitlab-ci.yml 檔案以「管道即程式碼」(Pipeline as Code)的模式,宣告式地定義建置、測試與部署的各個階段。此方法不僅提升了流程的可追溯性與可重複性,更進一步延伸至基礎設施層面。透過整合 Packer、Terraform 等基礎設施即程式碼(IaC)工具,CI/CD 管道的能力從應用程式部署擴展至基礎設施的自動化佈建與配置,形成一個從程式碼提交到服務上線的完整自動化閉環,是實現高效 DevOps 文化的核心技術堆疊。

GitLab 專案創建與程式碼版本管理

本節將引導您如何在 GitLab 中創建新專案,並將您的程式碼導入其中,為後續的 CI/CD 流程奠定基礎。

創建 GitLab 專案

GitLab 提供了多種創建專案的方式,以適應不同的需求:

  1. 啟動專案創建: 在 GitLab 主頁上,點擊「Create a project」按鈕。

  2. 選擇創建模式: GitLab 提供以下幾種創建專案的選項:

    • 創建空專案: 輸入專案名稱(例如 BookDemo),即可創建一個空的倉庫,您可以稍後手動添加程式碼。
    • 從範本創建: GitLab 內建了多種專案範本,可用於快速啟動特定類型的專案。
    • 導入程式碼: 您可以從現有的內部或外部程式碼倉庫(如 GitHub、Bitbucket 等)導入程式碼。這對於遷移現有專案非常有用。

    在本實驗中,我們將選擇創建一個「空專案」,並將其命名為 BookDemo

將程式碼推送到 GitLab 倉庫

專案創建完成後,GitLab 會提供一系列 Git 命令,指導您如何將本地程式碼推送到新創建的遠端倉庫。

  1. 本地準備: 在您的本地開發環境中,創建一個新的目錄(例如 gitlab-ci-demo),並在其中創建一個名為 .gitlab-ci.yml 的文件。

  2. 執行 Git 命令: 在本地專案目錄的終端機中,執行以下 Git 命令:

    • git init: 初始化本地 Git 倉庫。
    • git remote add origin <git repo Url>: 將本地倉庫與 GitLab 的遠端倉庫連結。
    • git add .: 將所有文件添加到暫存區。
    • git commit -m "Initial commit": 提交變更,並附帶描述性訊息。
    • git push -u origin master: 將本地的 master 分支推送到遠端倉庫。

    注意: 如果專案是私有的,執行 git push 時需要輸入您的 GitLab 帳戶憑證進行驗證。

  3. 驗證推送: 推送成功後,您可以在 GitLab 的專案頁面中看到您的程式碼已成功上傳。

GitLab CI 管道:以程式碼定義

與 Azure Pipelines 類似,GitLab CI 也採用「Pipeline as Code」(PaC) 的方式,即通過在專案根目錄下創建一個 .gitlab-ci.yml 文件來定義 CI/CD 管道。

  1. 創建 .gitlab-ci.yml 文件: 在您的專案根目錄下,創建一個名為 .gitlab-ci.yml 的文件。

  2. 定義基礎配置:

    • image: microsoft/dotnet:latest: 指定用於執行管道任務的 Docker 鏡像。這裡使用了一個包含 .NET SDK 的 Microsoft 鏡像。
    • stages: 定義管道的階段。在此範例中,定義了 buildtest 兩個階段。任務將按照這些階段的順序執行。

視覺化 GitLab 專案創建與程式碼推送流程

以下圖示展示了在 GitLab 中創建專案並推送程式碼的步驟。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

start

component "GitLab Project & Code Management" {
  node "Create Project" {
    :Click "Create a project";
    :Choose Creation Option (e.g., Empty Project);
    :Enter Project Name (e.g., BookDemo);
    :Validate Creation;
  }

  node "Local Setup" {
    :Create Local Directory;
    :Create .gitlab-ci.yml file;
  }

  node "Git Operations" {
    :git init;
    :git remote add origin <repo URL>;
    :git add .;
    :git commit -m "Initial commit";
    :git push -u origin master;
  }

  node "Remote Repository" {
    :View Code in GitLab UI;
  }
}

Create Project --> Local Setup : Prepare for Code Push
Local Setup --> Git Operations : Initialize and Stage Code
Git Operations --> Remote Repository : Upload Code to GitLab

stop

@enduml

看圖說話:

此圖示展示了在 GitLab 中創建專案並將本地程式碼推送上去的流程。首先,用戶「Click ‘Create a project’」,然後「Choose Creation Option」(例如選擇創建一個空專案),接著「Enter Project Name」(如 BookDemo)並「Validate Creation」。

專案創建後,進入「Local Setup」階段,用戶需要在本地「Create Local Directory」並創建 .gitlab-ci.yml 文件。隨後,在「Git Operations」階段,執行一系列 Git 命令,包括初始化倉庫、添加遠端、添加文件、提交以及最終的 git push 命令,將程式碼上傳到 GitLab。最後,可以在「Remote Repository」中「View Code in GitLab UI」,確認程式碼已成功存儲。

GitLab CI 管道定義與執行細節

本節將深入探討 GitLab CI 的 .gitlab-ci.yml 文件語法,並展示如何查看管道的執行細節。

.gitlab-ci.yml 文件結構與內容

一個典型的 GitLab CI 管道定義文件包含以下關鍵元素:

  1. image: 指定用於執行管道任務的預設 Docker 鏡像。範例中使用的 microsoft/dotnet:latest 鏡像包含了 .NET SDK,這對於編譯和測試 .NET 應用程式至關重要。

  2. variables: 允許定義可在管道腳本中使用的變數。在此範例中,BuildConfiguration: "Release" 定義了一個名為 BuildConfiguration 的變數,其值為 “Release”,用於指定編譯模式。

  3. stages: 定義管道的執行階段。stages: - build - test 表示管道將按順序執行 buildtest 這兩個階段。

  4. build 階段:

    • stage: build: 指定此任務屬於 build 階段。
    • script: 包含在該階段要執行的命令。
      • cd app: 進入應用程式目錄。
      • dotnet restore: 還原 NuGet 套件。
      • dotnet build --configuration $BuildConfiguration: 使用指定的構建配置(在此為 “Release”)編譯應用程式。
  5. test 階段:

    • stage: test: 指定此任務屬於 test 階段。
    • script:
      • cd tests: 進入測試專案目錄。
      • dotnet test --configuration $BuildConfiguration: 使用指定的構建配置運行單元測試。

提交與觸發管道

  1. 提交與推送: 將編寫好的 .gitlab-ci.yml 文件提交並推送到 GitLab 倉庫。

  2. 自動觸發: 一旦文件被推送到倉庫,GitLab CI 會自動檢測到 .gitlab-ci.yml 文件,並根據其定義觸發管道的執行。

查看 CI 管道執行詳情

您可以通過 GitLab 的 Web 界面來監控和查看管道的執行情況:

  1. 導航至 Pipelines: 在 GitLab 項目中,導航至「CI / CD」>「Pipelines」。這裡會列出所有管道的執行記錄。

  2. 查看執行狀態: 點擊列表中的某個管道執行,可以查看其詳細狀態,包括各個階段(如 buildtest)的執行情況。

  3. 查看日誌: 點擊具體的階段,可以查看該階段執行腳本的詳細日誌輸出。這有助於您理解每個步驟的執行過程,並排查潛在問題。

視覺化 GitLab CI 管道執行流程

以下圖示展示了 GitLab CI 管道的定義、觸發與執行監控流程。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

start

component "GitLab CI Pipeline Workflow" {
  node "Define Pipeline" {
    :Create .gitlab-ci.yml file;
    :Define image, variables, stages;
    :Configure build and test scripts;
  }

  node "Trigger Pipeline" {
    :Commit and push .gitlab-ci.yml;
    :GitLab CI automatically detects and triggers;
  }

  node "Execute Pipeline" {
    :Run tasks in defined stages (build, test);
    :Utilize specified Docker image;
  }

  node "Monitor Execution" {
    :Navigate to CI / CD > Pipelines;
    :View pipeline list and status;
    :Click on specific pipeline for details;
    :Inspect stage logs;
  }
}

Define Pipeline --> Trigger Pipeline : Version Control Integration
Trigger Pipeline --> Execute Pipeline : Automation Activation
Execute Pipeline --> Monitor Execution : Feedback Loop

stop

@enduml

看圖說話:

此圖示描繪了 GitLab CI 管道的完整生命週期。首先,「Define Pipeline」階段涉及創建 .gitlab-ci.yml 文件,其中定義了 Docker 鏡像、變數、執行階段以及構建和測試腳本。

接著,「Trigger Pipeline」階段,當 .gitlab-ci.yml 文件被提交並推送到倉庫時,GitLab CI 會自動檢測到它並觸發管道的執行。

「Execute Pipeline」階段是管道實際運行的地方,任務按照定義的階段順序在指定的 Docker 環境中執行。

最後,「Monitor Execution」階段,用戶可以通過 GitLab 的 Web 界面導航到「CI / CD > Pipelines」,查看管道的執行列表和狀態,並深入查看特定管道的詳細信息和日誌,從而獲得執行反饋。

利用 CI/CD 管道自動化基礎設施即程式碼 (IaC)

本章將整合先前學到的基礎設施即程式碼 (IaC) 工具(如 Packer、Terraform、Ansible)與 CI/CD 流程,實現基礎設施自動化配置與部署。我們將以 Azure Pipelines 作為 CI/CD 工具,並採用 YAML 格式定義管道。

目標與內容概述

本章的目標是展示如何利用 CI/CD 管道自動化 IaC 工作流程,包括:

  • 使用 Packer 構建基礎設施映像: 在 Azure Pipelines 中自動化 Packer 的映像構建過程。
  • 使用 Terraform 佈建虛擬機器: 在 Azure Pipelines 中配置 Terraform,自動化虛擬機器的創建。
  • 使用 Ansible 配置虛擬機器: 結合 Terraform 和 Ansible,自動化虛擬機器的配置,例如安裝 Nginx 伺服器。

技術先決條件

為順利進行本章的實踐,您需要具備以下條件:

  • Azure 訂閱: 用於創建 Packer 映像和佈建虛擬機器。
  • Azure DevOps 帳戶: 用於創建和管理 YAML 格式的 CI/CD 管道定義。

使用 Packer 在 Azure Pipelines 中自動化映像構建

本節將重點介紹如何利用 Azure Pipelines 自動化 Packer 的映像構建過程。

  1. 準備 Azure 資源: 首先,您需要在 Azure 中創建一個資源群組,用於存放 Packer 構建的虛擬機器映像。例如,可以創建一個名為 rg_images 的資源群組。

  2. 編寫 Azure Pipelines YAML 文件: 在與 Packer 範本文件 (.pkr.hcl) 相同的目錄下,創建一個新的 YAML 文件來定義 CI 管道。此文件將包含執行 Packer 命令的腳本。

    以下是管道定義的關鍵步驟:

    • packer init:

      • 腳本: script: packer init $(Build.SourcesDirectory)/CHAP08/packer/.pkr.hcl
      • 顯示名稱: Packer init
      • 目的: 初始化 Packer 專案,下載所需的插件和模塊。$(Build.SourcesDirectory) 是 Azure Pipelines 預定義的變數,指向包含原始碼的目錄。
    • packer validate:

      • 腳本: script: packer validate $(Build.SourcesDirectory)/CHAP08/packer/.pkr.hcl
      • 顯示名稱: Packer validate template
      • 目的: 驗證 Packer 範本文件的語法和結構是否正確,確保其可被解析。
    • packer build:

      • 腳本: script: packer build $(Build.SourcesDirectory)/CHAP08/packer/.pkr.hcl
      • 顯示名稱: Packer build template
      • 目的: 執行 Packer 命令,根據範本文件自動化創建虛擬機器映像的過程。

視覺化 Packer 管道執行流程

以下圖示展示了在 Azure Pipelines 中執行 Packer 命令的流程。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

start

component "Azure Pipelines Packer Integration" {
  node "Pipeline Definition" {
    :YAML file defines pipeline steps;
  }

  node "Packer Initialization" {
    :Execute 'packer init' command;
    :Initialize Packer project and plugins;
  }

  node "Template Validation" {
    :Execute 'packer validate' command;
    :Verify Packer template syntax and structure;
  }

  node "Image Building" {
    :Execute 'packer build' command;
    :Automate VM creation and image capture;
  }

  node "Azure Resource Group" {
    :Store created VM image;
  }
}

Pipeline Definition --> Packer Initialization : Define Execution Steps
Packer Initialization --> Template Validation : Ensure Correctness
Template Validation --> Image Building : Proceed with Build
Image Building --> Azure Resource Group : Store Final Artifact

stop

@enduml

看圖說話:

此圖示描繪了在 Azure Pipelines 中使用 Packer 自動化映像構建的流程。首先,「Pipeline Definition」階段,一個 YAML 文件定義了整個管道的步驟。

接著,「Packer Initialization」階段執行 packer init 命令,準備 Packer 環境。然後,「Template Validation」階段執行 packer validate,確保 Packer 範本文件的語法正確。

核心是「Image Building」階段,執行 packer build 命令,自動化虛擬機器的創建和映像的捕獲。最終的映像會被存儲在「Azure Resource Group」中。這個流程將 Packer 的映像構建能力與 Azure Pipelines 的自動化執行能力結合起來,實現了 IaC 的映像管理。

縱觀現代管理者的多元挑戰,將開發與維運流程的標準化與自動化,已從技術選項演變為組織效能的核心驅動力。本文所展示的實踐,從 GitLab 的專案初始化、程式碼版本管理,到利用 .gitlab-ci.yml 與 Azure Pipelines YAML 實現「管道即程式碼(Pipeline as Code)」,其真正價值並非單一工具的熟練操作,而在於將應用程式交付與基礎設施管理的完整生命週期,整合為一個連貫、可追溯且高度自動化的體系。

分析其核心挑戰,真正的瓶頸往往不在於學習 YAML 或 HCL 的語法,而在於推動團隊建立將一切「即程式碼」的文化心態。這種從依賴手動干預轉向信任自動化流程的思維轉變,才是釋放完整績效潛力的關鍵。實務上,最有效的路徑是循序漸進:先鞏固版本控制的紀律,再疊加應用程式的持續整合,最終將自動化延伸至基礎設施的佈建與配置。

展望未來,此類整合管道的生態系統將進一步融合安全掃描(DevSecOps)與智慧維運(AIOps),形成更具韌性的自我修復與優化機制。玄貓認為,對於追求卓越績效的管理者而言,當務之急是將建立「管道即程式碼」的核心能力視為戰略投資。這不僅是提升 IT 效率的工具,更是決定組織未來創新速度、交付品質與市場應變能力的關鍵基石。