Jenkins Pipeline as Code 讓開發者能以程式碼定義建置流程,提升自動化程度與版本控管能力。本文首先介紹如何使用 Jenkins Linter API 和 Jenkins CLI 驗證 Jenkinsfile,並說明 IDE 整合的設定步驟,讓開發者能在開發階段及早發現錯誤。接著,文章探討 Jenkins 分散式建置架構,說明主節點負責任務排程與監控,而工作節點負責執行建置任務。透過主從架構,能有效分配建置負載,提升建置效率。最後,文章以 AWS 雲端環境為例,說明如何利用 Auto Scaling Group 和 CloudWatch 建立可動態擴充套件的 Jenkins 叢集,並透過安全群組設定與監控機制確保叢集的穩定性和安全性。

使用 Jenkins 實作 Pipeline as Code

Jenkins Linter API 的應用

Jenkins Linter API 提供了一種驗證 Jenkinsfile 語法和結構的有效方法。透過這個 API,開發者可以在提交程式碼之前檢查 Jenkinsfile 是否存在錯誤或警告,從而節省開發時間並遵循最佳實踐。

使用 cURL 命令驗證 Jenkinsfile

可以使用以下命令透過終端驗證 Jenkinsfile:

curl -X POST -L --user USERNAME:TOKEN JENKINS_URL/pipeline-model-converter/validate -F "jenkinsfile=<Jenkinsfile"

#### 內容解密:

  • curl 是一個用於傳輸資料的命令列工具。
  • -X POST 指定請求方法為 POST。
  • -L 選項使 curl 跟隨重定向。
  • --user USERNAME:TOKEN 用於提供 Jenkins 使用者名稱和 API Token 進行身份驗證。
  • JENKINS_URL/pipeline-model-converter/validate 是 Jenkins Linter API 的端點。
  • -F "jenkinsfile=<Jenkinsfile" 將本地的 Jenkinsfile 檔案傳送到伺服器進行驗證。

Jenkins 命令列介面(CLI)的使用

Jenkins CLI 提供了一種透過命令列與 Jenkins 互動的方式。可以使用 declarative-lint 選項來檢查 Declarative Pipeline 的語法:

ssh -p $JENKINS_SSHD_PORT $JENKINS_HOSTNAME declarative-linter < Jenkinsfile

#### 內容解密:

  • ssh 命令用於建立安全的 Shell 連線。
  • -p $JENKINS_SSHD_PORT 指定連線的埠。
  • $JENKINS_HOSTNAME 是 Jenkins 伺服器的主機名或 IP 地址。
  • declarative-linter 是用於檢查 Jenkinsfile 語法的命令。
  • < Jenkinsfile 將本地的 Jenkinsfile 檔案重定向到命令輸入。

IDE 整合

為了進一步簡化 Jenkinsfile 的驗證過程,可以在 IDE 中安裝相關的外掛程式,如 Visual Studio Code 的 Jenkins Validation Linter。

設定 Jenkins Pipeline Linter 外掛程式

  1. 安裝外掛程式後,開啟設定頁面。
  2. 組態 Jenkins 伺服器的 URL 和認證資訊。

使用命令面板驗證 Jenkinsfile

在 VSCode 中,可以透過命令面板(⇧⌘P)執行「Validate Jenkinsfile」命令來驗證 Jenkinsfile。

定義 Jenkins 架構

分散式建置的重要性

在分散式微服務架構中,可能需要定期建置、測試和佈署多個服務。因此,擁有多台建置機器是合理的。雖然可以在單一機器上執行 Jenkins,但對於較大型的專案,這可能會成為單點故障。

主從式架構(Master/Worker)

Jenkins 可以組態為在多台機器/節點上執行分散式建置,透過設定主從式叢集來實作。

本章涵蓋內容

 瞭解 Jenkins 分散式建置的工作原理。  瞭解 Jenkins 主節點和工作節點的角色。  在雲端架構 Jenkins 以實作擴充套件性。  組態多個 Jenkins 主節點。  準備 AWS 環境和 CLI 組態。

Jenkins 主從式架構示意圖

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333

title Jenkins 主從式架構示意圖

rectangle "控制" as node1
rectangle "執行建置任務" as node2

node1 --> node2

@enduml

圖表翻譯: 此圖示展示了 Jenkins 的主從式架構。Jenkins Master 負責控制多個 Jenkins Worker 節點,這些 Worker 節點負責執行實際的建置任務並傳回結果給 Master。這種架構使得建置過程可以分散到多台機器上,提高了建置效率和系統的可擴充套件性。

