返回文章列表

AWS Jenkins 擴充套件架構佈署實踐

本文探討如何在 AWS 上建構可擴充套件的 Jenkins 架構,涵蓋 VPC、子網、堡壘機、負載平衡器等關鍵元件的設定,並結合 Packer 烘焙機器映像,實作自動化佈署和組態。文章提供詳細的步驟說明、程式碼範例和圖表,引導讀者逐步建構安全、高效且可擴充套件的 Jenkins 叢集。

DevOps 雲端架構

在 AWS 上佈署 Jenkins 叢集,需要考量 VPC 網路設定、堡壘機存取、負載平衡以及自動擴充套件等導向。首先,我們會在 VPC 內建立私有子網放置 Jenkins 主節點和工作節點,並透過堡壘機確保安全存取。為了提高 Jenkins 服務的可用性,我們會使用負載平衡器分流流量,並設定自動擴充套件群組,根據構建負載動態調整工作節點數量。此外,我們將使用 Packer 烘焙機器映像,預先安裝和組態 Jenkins 相關套件,以提升佈署效率和一致性。最後,我們會探討如何使用 CloudFormation 等工具自動化基礎設施的佈署和管理,簡化維運流程。

建構 Jenkins 在 AWS 上的擴充套件架構

虛擬私有雲(VPC)的設定與安全強化

為了確保 Jenkins 叢集的安全性,我們將其佈署在虛擬私有雲(VPC)內的私有子網中。預設情況下,AWS 上的 EC2 例項會被佈署在預設 VPC 中,但為了滿足特定的安全需求,我們將建立一個非預設的 VPC,並指定特定的無類別域間路由(CIDR)區塊範圍和子網大小。

VPC 的優勢與設定

Amazon VPC 允許使用者在 AWS 雲端中建立一個邏輯上隔離的部分,使用者可以在這裡啟動 AWS 資源,並定義自己的虛擬網路環境。這包括選擇自己的 IP 位址範圍、建立子網,以及組態路由表和網路閘道。

需要注意的是,VPC 仍然是 AWS 雲的一部分,它不是一個物理上獨立的託管環境,而是 EC2 基礎設施中邏輯上隔離的一部分。這種隔離是在網路層面上實作的,與傳統資料中心的網路隔離類別似。

網路拓撲與子網設定

圖 3.14 展示了 AWS VPC 的網路拓撲結構。我們將在不同的可用區域中建立多個子網,以提高架構的彈性。每個子網代表了一個有效的 IP 位址範圍。

網際網路連線與 NAT 設定

為了讓 Jenkins 例項能夠存取網際網路,我們需要設定一個網際網路閘道(IGW),並將其附加到 VPC 上。IGW 主要用於為 Jenkins 例項提供網際網路連線,這對於需要從網際網路下載外部套件的構建任務來說是必要的。同時,IGW 也負責將例項的私有 IP 位址對映到相關的公有或彈性 IP 位址,並將流量路由到網際網路。

對於私有子網中的例項,我們需要使用網路位址轉換(NAT)閘道或例項來轉發輸出流量,同時阻止來自網際網路的輸入流量。這樣,例項就可以在不暴露於公眾的情況下存取網際網路。

路由表的組態

我們需要為公有子網和私有子網分別建立路由表,並設定相應的規則,以確保流量能夠正確地路由到 IGW 或 NAT 閘道。表 3.1 和表 3.2 分別展示了公有路由表和私有路由表的組態。

堡壘主機與安全存取

由於 Jenkins 例項被佈署在與網際網路隔離的私有子網中,我們無法直接從本地桌面透過 SSH 連線到這些例項。因此,我們需要佈署一個特殊的例項,稱為堡壘主機或跳板機,作為代理來存取 Jenkins 例項。這個堡壘主機會被佈署在公有子網中,並透過建立安全的 SSH 通道來路由來自本地網路的 SSH 流量到 Jenkins 例項。

OpenVPN 的替代方案

另一種更進階的解決方案是佈署 OpenVPN,以建立安全的 TLS VPN 連線來存取私有 Jenkins 例項。有關如何設定 OpenVPN,請參閱相關檔案。

Jenkins 叢集的佈署架構

一旦 VPC 組態完成,我們就可以佈署一個專用的 EC2 例項來執行 Jenkins 伺服器,並將其放置在私有子網中。同時,我們還會在多個私有子網中佈署一個 Jenkins 工作節點的自動擴充套件群組(ASG)。透過組態擴充套件策略和 CloudWatch 警示,我們可以根據構建活動動態地擴充套件 Jenkins 工作節點。

