返回文章列表

Jenkins Pipeline 微服務程式碼定義

本文闡述如何以程式碼定義微服務的 Jenkins Pipeline,涵蓋 Jenkins Job 的 XML 設定、使用 RESTful API 和 CLI 建立 Job、SSH 金鑰驗證、GitHub Webhook 觸發自動建置,以及 AWS Lambda 與 API Gateway 的整合應用。

DevOps CI/CD

透過程式碼定義 Jenkins Pipeline,可以有效提升微服務的自動化建置與佈署效率。本文詳細介紹瞭如何使用 XML 設定檔定義 Jenkins Job,並透過 RESTful API 和 Jenkins CLI 建立 Job。同時也說明瞭如何使用 SSH 金鑰確保 Jenkins 與 GitHub 儲存函式庫之間的安全驗證,以及如何利用 GitHub Webhook 觸發 Jenkins 自動建置。此外,文章還涵蓋了 AWS Lambda 與 API Gateway 的整合應用,實作更彈性且可擴充套件的自動化流程。

以程式碼定義微服務的 Jenkins Pipeline

Jenkins Job 的 XML 設定檔結構

在 Jenkins 中,Job 的設定可以透過 XML 檔案來定義。為了建立一個新的 Job,我們需要建立一個 XML 設定檔,並使用適當的值更新 XML 標籤。

XML 標籤說明

XML 標籤描述
<description>對 Jenkins Job 的簡短描述
<displayName>Jenkins Job 的顯示名稱,通常使用儲存原始碼的儲存函式庫名稱
<repository>儲存原始碼的 GitHub 儲存函式庫名稱
<repositoryURL>GitHub 儲存函式庫的 HTTPS Clone URL

設定檔範例

以下是一個範例 XML 設定檔,用於建立一個名為 movies-store 的 Job:

<?xml version="1.0" encoding="UTF-8"?>
<org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject plugin="[email protected]">
  <actions />
  <description>Movies store RESTful API</description>
  <displayName>movies-store</displayName>
  <sources class="jenkins.branch.MultiBranchProject$BranchSourceList" plugin="[email protected]">
    <data>
      <jenkins.branch.BranchSource>
        <source class="org.jenkinsci.plugins.github_branch_source.GitHubSCMSource" plugin="[email protected]">
          <id>bf197dad-7d42-4a00-be25-7ae7ea7fef15</id>
          <apiUri>https://api.github.com</apiUri>
          <credentialsId>github</credentialsId>
          <repoOwner>mlabouardy</repoOwner>
          <repository>movies-store</repository>
          <repositoryUrl>https://github.com/mlabouardy/movies-store.git</repositoryUrl>
          <traits>
            <org.jenkinsci.plugins.github__branch__source.BranchDiscoveryTrait>
              <strategyId>1</strategyId>
            </org.jenkinsci.plugins.github__branch__source.BranchDiscoveryTrait>
          </traits>
        </source>
      </jenkins.branch.BranchSource>
    </data>
  </sources>
</org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject>

建立 Jenkins Job

要建立 Jenkins Job,我們需要將 XML 設定檔傳送到 Jenkins 的 RESTful API。可以使用 Postman 或 cURL 命令來完成此操作。

curl -s https:///<USER>:<API_TOKEN>@JENKINS_HOST/job/JOBNAME/config.xml | 
curl -X POST 'https:///<USER>:<API_TOKEN>@JENKINS_HOST/createItem?name=JOBNAME' 
--header "Content-Type: application/xml" -d @-

API Token 的產生

要使用 Jenkins 的 RESTful API,我們需要產生一個 API Token。可以按照以下步驟產生 API Token:

  1. 登入 Jenkins Dashboard。
  2. 開啟使用者設定頁面。
  3. 點選「Add new Token」按鈕。
  4. 輸入 Token 名稱並點選「Generate」按鈕。

使用 Jenkins CLI 建立 Job

除了使用 RESTful API 外,我們也可以使用 Jenkins CLI 建立 Job。以下是使用 Jenkins CLI 建立 Job 的範例命令:

java -jar jenkins-cli.jar -s JENKINS_URL -auth USERNAME:PASSWORD create-job movies-marketplace < config.xml

使用存取 Token 認證

我們也可以使用存取 Token 認證代替使用者名稱和密碼。以下是使用存取 Token 認證的範例命令:

java -jar jenkins-cli.jar -s JENKINS_URL -auth USERNAME:TOKEN create-job movies-marketplace < config.xml
本章重點整理:
  • 使用 XML 設定檔定義 Jenkins Job。
  • 使用 RESTful API 或 Jenkins CLI 建立 Job。
  • 產生 API Token 和使用存取 Token 認證。

在未來,我們可以進一步探索如何使用 Jenkins 自動化微服務的佈署和測試。同時,我們也可以學習如何使用其他工具和技術來增強 Jenkins 的功能和效率。

圖表翻譯:

此圖示展示瞭如何使用 Postman 建立一個新的 Jenkins Job。