Jenkins架構定義與分散式架構解析

Jenkins採用主從式架構(master-worker architecture)來管理分散式建置作業,每個元件都有其特定的角色:

主節點(Jenkins Master)與工作節點(Jenkins Worker)

  • Jenkins主節點:負責排程建置作業並將建置任務分配給工作節點執行,同時監控工作節點的狀態並收集和彙總建置結果於網頁儀錶板中。
  • Jenkins工作節點(也稱為slave或build agent):是一個Java可執行檔,執行於遠端機器上,監聽來自Jenkins主節點的請求並執行建置作業。

主從式架構的優勢

在主從式架構中,網頁儀錶板執行於Jenkins主節點上。主節點負責排程建置作業、將建置任務分派給工作節點執行、監控工作節點狀態(線上或離線),以及記錄和呈現建置結果。即使在分散式架構中,Jenkins主節點也可以直接執行建置作業。

工作節點的管理與組態

可以透過Jenkins儀錶板或Jenkins RESTful API新增和組態工作節點。工作節點的角色是執行由主節點分配的建置作業。可以透過為節點分配標籤(labels)來組態專案始終在特定節點上執行。標籤是一種強大的功能,代表虛擬群組名稱,可以為工作節點分配多個標籤。

新增工作節點

  1. 在管理頁面選單中點選「Manage Jenkins」。
  2. 點選「Manage Nodes」並選擇「Add New Node」。
  3. 填寫組態資訊,包括節點名稱、工作區名稱和節點的IP地址。
  4. 輸入標籤(如workers),可透過空格分隔多個標籤。

設定建置作業執行環境

在宣告式Pipeline(declarative pipeline)中,可以透過設定agent指令來限制Pipeline在具有特定標籤的節點上執行:

pipeline {
    agent {
        label 'workers'
    }
    stages {
        stage('Checkout') {}
    }
}

在指令碼式Pipeline(scripted pipeline)中,則使用node區塊包裝器並傳入標籤名稱作為引數來定義執行環境:

node('workers') {
    stage('Checkout') {}
}

工作節點的通訊與Java安裝需求

為了將工作節點新增至Jenkins叢集,工作節點和主節點需要透過TCP/IP建立雙向通訊。此外,工作節點機器上需要安裝Java。由於Java是一種跨平台的程式語言,Jenkins叢集可以包含執行在不同作業系統平台(如Windows、Linux或macOS)上的工作節點。

多重執行器的組態

預設情況下,每個節點可以執行一個作業,但可以透過設定# of Executors欄位來增加節點執行作業的能力。例如,若將該欄位設為3,則最多可同時執行三個作業。如果啟動四個作業,前三個將立即執行,而第四個將被加入建置佇列中,等待有可用節點時再執行。

管理Jenkins工作節點的策略

有多種策略可用於管理Jenkins工作節點,取決於目標作業系統和其他架構考量。常見的管理策略包括使用SSH或Java Network Launch Protocol(JNLP)來啟動工作節點。

使用SSH管理工作節點

在UNIX環境中,最方便的方式是使用Secure Shell(SSH)。Jenkins內建SSH客戶端,而幾乎所有UNIX環境都支援SSH(通常是sshd)。這種方式使得在不同作業系統(如Windows、Linux或macOS)上設定多個工作節點成為可能,從而建立一個支援多種環境的異質建置農場(heterogeneous build farm)。

圖示:多重作業系統的工作節點組態

此圖示呈現了一個包含多個工作節點的Jenkins叢集,每個工作節點執行於不同的作業系統上。

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333

title 圖示:多重作業系統的工作節點組態

rectangle "SSH/JNLP" as n1
rectangle "SSH/JNLP" as n2
rectangle "SSH/JNLP" as n3

n1 --> n2
n2 --> n3

@enduml

圖表翻譯: 此圖示描述了一個包含一個Jenkins主節點和多個執行於不同作業系統上的工作節點的叢集。主節點透過SSH或JNLP與工作節點通訊,以分配和執行建置作業。

管理Jenkins工作節點

Jenkins工作節點需要能夠被主伺服器存取,因此你需要提供主機名稱、登入資訊和密碼。你也可以提供主伺服器上SSH私鑰檔案的路徑,以使用公鑰/私鑰認證,如圖3.4所示。

3.2.1 SSH啟動方式

透過SSH啟動Jenkins工作節點是一種常見的方法。這種方法需要在主伺服器上能夠透過SSH連線到工作節點。