圖 3.15 總結了目前的佈署架構。

負載平衡器的組態

為了進一步增強架構,我們可以在 Jenkins 例項前面組態一個導向公眾的彈性負載平衡器,以存取 Jenkins 網頁儀錶板。這樣,您的 Jenkins 例項就不必直接暴露在網際網路上。

負載平衡器將監聽 HTTP(80)和 HTTPS(443)埠,並將傳入的請求轉發到例項上的 8080 埠。這樣,可以使用加密連線與 Jenkins 例項進行通訊。表 3.3 總結了負載平衡器的監聽器組態。

如果指定 HTTPS 監聽器,則需要選擇一個私有的 SSL 證書。負載平衡器使用該證書終止連線,然後在將請求傳送到 Jenkins 例項之前解密來自客戶端的請求。

多 Jenkins 例項的可能性

雖然 Jenkins 核心預設不支援多個主節點,但仍然可以透過使用負載平衡器來分配請求給多個 Jenkins 主節點,從而實作多個 Jenkins 例項的高用性。

程式碼範例與詳細說明

# 定義 VPC 與子網的 CloudFormation 範本範例
Resources:
  MyVPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: '10.0.0.0/16'

  PublicSubnet:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: '10.0.1.0/24'
      AvailabilityZone: 'us-west-2a'

  PrivateSubnet:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: '10.0.2.0/24'
      AvailabilityZone: 'us-west-2b'

  InternetGateway:
    Type: 'AWS::EC2::InternetGateway'

  VPCGatewayAttachment:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref MyVPC

#### 程式碼解密:
此 CloudFormation 範本定義了一個 VPC、兩個子網(公有和私有)、一個網際網路閘道,並將閘道附加到 VPC 上。VPC 的 CIDR 區塊被設定為 `10.0.0.0/16`,公有子網和私有子網分別位於不同的可用區域。這樣的設定為後續的資源佈署奠定了基礎。

### 圖表翻譯:VPC 網路拓撲圖
**圖表翻譯:**
此圖示展示了 AWS VPC 的基本網路拓撲結構,包括公有子網、私有子網、網際網路閘道和 NAT 閘道的組態。這種組態確保了資源的安全性和彈性,同時提供了對外連線的能力。

## 在AWS上擴充套件Jenkins的架構設計
在AWS上建立可擴充套件的Jenkins架構,需要考量多個層面,包括負載平衡、主從架構、以及儲存解決方案。本章將詳細介紹如何在AWS上設計和實作Jenkins叢集。

### 使用負載平衡器提升可用性
為了確保Jenkins服務的高用性,可以使用AWS Elastic Load Balancer(ELB)。ELB可以將流量分配到多個Jenkins例項,從而提高整體效能和可用性。

#### 負載平衡器的組態
1. **建立SSL/TLS憑證**:可以使用AWS Certificate Manager(ACM)取得免費的SSL憑證,也可以匯入自己的憑證。
2. **設定負載平衡器**:ELB具有公開可解析的DNS名稱,可以將來自客戶端的請求路由到註冊的Jenkins例項。
3. **自定義DNS名稱**:如果需要使用友好的DNS名稱存取負載平衡器,可以在Amazon Route 53上進行DNS組態。

### Jenkins叢集架構
Jenkins叢集的典型擴充套件方式是新增工作節點。然而,也可以設定多個Jenkins主節點,並使用代理(如HAProxy或NGINX)來監控主節點並在主節點故障時重新路由請求。

#### 高用性Jenkins主節點架構
1. **反向代理**:第一層是反向代理,負責接收傳入的請求並將其路由到適當的Jenkins主節點。
2. **Amazon Elastic File System(EFS)**:第二層是EFS,用於持久化Jenkins的主目錄($JENKINS_HOME),確保兩個Jenkins主節點可以存取和儲存Jenkins作業。

### 準備AWS環境
在開始安裝和組態Jenkins之前,需要準備AWS環境,包括安裝和組態AWS CLI。

#### 組態AWS CLI
1. **安裝AWS CLI**:根據官方檔案,在您的作業系統上安裝AWS CLI。
2. **將AWS CLI二進位制路徑新增到PATH環境變數**:確保可以在任何目錄下執行AWS CLI命令。
3. **驗證安裝**:執行`aws --version`命令驗證AWS CLI是否正確安裝。