圖表翻譯: 圖中呈現了使用 Postman 向 Jenkins 的 RESTful API 傳送請求,以建立一個新的 Job 的過程。其中包括了設定 HTTP 請求的方法、URL、Header 和 Body 等資訊。透過此圖表,我們可以清晰地瞭解如何使用 Postman 與 Jenkins 的 RESTful API 進行互動。

程式碼解密:

curl -s https:///<USER>:<API_TOKEN>@JENKINS_HOST/job/JOBNAME/config.xml | 
curl -X POST 'https:///<USER>:<API_TOKEN>@JENKINS_HOST/createItem?name=JOBNAME' 
--header "Content-Type: application/xml" -d @-

程式碼解密:

這段程式碼是用於建立一個新的 Jenkins Job 的 cURL 命令。首先,它從指定的 URL 下載一個 XML 設定檔,然後將該檔案傳送到 Jenkins 的 RESTful API,以建立一個新的 Job。其中,<USER><API_TOKEN> 需要替換為實際的使用者名稱和 API Token,<JENKINS_HOST> 需要替換為實際的 Jenkins 主機地址,<JOBNAME> 需要替換為實際的 Job 名稱。

  1. curl -s:表示靜默模式,不顯示進度條。
  2. https:///<USER>:<API_TOKEN>@JENKINS_HOST/job/JOBNAME/config.xml:這是要下載的 XML 設定檔的 URL。
  3. curl -X POST:表示傳送一個 POST 請求到指定的 URL。
  4. 'https:///<USER>:<API_TOKEN>@JENKINS_HOST/createItem?name=JOBNAME':這是 Jenkins 的 RESTful API 的 URL,用於建立一個新的 Job。
  5. --header "Content-Type: application/xml":表示設定 HTTP 請求的 Header,指定內容型別為 XML。
  6. -d @-:表示將從標準輸入讀取的資料作為請求的 Body。

透過這段程式碼,我們可以實作自動化建立 Jenkins Job 的功能。

使用 SSH 金鑰與 Jenkins 進行驗證

在與專案儲存函式庫互動時,Jenkins 需要適當的驗證機制以確保安全。本文將介紹如何使用 SSH 金鑰來驗證 Jenkins 與 GitHub 儲存函式庫之間的連線。

生成 SSH 金鑰

首先,您需要為 Jenkins 生成一個專用的 SSH 金鑰。可以使用 ssh-keygen 命令來完成此操作。

在 GitHub 上組態 SSH 金鑰

  1. 登入您的 GitHub 帳戶並導航至儲存函式庫的設定頁面。
  2. 在「Deploy Keys」或使用者設定中新增 SSH 金鑰。
  3. 將公鑰(通常儲存在 id_rsa.pub 檔案中)的內容貼上並儲存。

驗證 SSH 金鑰組態

在 Jenkins 的 SSH 工作階段中執行以下命令,以驗證金鑰是否正確組態:

ssh -T -ai PRIVATE_KEY_PATH [email protected]

如果回應顯示「Hi username」,則表示金鑰已成功組態。

在 Jenkins 中組態 SSH 憑證

  1. 導航至 Jenkins 控制檯的「Credentials」頁面。
  2. 點選「Global」並選擇「Add Credentials」。
  3. 選擇「SSH Username with Private Key」型別。
  4. 輸入金鑰名稱、私鑰內容以及 GitHub 帳戶的使用者名稱。

程式碼示例:Jenkinsfile 中的 SSH 組態

stage('Checkout') {
    steps {
        git branch: 'develop',
            credentialsId: 'github-ssh',
            url: '[email protected]:mlabouardy/movies-loader.git'
    }
}

內容解密:

此段程式碼定義了一個名為「Checkout」的階段,用於從 GitHub 儲存函式庫中簽出程式碼。其中:

  • branch: 指定要簽出的分支名稱。
  • credentialsId: 指定用於驗證的 SSH 憑證 ID。
  • url: 指定 GitHub 儲存函式庫的 SSH 克隆 URL。

使用 GitHub Webhook 觸發 Jenkins 建置

為了實作自動化建置,可以在 GitHub 儲存函式庫中設定 Webhook,以便在發生 push 事件時通知 Jenkins。

  1. 導航至 GitHub 儲存函式庫的設定頁面。
  2. 點選「Webhooks」並新增一個新的 Webhook。
  3. 設定 Payload URL 為 JENKINS_URL/github-webhook/,並選擇觸發事件為「push」。

Webhook 工作流程

圖表翻譯: 此圖表展示了當 GitHub 發生 push 事件時,如何透過 Webhook 觸發 Jenkins 建置的流程。首先,GitHub 傳送 push 事件通知給 Jenkins 的 Webhook,然後 Webhook 觸發相應的 Jenkins 建置任務。

使用 GitHub Webhook 觸發 Jenkins 自動建置

在現代化的軟體開發流程中,持續整合(CI)與持續佈署(CD)扮演著至關重要的角色。透過將 GitHub 與 Jenkins 結合,我們可以實作自動化的建置流程,大幅提升開發效率與程式碼品質。本篇文章將探討如何利用 GitHub Webhook 觸發 Jenkins 自動建置,並使用 AWS Lambda 與 API Gateway 作為中介服務。