內容解密:

  • 需要在主伺服器上生成SSH金鑰對,並將公鑰複製到工作節點上。
  • 在Jenkins管理介面中,新增工作節點並選擇SSH啟動方式。
  • 需要輸入工作節點的主機名稱、登入使用者名稱和密碼,或是使用私鑰檔案進行認證。

3.2.2 命令列啟動方式

你也可以透過在主伺服器上執行命令列來新增工作節點,如圖3.5所示。這種方法適用於主伺服器能夠遠端執行其他機器上的程式。不過,自Jenkins 2.54版本以來,遠端模式已被棄用,因此在最新版本的Jenkins中可能不再有效。

內容解密:

  • 需要在主伺服器上組態遠端執行命令列的環境。
  • 在Jenkins管理介面中,新增工作節點並選擇命令列啟動方式。
  • 需要輸入遠端執行的命令列指令。

3.2.3 JNLP啟動方式

另一種方法是從工作節點本身使用Java Web Start (JWS) 啟動代理。這種方法適用於主伺服器無法存取工作節點的情況,例如工作節點位於防火牆後面。不過,這種方法有一些缺點:工作節點無法被Jenkins自動啟動或重新啟動。

內容解密:

  • 需要在工作節點上安裝Java執行環境。
  • 在Jenkins管理介面中,新增工作節點並選擇JNLP啟動方式。
  • 需要在工作節點上開啟瀏覽器,存取Jenkins主伺服器的網頁介面,並下載JNLP檔案來啟動工作節點。

3.2.4 Windows服務啟動方式

Jenkins也可以透過Windows DCOM Server Process Launcher服務來管理遠端Windows工作節點,如圖3.6所示。這種方法不需要物理連線到Windows機器就能進行設定。

內容解密:

  • 需要在Windows工作節點上啟用Windows DCOM Server Process Launcher服務。
  • 在Jenkins管理介面中,新增工作節點並選擇Windows服務啟動方式。
  • 需要輸入Windows主機名稱、使用者名稱和密碼。

組態Jenkins工作節點監控

一旦工作節點被新增到Jenkins叢集中,主伺服器就會主動監控它們的狀態。如果工作節點被認為無法安全地執行建置作業,主伺服器就會將其標記為離線。你可以在「管理節點」頁面中調整Jenkins的監控閾值,如圖3.7所示。

圖表翻譯:

此圖示展示了Jenkins管理介面中的「管理節點」頁面,用於設定工作節點的監控閾值。

內容解密:

  • Jenkins監控每個工作節點上的$JENKINS_HOME可用磁碟空間、暫存目錄和交換空間。
  • 同時監控主伺服器和工作節點之間的系統時鐘差異和網路往返時間。
  • 如果任何一個指標低於設定的閾值,工作節點就會被標記為離線。

在AWS上架構Jenkins以實作擴充套件

本文將介紹如何在AWS上架構Jenkins以實作擴充套件。你需要一個AWS帳戶來跟隨範例。透過新的AWS帳戶,「免費層級」應該能夠涵蓋所有範例,而不會產生任何費用。

簡單架構

最簡單的架構是在Amazon Elastic Compute Cloud (EC2)例項上佈署Jenkins伺服器。你可以從AWS Marketplace中選擇Jenkins Long-Term Support (LTS)版本和適當的機器例項型別,如圖3.9所示。

內容解密:

  • 需要在AWS Marketplace中搜尋Jenkins並選擇適當的版本。
  • 需要組態EC2例項的安全群組,以允許對埠8080的流量存取。

安全群組組態

安全群組就像是一個防火牆,用於控制允許到達EC2例項的流量,如圖3.10所示。你需要在安全群組中新增規則,以允許對埠8080的入站流量。

內容解密:

  • 需要在安全群組中新增一條規則,以允許對埠8080的入站流量。
  • 這樣就可以從外部存取Jenkins儀錶板。
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333

title 內容解密:

rectangle "SSH" as node1
rectangle "Command Line" as node2
rectangle "JNLP" as node3
rectangle "Windows Service" as node4

node1 --> node2
node2 --> node3
node3 --> node4

@enduml

圖表翻譯: 此圖示展示了Jenkins主伺服器與不同型別的工作節點之間的連線方式,包括SSH、命令列、JNLP和Windows服務。

在AWS上擴充套件Jenkins的架構設計

在前面的章節中,我們討論瞭如何在AWS上建立Jenkins伺服器。然而,當專案規模擴大時,單一Jenkins主伺服器可能無法負擔所有的建置工作。因此,本章節將探討如何設計一個可擴充套件的Jenkins架構,以滿足大型專案的需求。

