在 GCP 環境中佈署 Jenkins 時,安全性與高用性至關重要。本文將引導你設定堡壘機,作為連線私有 Jenkins Master 的安全通道。同時,我們會利用 GCP 的負載平衡服務,將流量分發到健康的 Jenkins Master,確保服務持續執行。此外,為了最佳化資源使用,我們將使用案例項群組和自動擴充套件政策,根據負載動態調整 Jenkins Worker 的數量,提升建置效率並降低成本。最後,我們將使用 Terraform 進行基礎設施程式碼的管理,實作自動化佈署和管理。
在Google Cloud Platform上佈署高用性Jenkins
建立堡壘主機(Bastion Host)以存取私有Jenkins例項
為了能夠SSH到私有的Jenkins例項,我們將佈署一個堡壘主機。首先,建立bastion.tf檔案並定義一個虛擬機器例項,該例項位於公有子網路中,並具有靜態IPv4公有IP地址。
resource "google_compute_address" "static" {
name = "ipv4-address"
}
resource "google_compute_instance" "bastion" {
project = var.project
name = "bastion"
machine_type = var.bastion_machine_type
zone = var.zone
tags = ["bastion"]
boot_disk {
initialize_params {
image = var.machine_image
}
}
network_interface {
subnetwork = google_compute_subnetwork.public_subnets[0].self_link
access_config {
nat_ip = google_compute_address.static.address
}
}
metadata = {
ssh-keys = "${var.ssh_user}:${file(var.ssh_public_key)}"
}
}
內容解密:
google_compute_address資源用於建立一個靜態IPv4地址。google_compute_instance資源定義了一個名為"bastion"的虛擬機器例項。metadata屬性用於上傳公鑰,以便能夠使用SSH連線到堡壘主機。
設定防火牆規則以允許SSH連線
在同一個檔案中,建立一個防火牆規則以允許從任何地方SSH到堡壘主機。
resource "google_compute_firewall" "allow_ssl_to_bastion" {
project = var.project
name = "allow-ssl-to-bastion"
network = google_compute_network.management.self_link
allow {
protocol = "tcp"
ports = ["22"]
}
source_ranges = ["0.0.0.0/0"]
source_tags = ["bastion"]
}
內容解密:
google_compute_firewall資源定義了一個防火牆規則。- 此規則允許從任何IP地址(
0.0.0.0/0)透過TCP協定的22埠(SSH)存取堡壘主機。
輸出堡壘主機的公有IP地址
建立一個outputs.tf檔案,並使用Terraform的輸出變數來輸出堡壘虛擬機器的公有IP地址。
output "bastion" {
value = "${google_compute_instance.bastion.network_interface.0.access_config.0.nat_ip}"
}
內容解密:
output用於輸出堡壘主機的公有IP地址。
在Google Compute Engine上佈署Jenkins
現在,我們將在私有子網路中佈署一個根據Jenkins master映像的虛擬機器例項,並暴露一個公有負載平衡器來存取Jenkins的Web儀錶板。
建立一個jenkins_master.tf檔案,並定義一個私有的計算例項。
resource "google_compute_instance" "jenkins_master" {
project = var.project
name = "jenkins-master"
machine_type = var.jenkins_master_machine_type
zone = var.zone
tags = ["jenkins-ssh", "jenkins-web"]
depends_on = [google_compute_instance.bastion]
boot_disk {
initialize_params {
image = var.jenkins_master_machine_image
}
}
network_interface {
subnetwork = google_compute_subnetwork.private_subnets[0].self_link
}
metadata = {
ssh-keys = "${var.ssh_user}:${file(var.ssh_public_key)}"
}
}
內容解密:
google_compute_instance資源定義了一個名為"jenkins-master"的虛擬機器例項。- 此例項位於私有子網路中。
設定防火牆規則以允許存取Jenkins
定義防火牆規則以允許從堡壘主機SSH到Jenkins主機,並允許從任何地方存取Jenkins的Web介面。
resource "google_compute_firewall" "allow_ssh_to_jenkins" {
project = var.project
name = "allow-ssh-to-jenkins"
network = google_compute_network.management.self_link
allow {
protocol = "tcp"
ports = ["22"]
}
source_tags = ["bastion", "jenkins-ssh"]
}
resource "google_compute_firewall" "allow_access_to_ui" {
project = var.project
name = "allow-access-to-jenkins-web"
network = google_compute_network.management.self_link
allow {
protocol = "tcp"
ports = ["8080"]
}
source_ranges = ["0.0.0.0/0"]
source_tags = ["jenkins-web"]
}
內容解密:
- 第一個防火牆規則允許從堡壘主機SSH到Jenkins主機。
- 第二個防火牆規則允許從任何地方存取Jenkins的Web介面(埠8080)。
建立負載平衡器
首先,定義一個目標池資源,該資源定義了應該接收傳入流量的例項。
resource "google_compute_target_pool" "jenkins-master-target-pool" {
name = "jenkins-master-target-pool"
session_affinity = "NONE"
region = var.region
instances = [
google_compute_instance.jenkins_master.self_link
]
health_checks = [
google_compute_http_health_check.jenkins_master_health_check.name
]
}
內容解密:
google_compute_target_pool資源定義了一個目標池。- 此目標池包含Jenkins主機例項,並與健康檢查相關聯。
在多雲端提供者上佈署高用性 Jenkins
使用 Google Cloud Platform 佈署 Jenkins
設定負載平衡器
要確保 Jenkins 主節點的高用性,需要設定一個對外公開的負載平衡器。這個負載平衡器會將流量轉發到 Jenkins 主節點,只有當主節點運作正常並準備好接收流量時才會進行轉發。因此,需要定義一個健康檢查資源,以特定的頻率向 Jenkins 主節點的 8080 埠傳送健康檢查請求。
resource "google_compute_http_health_check" "jenkins_master_health_check" {
name = "jenkins-master-health-check"
request_path = "/"
port = "8080"
timeout_sec = 4
check_interval_sec = 5
}
設定轉發規則
接下來,定義一個轉發規則,將流量導向之前定義的目標池。
resource "google_compute_forwarding_rule" "jenkins_master_forwarding_rule" {
name = "jenkins-master-forwarding-rule"
region = var.region
load_balancing_scheme = "EXTERNAL"
target = google_compute_target_pool.jenkins-master-target-pool.self_link
port_range = "8080"
ip_protocol = "TCP"
}
輸出負載平衡器的 IP 位址
為了顯示負載平衡器的 IP 位址,在 outputs.tf 檔案中建立一個輸出區段:
output "jenkins" {
value = google_compute_forwarding_rule.jenkins_master_forwarding_rule.ip_address
}
執行 terraform output 命令,即可在控制檯上顯示 Jenkins 負載平衡器的 IP 位址。
#### 內容解密:
此段落程式碼定義了一個對外公開的負載平衡器,並設定了健康檢查和轉發規則,以確保 Jenkins 主節點的高用性。透過 terraform apply 命令佈署後,可以在瀏覽器中輸入負載平衡器的 IP 位址和埠號(8080)來存取 Jenkins 的歡迎畫面。
在 GCP 上啟動自動管理的 Jenkins 工作節點
Jenkins 的強大功能之一是能夠將建置作業分配到多個工作節點上。為了避免在工作節點閒置時支付額外的資源費用,將在例項群組中佈署 Jenkins 工作節點,並設定自動擴充套件政策,以根據 CPU 使用率等指標觸發擴充套件或縮減事件。
建立 Jenkins 工作節點範本
首先,建立一個 jenkins_workers.tf 檔案,並定義用於建立 Jenkins 工作節點組態的例項範本。
resource "google_compute_instance_template" "jenkins-worker-template" {
name_prefix = "jenkins-worker"
description = "Jenkins workers instances template"
region = var.region
tags = ["jenkins-worker"]
machine_type = var.jenkins_worker_machine_type
metadata_startup_script = data.template_file.jenkins_worker_startup_script.rendered
disk {
source_image = var.jenkins_worker_machine_image
disk_size_gb = 50
}
network_interface {
network = google_compute_network.management.self_link
subnetwork = google_compute_subnetwork.private_subnets[0].self_link
}
metadata = {
ssh-keys = "${var.ssh_user}:${file(var.ssh_public_key)}"
}
}
#### 內容解密:
此段落程式碼定義了一個例項範本,用於建立 Jenkins 工作節點。範本中指定了機器型別、啟動指令碼、磁碟來源映像和網路介面等組態。啟動指令碼會在虛擬機器首次啟動時執行,使其自動加入 Jenkins 群集。
設定防火牆規則以允許 SSH 連線
定義一個防火牆規則,以允許從 Jenkins 主節點和堡壘主機到 Jenkins 工作節點的 SSH 連線。
resource "google_compute_firewall" "allow_ssh_to_worker" {
project = var.project
name = "allow-ssh-to-worker"
network = google_compute_network.management.self_link
}
#### 內容解密:
此防火牆規則允許從指定的來源到 Jenkins 工作節點的 SSH 連線,確保可以遠端管理這些工作節點。
圖表翻譯:
此圖示呈現了在 Google Cloud Platform 上佈署 Jenkins 群集的架構。首先,設定了一個對外公開的負載平衡器,以確保 Jenkins 主節點的高用性。然後,建立了一個例項範本,用於建立 Jenkins 工作節點,並設定了自動擴充套件政策,以根據 CPU 使用率等指標動態調整工作節點的數量。最後,定義了防火牆規則,以允許必要的網路連線。透過這些步驟,可以在 GCP 上成功佈署一個高用性的 Jenkins 環境。
在多雲供應商上佈署高用性 Jenkins
6.2 Microsoft Azure
Microsoft Azure 和 AWS 類別似,提供多種雲端服務。然而,使用 Microsoft 軟體的組織通常具有企業協定,可獲得軟體折扣。這些組織在使用 Azure 時通常可以獲得顯著的優惠。
6.2.1 在 Azure 中建立黃金 Jenkins 虛擬機器映像
在建置過程中,Packer 會建立臨時的 Azure 資源。因此,它需要被授權與 Azure API 互動。
建立 Azure 服務主體(SP)
建立具有建立和管理資源許可權的 Azure 服務主體(SP)。SP 代表存取 Azure 資源的應用程式。它由客戶端 ID(即應用程式 ID)識別,可以使用密碼或憑證進行身份驗證。
$sp = New-AzADServicePrincipal -DisplayName "PackerServicePrincipal"
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($sp.Secret)
$plainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
New-AzRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName $sp.ApplicationId
內容解密:
此段 PowerShell 指令碼用於建立 Azure 服務主體。首先,建立一個名為 “PackerServicePrincipal” 的服務主體,然後將其密碼轉換為純文字格式,最後為該服務主體分配「Contributor」角色,以便其能夠建立和管理 Azure 資源。
執行以下命令輸出密碼和應用程式 ID:
$plainPassword
$sp.ApplicationId
儲存應用程式 ID 和密碼以供稍後使用。
建立 Jenkins Worker 映像
要建立 Jenkins Worker 映像,請建立一個 template.json 檔案。在該範本中,您定義了執行實際建置過程的建置器和提供者。Packer 有一個名為 azure-arm 的 Azure 建置器,允許您定義 Azure 映像。
{
"variables": {
"subscription_id": "YOUR SUBSCRIPTION ID",
"client_id": "YOUR CLIENT ID",
"client_secret": "YOUR CLIENT SECRET",
"tenant_id": "YOUR TENANT ID",
"resource_group": "RESOURCE GROUP NAME",
"location": "LOCATION NAME"
},
"builders": [
{
"type": "azure-arm",
<!-- 其他設定 -->
}
]
}
內容解密:
此 JSON 範本檔案定義了 Packer 建置器的變數和設定。其中,variables 部分定義了 Azure 的訂閱 ID、客戶端 ID、客戶端密碼、租戶 ID、資源群組名稱和位置名稱。builders 部分定義了使用 azure-arm 建置器來建立 Azure 映像。您需要將 YOUR SUBSCRIPTION ID、YOUR CLIENT ID、YOUR CLIENT SECRET、YOUR TENANT ID、RESOURCE GROUP NAME 和 LOCATION NAME 替換為您的實際 Azure 資訊。
圖表翻譯:
此圖表展示了在 Azure 中建立 Jenkins Worker 映像的流程。首先,建立 Azure 服務主體,然後使用 Packer 的 azure-arm 建置器建立映像。
Azure 中建立 Jenkins Worker 映像流程圖
@startuml
skinparam backgroundColor #FEFEFE
title GCP高用性Jenkins佈署實踐
|開發者|
start
:提交程式碼;
:推送到 Git;
|CI 系統|
:觸發建置;
:執行單元測試;
:程式碼品質檢查;
if (測試通過?) then (是)
:建置容器映像;
:推送到 Registry;
else (否)
:通知開發者;
stop
endif
|CD 系統|
:部署到測試環境;
:執行整合測試;
if (驗證通過?) then (是)
:部署到生產環境;
:健康檢查;
:完成部署;
else (否)
:回滾變更;
endif
stop
@enduml
此圖表清晰地展示了在 Azure 中建立 Jenkins Worker 映像所需的步驟,包括建立服務主體、定義 template.json 檔案和使用 Packer 建立映像。