架構設計與實作

1. 建立 AWS Lambda 函式轉發 GitHub Webhook 請求

首先,我們需要建立一個 AWS Lambda 函式,用於接收來自 GitHub 的 Webhook 請求並將其轉發至 Jenkins 伺服器。該 Lambda 函式使用 Node.js 編寫,如下所示:

const Request = require('request');

exports.handler = (event, context, callback) => {
    Request.post({
        url: process.env.JENKINS_URL,
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "X-GitHub-Event": event.headers["X-GitHub-Event"]
        },
        json: JSON.parse(event.body)
    }, (error, response, body) => {
        callback(null, {
            "statusCode": 200,
            "headers": {
                "content-type": "application/json"
            },
            "body": "success",
            "isBase64Encoded": false
        });
    });
};

內容解密:

此段程式碼定義了一個 AWS Lambda 函式的處理程式。它使用 Request 模組向指定的 Jenkins URL 傳送 POST 請求,將 GitHub Webhook 請求的內容轉發給 Jenkins。其中:

  • process.env.JENKINS_URL 是環境變數,用於指定 Jenkins 伺服器的 URL。
  • 請求頭部包含 Content-TypeX-GitHub-Event,確保 Jenkins 正確解析請求。
  • 請求成功後,傳回一個 HTTP 200 回應給 API Gateway。

2. 使用 Terraform 佈署 AWS 資源

接下來,我們使用 Terraform 來佈署所需的 AWS 資源,包括 Lambda 函式、API Gateway 以及相關的 IAM 角色。

首先,建立一個 lambda.tf 檔案,定義 Lambda 函式資源:

resource "aws_lambda_function" "lambda" {
    filename         = "../deployment.zip"
    function_name    = "GitHubWebhookForwarder"
    role             = aws_iam_role.role.arn
    handler          = "index.handler"
    runtime          = "nodejs14.x"
    timeout          = 10
    environment {
        variables = {
            JENKINS_URL = var.jenkins_url
        }
    }
}

內容解密:

此段 Terraform 程式碼定義了一個名為 GitHubWebhookForwarder 的 Lambda 函式。它使用了:

  • deployment.zip 檔案,其中包含 Lambda 函式的程式碼。
  • index.handler 作為處理程式的入口點。
  • Node.js 14.x 作為執行環境。
  • 環境變數 JENKINS_URL,其值來自變數 var.jenkins_url

然後,建立一個 apigateway.tf 檔案,定義 API Gateway RESTful API:

resource "aws_api_gateway_rest_api" "api" {
    name        = "GitHubWebHookAPI"
    description = "GitHub Webhook forwarder"
}

resource "aws_api_gateway_resource" "path" {
    rest_api_id = aws_api_gateway_rest_api.api.id
    parent_id   = aws_api_gateway_rest_api.api.root_resource_id
    path_part   = "webhook"
}

resource "aws_api_gateway_integration" "request_integration" {
    rest_api_id = aws_api_gateway_rest_api.api.id
    resource_id = aws_api_gateway_method.request_method.resource_id
    http_method = aws_api_gateway_method.request_method.http_method
    type        = "AWS_PROXY"
    uri         = aws_lambda_function.lambda.invoke_arn
    integration_http_method = "POST"
}

內容解密:

此段程式碼定義了一個 API Gateway RESTful API,用於接收 GitHub 的 Webhook 請求並觸發 Lambda 函式。其中:

  • aws_api_gateway_rest_api 資源定義了 API 的基本屬性。
  • aws_api_gateway_resource 資源定義了 API 的資源路徑 /webhook
  • aws_api_gateway_integration 資源將 API Gateway 與 Lambda 函式整合,當接收到 POST 請求時觸發 Lambda 函式。

最後,建立一個 variables.tf 檔案,定義所需的變數:

variable "region" {
    type        = string
    description = "The AWS region in which to deploy AWS resources."
}

variable "jenkins_url" {
    type        = string
    description = "The Jenkins URL."
}

內容解密:

此段程式碼定義了兩個變數:regionjenkins_url,分別用於指定 AWS 佈署區域與 Jenkins 伺服器的 URL。

圖表說明

@startuml
skinparam backgroundColor #FEFEFE

title Jenkins Pipeline 微服務程式碼定義

|開發者|
start
:提交程式碼;
:推送到 Git;

|CI 系統|
:觸發建置;
:執行單元測試;
:程式碼品質檢查;

if (測試通過?) then (是)
    :建置容器映像;
    :推送到 Registry;
else (否)
    :通知開發者;
    stop
endif

|CD 系統|
:部署到測試環境;
:執行整合測試;

if (驗證通過?) then (是)
    :部署到生產環境;
    :健康檢查;
    :完成部署;
else (否)
    :回滾變更;
endif

stop

@enduml

圖表翻譯: 此圖表展示了從 GitHub 傳送 Webhook 請求到 Jenkins 自動建置的流程。首先,GitHub 傳送 Webhook 請求到 API Gateway,接著 API Gateway 觸發 Lambda 函式,最後 Lambda 函式將請求轉發給 Jenkins 以啟動自動化建置流程。