### 圖表翻譯:
此圖示展示了Jenkins叢集佈署在自定義VPC上的架構圖,包括負載平衡器、Jenkins主節點和EFS。

#### 內容解密:
- 負載平衡器負責分配傳入的流量到多個Jenkins例項。
- Jenkins主節點可以設定為高用性架構,使用反向代理和EFS來確保服務的連續性。

```bash
# 安裝AWS CLI的範例命令
aws --version
aws s3 ls --region eu-central-1

內容解密:

  • aws --version命令用於驗證AWS CLI的版本。
  • aws s3 ls --region eu-central-1命令用於列出指定區域(本例中為eu-central-1)的S3儲存桶。

在AWS上架構Jenkins

3.3 使用AWS CLI設定AWS環境

在使用AWS CLI時,通常需要提供AWS憑證以驗證與AWS服務的連線。您可以透過多種方式組態AWS憑證:

  • 環境憑證:使用AWS_ACCESS_KEY_IDAWS_SECRET_KEY環境變數。這些變數對於指令碼編寫或臨時設定預設的命名profile非常有用。

    • 注意:如果您在終端機提示符下設定環境變數,則這些值僅在當前會話期間有效。要使環境變數設定在所有終端機會話中保持不變,請將它們儲存在/etc/profile或當前使用者的~/.bash_profile中。
  • 分享憑證檔案:AWS CLI將憑證儲存在您主目錄下.aws資料夾中的名為credentials的本地檔案中。您可以透過設定AWS_SHARED_CREDENTIALS_FILE環境變數來指定非預設位置的憑證檔案。

  • IAM角色:如果您在EC2例項中使用CLI,這將消除在生產環境中管理憑證檔案的需要。每個Amazon EC2例項都包含後設資料,AWS CLI可以直接查詢這些後設資料以取得臨時憑證。

3.3.3 建立和管理IAM使用者

IAM(https://aws.amazon.com/iam/)是一項允許您管理使用者、群組及其對AWS服務的存取級別的服務。強烈建議不要使用AWS根帳戶執行除帳單任務以外的任何任務,因為它具有建立和刪除IAM使用者、更改帳單、關閉帳戶以及在您的AWS帳戶上執行所有其他操作的最終許可權。因此,我們將建立一個新的IAM使用者,並根據最小許可權原則授予其存取正確AWS資源所需的許可權。

  • **最小許可權原則(PoLP)**的工作原理是隻給予特定使用者執行所需任務所需的最低存取級別或許可權。

要建立新的IAM使用者,請登入AWS管理控制檯,然後開啟IAM控制檯。從導航窗格中,選擇“使用者”,然後點選“新增使用者”按鈕。為使用者設定名稱,並選擇“程式設計存取”(如果您希望同一使用者具有對控制檯的存取許可權,也請選擇“AWS管理控制檯存取許可權”)。

設定許可權

在“設定許可權”部分,將AmazonS3FullAccess策略分配給使用者。

  • 注意:最好是細粒度地指定完成工作所需的許可權(最小許可權存取)。從最小許可權集開始,只有在必要時才新增更多許可權。

在最後一頁,您應該看到使用者的AWS憑證。請確保將存取金鑰儲存在安全的位置,因為您以後無法再看到它們。

組態AWS CLI

接下來,使用aws configure命令組態AWS CLI。CLI將把前面命令中指定的憑證儲存在~/.aws/credentials下的本地檔案中(或Windows上的%UserProfile%\.aws\credentials),內容如下(用您的AWS區域替換eu-central-1):

[default]
region=eu-central-1
aws_access_key_id=ACCESS KEY ID
aws_secret_access_key=SECRET ACCESS KEY
  • 注意:您可以使用AWS_DEFAULT_REGION環境變數或--region命令列選項來覆寫您的AWS資源所在的區域。

嘗試執行以下命令,如果您有S3儲存桶,您應該能夠看到列出的憑證。否則,該命令將不會傳回任何結果:

aws s3 ls

既然AWS環境已經設定好了,讓我們開始佈署Jenkins叢集在AWS上。

使用Packer烘焙機器映像

在上一章中,您瞭解了Jenkins分散式模式架構的工作原理。在本章中,我們將動手實踐,在AWS上佈署Jenkins叢集。作為一個快速提醒,您瞭解到Jenkins叢集分為兩個主要元件:主節點和工作節點。在深入實施分散式構建架構之前,我們將佈署單機模式,如圖4.1所示,以涵蓋一些基礎知識。

本章涵蓋內容

  • 不可變基礎架構概述
  • 使用Packer烘焙Jenkins機器映像
  • 發現Jenkins基本外掛
  • 執行Jenkins Groovy指令碼
  • 使用Packer provisioners自動化Jenkins設定

圖4.1 單機模式架構

要佈署此架構,我們需要組態一台伺服器(例如,AWS中的EC2例項)。然後,我們將在機器上安裝和組態Jenkins。雖然此手動過程有效,但當我們想要佈署Jenkins到多台機器時,它就變得不那麼高效了。下一章節將介紹如何使用Packer自動化此過程。

不可變基礎設施(Immutable Infrastructure)與 Packer 的應用

在現代雲端運算時代,許多企業正採用不可變基礎設施(Immutable Infrastructure)來簡化組態管理並提升可靠性。這種做法的核心是透過「基礎設施即程式碼」(Infrastructure as Code)來實作自動化佈署和管理。

不可變基礎設施的概念

不可變基礎設施強調的是在基礎設施建立後,不對現有的元件進行更新或修改,而是透過重新建立和替換來實作變更。這種做法可以減少錯誤發生的可能性,提高佈署過程的一致性和可靠性。

當需要更新不可變基礎設施時,新的伺服器會使用預先組態好的映像(Image)進行佈署,而舊的伺服器則會被銷毀。這種方式使得組態設定從伺服器建立過程轉移到構建過程中進行。透過這種方式,所有佈署都是根據新的映像進行,因此可以保留之前版本的歷史記錄,以便在需要時回復到舊版本。

不可變基礎設施的優點

  • 減少佈署時間:由於新伺服器是根據預先組態好的映像建立,因此可以快速佈署。
  • 降低組態失敗的風險:透過在構建過程中完成組態設定,可以減少因組態錯誤導致的佈署失敗。
  • 提高可擴充套件性:相同的映像可以用於建立多個例項,無需額外的組態。

使用 Packer 實作不可變基礎設施

HashiCorp Packer 是一款輕量級且易於使用的開源工具,用於自動化建立各種平台的機器映像。Packer 與組態管理工具(如 Ansible、Puppet 或 Chef)協同工作,在建立映像的過程中安裝和組態軟體及依賴項。

Packer 的工作流程

  1. 組態檔案的定義:使用組態檔案定義機器映像的建立過程。
  2. Builder 的使用:Packer 使用 Builder 在目標平台上啟動例項。
  3. Provisioners 的執行:執行 Provisioners 來組態應用程式或服務。
  4. 映像的建立:設定完成後,關閉例項並儲存新的機器映像。

Packer 的優勢

  • 快速基礎設施佈署:透過預先組態好的機器映像,可以快速啟動新例項。
  • 可擴充套件性:Packer 在映像建立過程中安裝和組態所有必要的軟體和依賴項,同一個映像可以用於啟動任意數量的例項。
  • 多提供者支援:Packer 可以用於建立多個雲端服務提供商(如 AWS、GCP 和 Microsoft Azure)的映像。

圖表說明:Packer 構建機器映像的流程

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title AWS Jenkins 擴充套件架構佈署實踐

package "Docker 架構" {
    actor "開發者" as dev

    package "Docker Engine" {
        component [Docker Daemon] as daemon
        component [Docker CLI] as cli
        component [REST API] as api
    }

    package "容器運行時" {
        component [containerd] as containerd
        component [runc] as runc
    }

    package "儲存" {
        database [Images] as images
        database [Volumes] as volumes
        database [Networks] as networks
    }

    cloud "Registry" as registry
}

dev --> cli : 命令操作
cli --> api : API 呼叫
api --> daemon : 處理請求
daemon --> containerd : 容器管理
containerd --> runc : 執行容器
daemon --> images : 映像檔管理
daemon --> registry : 拉取/推送
daemon --> volumes : 資料持久化
daemon --> networks : 網路配置

@enduml

圖表翻譯: 此圖示展示了 Packer 構建機器映像的工作流程,從定義組態檔案開始,到使用 Builder 啟動例項、執行 Provisioners 組態應用程式,最後儲存新的機器映像。

管理現有的映像

使用 Packer 的一個挑戰是管理現有的映像。使用者需要自行管理映像的版本或標籤,並定期刪除不再使用的舊映像,以避免額外的儲存成本。