安全群組的設定

在建立Jenkins伺服器時,我們需要設定安全群組(Security Group)以控制進出伺服器的流量。安全群組就像是一個防火牆,可以根據設定的規則允許或拒絕特定的流量。

設定安全群組的步驟

  1. 允許來自特定IP的SSH流量,以便進行除錯或維護。
  2. 設定安全群組的出站規則,以允許所有出站流量。

使用Auto Scaling Group動態調整Jenkins工作節點

為了能夠動態調整Jenkins工作節點的數量,我們可以使用AWS Auto Scaling Group(ASG)。ASG可以根據設定的條件自動新增或移除工作節點,以滿足建置工作的需求。

ASG的工作原理

  1. 建立一個ASG,並設定最小和最大工作節點數量。
  2. 設定擴充套件政策(Scaling Policy),以根據特定的指標(如CPU使用率)調整工作節點的數量。
  3. 使用Amazon CloudWatch監控ASG中的工作節點,並根據設定的閾值觸發擴充套件或縮減事件。

使用CloudWatch監控和觸發擴充套件事件

Amazon CloudWatch可以用於監控Jenkins工作節點的CPU使用率,並根據設定的閾值觸發擴充套件或縮減事件。

設定CloudWatch報警

  1. 建立一個CloudWatch報警,以監控ASG中工作節點的平均CPU使用率。
  2. 設定報警的閾值,以觸發擴充套件或縮減事件。

自定義指標和Lambda函式

除了使用CPU使用率作為指標外,我們還可以使用自定義指標(如建置佇列中的工作數量)來觸發擴充套件事件。

使用Prometheus和Lambda函式

  1. 使用Prometheus從Jenkins叢集中匯出指標。
  2. 建立一個Lambda函式,以消費這些指標並觸發擴充套件事件。
圖表翻譯:Jenkins叢集動態擴充套件架構

此圖示展示了Jenkins叢集如何根據CPU使用率動態調整工作節點的數量。透過使用Auto Scaling Group和CloudWatch,Jenkins叢集可以自動新增或移除工作節點,以滿足建置工作的需求。

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333

title 使用Prometheus和Lambda函式

rectangle "管理" as node1
rectangle "註冊" as node2
rectangle "監控" as node3
rectangle "觸發" as node4
rectangle "新增/移除" as node5

node1 --> node2
node2 --> node3
node3 --> node4
node4 --> node5

@enduml

圖表翻譯: 此圖示呈現了Jenkins叢集的動態擴充套件架構,透過Auto Scaling Group和CloudWatch實作工作節點的自動調整。

import boto3

# 建立Auto Scaling Group
asg = boto3.client('autoscaling')
asg.create_auto_scaling_group(
    AutoScalingGroupName='jenkins-workers',
    LaunchConfigurationName='jenkins-worker-launch-config',
    MinSize=1,
    MaxSize=10
)

# 設定擴充套件政策
asg.put_scaling_policy(
    AutoScalingGroupName='jenkins-workers',
    PolicyName='scale-out-policy',
    PolicyType='SimpleScaling',
    AdjustmentType='ChangeInCapacity',
    ScalingAdjustment=1
)

# 建立CloudWatch報警
cloudwatch = boto3.client('cloudwatch')
cloudwatch.put_metric_alarm(
    AlarmName='cpu-utilization-alarm',
    ComparisonOperator='GreaterThanThreshold',
    EvaluationPeriods=1,
    MetricName='CPUUtilization',
    Namespace='AWS/EC2',
    Period=300,
    Statistic='Average',
    Threshold=80,
    ActionsEnabled=True,
    AlarmActions=['arn:aws:autoscaling:REGION:ACCOUNT_ID:scalingPolicy:POLICY_ID:autoScalingGroupName/jenkins-workers']
)

內容解密:

上述程式碼展示瞭如何使用Boto3函式庫建立Auto Scaling Group、設定擴充套件政策以及建立CloudWatch報警。首先,我們建立了一個名為jenkins-workers的Auto Scaling Group,並指定了啟動組態和最小/最大容量。接著,我們設定了一個名為scale-out-policy的擴充套件政策,當觸發時會增加一個工作節點。最後,我們建立了一個名為cpu-utilization-alarm的CloudWatch報警,當平均CPU使用率超過80%時會觸發擴充套件事件。這些程式碼片段共同實作了Jenkins叢集的動態擴充套件功能。