在現代 CI/CD 流程中,有效管理和分析 Jenkins 日誌至關重要。ELK 堆積疊提供了一個強大的解決方案,能集中收集、處理和視覺化 Jenkins 產生的海量日誌資料。透過 Filebeat 收集日誌,Logstash 解析和轉換資料,最後 Elasticsearch 儲存和 Kibana 呈現,開發團隊可以更輕鬆地監控建置狀態、追蹤錯誤,並深入分析系統效能。此外,搭配 Logstash 外掛程式,更能簡化日誌串流程,並結合 Grafana 和 Slack 的警示機制,在系統異常時即時通知相關人員,確保 CI/CD 管道的穩定執行。
使用ELK實作Jenkins日誌的集中式管理
在持續整合和持續交付(CI/CD)的實踐中,日誌的管理和分析是至關重要的。Jenkins作為一個流行的自動化伺服器,產生了大量的日誌資料,這些資料對於除錯、監控和最佳化構建流程具有重要意義。本文將介紹如何使用ELK(Elasticsearch、Logstash、Kibana)堆積疊來集中管理和分析Jenkins日誌。
ELK堆積疊的佈署
首先,我們需要佈署ELK堆積疊。可以使用Packer來建立Elasticsearch、Logstash和Kibana的AMI(Amazon Machine Images),然後在AWS上啟動相應的EC2例項。
ELK堆積疊佈署架構
圖表翻譯: 此圖示展示了ELK堆積疊的佈署架構,其中Jenkins的日誌被傳送到Logstash進行處理,然後儲存在Elasticsearch中,最終透過Kibana進行視覺化展示。
在Jenkins伺服器上安裝Filebeat
為了收集Jenkins的日誌,我們需要在Jenkins伺服器上安裝Filebeat。Filebeat是一個輕量級的日誌傳送工具,可以將日誌資料傳送到Logstash或Elasticsearch。
curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.13.2-x86_64.rpm
sudo rpm -vi filebeat-7.13.2-x86_64.rpm
安裝完成後,需要組態Filebeat以收集Jenkins的日誌。編輯/etc/filebeat/filebeat.yml檔案,新增以下組態:
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/jenkins/jenkins.log
fields:
type: jenkins
multiline.pattern: '[0-9]{4}-[0-9]{2}-[0-9]{2}'
multiline.negate: true
multiline.match: after
output.logstash:
hosts: ["LOGSTASH_HOST"]
內容解密:
filebeat.inputs:定義了Filebeat的輸入源,這裡組態為從/var/log/jenkins/jenkins.log檔案中讀取日誌。fields:增加了一個名為type的欄位,值為jenkins,用於標識這些日誌來自Jenkins。multiline:組態了多行日誌的處理規則,這裡根據日期模式來識別新的日誌事件。output.logstash:將收集到的日誌傳送到指定的Logstash主機。
組態Logstash解析Jenkins日誌
在Logstash中,我們可以使用Grok過濾器來解析Jenkins日誌,將其結構化為可查詢的欄位。
filter {
if [type] == "jenkins" {
grok {
patterns_dir => ["/etc/logstash/patterns"]
match => {
"message" => "%{TIMESTAMP_ISO8601:createdAt}%{SPACE}\[id=%{INT:buildId}\]%{SPACE}%{LOGLEVEL:level}%{SPACE}%{JAVACLASS:class}%{DATA:state}:%{SPACE}%{JOBNAME:project}#%{NUMBER:buildNumber} %{DATA:execution}: %{WORD:status}"
}
}
}
}
內容解密:
filter:定義了Logstash的過濾器,這裡根據type欄位的值來決定是否應用Grok過濾器。grok:使用了Grok模式來解析Jenkins日誌,將日誌中的不同部分提取到不同的欄位中。patterns_dir:指定了自定義Grok模式的目錄。match:定義了用於匹配日誌訊息的Grok模式。
在Kibana中視覺化Jenkins日誌
最後,我們可以在Kibana中建立索引模式,並使用Discover頁面來瀏覽和分析Jenkins日誌。
Kibana中Jenkins日誌的視覺化
圖表翻譯: 此圖示展示了Kibana如何查詢Elasticsearch中的資料,並將結果以視覺化的方式呈現給使用者。
透過上述步驟,我們成功地使用ELK堆積疊實作了Jenkins日誌的集中式管理和分析。這不僅提高了日誌的可讀性和可查詢性,也為進一步的日誌分析和監控奠定了基礎。
使用ELK堆積疊進行Jenkins日誌的集中式紀錄
在持續交付的過程中,收集和分析Jenkins日誌是至關重要的。ELK堆積疊(Elasticsearch、Logstash、Kibana)提供了一個強大的解決方案來實作Jenkins日誌的集中式紀錄和分析。
組態Filebeat和Logstash
首先,我們需要組態Filebeat將Jenkins日誌轉發到Logstash進行解析,然後將解析後的資料寫入Elasticsearch伺服器。每個來自Jenkins的日誌訊息都會匹配並產生如表13.1所示的欄位。
表13.1 Elasticsearch中的Jenkins索引欄位
| 欄位名稱 | 描述 |
|---|---|
| time | 訊息的日期和時間(UTC格式) |
| level | 日誌訊息級別(INFO、WARNING、DEBUG、FATAL、ERROR) |
| project | Jenkins作業的建置名稱 |
| buildNumber | 作業的建置編號,標識Jenkins執行此建置流程的次數 |
| status | 建置的狀態(FAILURE或SUCCESS) |
| execution | 建置的當前狀態(執行中、待處理、終止或完成) |
你可以根據status欄位建立一個堆積疊柱狀圖,顯示一段時間內失敗與成功的建置數量,如圖13.26所示。
圖13.26 根據Jenkins結構化欄位建立互動式小工具
你可以將柱狀圖儲存為小工具並匯入儀錶板。透過儀錶板,你可以將多個視覺化元件組合到單一頁面上,並透過提供搜尋查詢或點選視覺化元件中的元素來篩選它們,如圖13.27所示。
圖13.27 從Kibana儀錶板分析Jenkins日誌
完整的儀錶板可以從JSON檔案(chapter13/kibana/dashboard/jenkins.json)匯入。
使用Logstash外掛程式串流日誌
你也可以直接透過Jenkins上的Logstash外掛程式將Jenkins日誌傳送到Elasticsearch例項,而無需組態Filebeat和Logstash。這種方法非常適合尚未使用外部Logstash代理將基礎設施或應用程式日誌串流到Elasticsearch的情況。
組態Logstash外掛程式
安裝Logstash外掛程式後,需要在Jenkins的全域性組態中組態外掛程式,指定Elasticsearch伺服器的URI,如圖13.28所示。
圖13.28 組態Logstash外掛程式以將日誌串流到Elasticsearch伺服器
在組態Logstash外掛程式後,可以在管道中新增以下區塊,將日誌資料串流到Elasticsearch:
logstash {
echo "Job:${env.JOB_NAME}"
}
你可以透過存取Kibana儀錶板檢視串流的日誌,如圖13.29所示。
圖13.29 傳送到Elasticsearch的日誌訊息範例
根據指標建立警示
我們可以進一步利用日誌和監控解決方案來設定警示。DevOps團隊可以透過警示通知事件,例如當失敗建置率明顯高於平常時。使用Kibana定義有意義的警示,如圖13.30所示。
圖13.30 在Kibana上組態警示
你也可以使用Grafana警示功能根據Prometheus或Telegraf收集的指標建立警示。
組態Slack通知頻道
首先,需要新增通知頻道。在Grafana中,懸停在警示圖示上,然後點選通知頻道,如圖13.32所示。建立Slack通知頻道需要輸入頻道名稱、選擇型別為Slack並輸入建立的Webhook URL。
圖13.32 組態新的Slack通知頻道
Slack Webhook URL建立流程圖
圖表翻譯: 此圖示展示了建立Slack Webhook URL的步驟,包括建立Slack應用程式、啟用Incoming Webhook功能、新增新的Webhook到工作區、選擇Slack頻道並授權應用程式,最後取得Webhook URL並在Grafana中建立Slack通知頻道。
#### 內容解密:
此Plantuml圖展示了建立Slack Webhook URL的完整流程。首先,開發者需要前往Slack API頁面建立一個新的應用程式。接著,啟用Incoming Webhook功能,這允許外部服務向Slack頻道傳送訊息。然後,點選“Add New Webhook to Workspace”按鈕,將Webhook新增到指定的工作區。在這個過程中,需要選擇一個Slack頻道並授權應用程式存取該頻道。完成這些步驟後,會獲得一個Webhook URL,這個URL將用於在Grafana中組態Slack通知頻道,從而實作警示通知功能。
Jenkins 警示設定與安全管理最佳實踐
在前一章中,我們探討瞭如何監控 Jenkins 叢集、設定警示以及關聯 Jenkins 日誌和指標以識別問題並避免停機。本章將探討如何透過設定細粒度存取許可權來強化 Jenkins 的安全性,並介紹一些維護 Jenkins 例項的最佳實踐。
建立根據指標的警示
在 Grafana 中建立警示規則是一個重要的步驟,可以在系統出現異常時及時通知團隊。首先,選擇要建立警示的面板,例如記憶體使用率指標。接著,點選「Alert」標籤並選擇「Create Alert」,開啟設定警示的表單。
設定評估間隔與條件
在設定警示時,需要指定評估間隔(Evaluate Every)和條件(Conditions)。例如,將評估間隔設為每 1 分鐘評估一次,如果指標違反規則,Grafana 將等待 1 分鐘後再觸發警示。使用 avg() 函式來驗證平均記憶體使用率是否超過 90%。
### 警示規則範例
- 評估間隔:每 1 分鐘
- 條件:平均記憶體使用率 > 90%
新增通知通路與訊息
設定警示規則時,還需要指定通知通路和訊息內容。當警示被觸發時,相關訊息將被傳送到指定的 Slack 頻道,確保團隊成員能夠及時收到通知。
#### Slack 通知範例
@here 注意:記憶體使用率已超過 90%!
Jenkins 安全管理與 RBAC 設定
Jenkins 的預設組態允許未登入的使用者具有讀取許可權,而登入的使用者幾乎可以存取所有內容。為了覆寫此預設行為,需要進入「Manage Jenkins」的「Configure Global Security」部分。
停用匿名讀取許可權與啟用使用者註冊
停用「Allow Anonymous Read Access」並啟用「Allow Users to Sign Up」,這樣使用者可以自行建立帳戶。
### 安全設定步驟
1. 停用匿名讀取許可權
2. 啟用使用者註冊功能
使用 Matrix 授權策略
為了實作對登入使用者的細粒度存取控制,可以安裝 Jenkins Matrix Authorization Strategy 外掛。此外掛允許對每個專案中的作業許可權進行精細控制。
#### Matrix 授權策略設定
1. 安裝 Matrix Authorization Strategy 外掛
2. 在「Configure Global Security」中啟用「Project-Based Matrix Authorization Strategy」
Jenkins 管理與最佳實踐:安全與角色存取控制
Jenkins 是一個強大的自動化工具,用於持續整合和持續佈署(CI/CD)。在企業環境中,安全管理是至關重要的。本章將探討 Jenkins 的安全管理,包括使用者管理、許可權控制以及如何與 GitHub OAuth 整合。
矩陣式安全組態
Jenkins 提供了一個矩陣式安全組態,允許管理員為不同使用者分配不同的許可權。這些許可權分為幾個類別,包括整體系統許可權、憑證管理、代理節點管理、作業管理、執行管理和檢視管理等。
許可權分類別
- 整體(Overall):涵蓋基本的系統級許可權。
- 憑證(Credentials):涵蓋 Jenkins 憑證的管理。
- 代理(Agent):涵蓋與建置節點或工作節點相關的許可權。
- 作業(Job):涵蓋與作業相關的許可權,如建立、更新或刪除作業。
- 執行(Run):涵蓋與特定建置歷史相關的許可權。
- 檢視(View):涵蓋檢視的管理,允許將作業和內容組織成不同的標籤頁。
- SCM:涵蓋與版本控制系統(如 Git 或 SVN)相關的許可權。
設定使用者許可權
- 在 Jenkins 的「設定全域安全性」頁面中,啟用矩陣式安全組態。
- 新增使用者或群組,並為他們分配相應的許可權。
- 例如,可以為管理員分配所有許可權,而為開發者分配讀取作業的許可權。
角色基礎存取控制(RBAC)
在大型組織中,為多個使用者分配細粒度許可權可能非常繁瑣。角色基礎存取控制(RBAC)提供了一個更有效的方式來管理許可權。
安裝 Role-Based Authorization Strategy 外掛
- 從外掛管理器安裝 Role-Based Authorization Strategy 外掛。
- 在「設定全域安全性」頁面中啟用 Role-Based Strategy。
定義和管理角色
- 在「管理 Jenkins」頁面中,選擇「Manage and Assign Roles」。
- 定義自訂角色,如 Admin、Developer 和 QA,並為他們分配相應的許可權。
- 將這些角色分配給特定的使用者。
使用 GitHub OAuth 組態 Jenkins
Jenkins 支援多種驗證外掛,包括 GitHub OAuth。這允許使用 GitHub 帳戶進行身份驗證和管理許可權。
組態步驟
- 安裝 GitHub Authentication 外掛。
- 在 GitHub 上建立一個新的 OAuth 應用程式,並取得 Client ID 和 Client Secret。
- 在 Jenkins 的「設定全域安全性」頁面中,設定 GitHub Authentication Plugin,並輸入 Client ID 和 Client Secret。
- 使用 GitHub 帳戶登入 Jenkins,並組態相應的許可權。
圖表說明
圖表翻譯: 此圖示展示瞭如何在 Jenkins 中使用 GitHub OAuth 進行身份驗證的流程。首先,在 Jenkins 中安裝 GitHub Authentication 外掛。然後,在 GitHub 上建立一個新的 OAuth 應用程式,以取得 Client ID 和 Client Secret。接著,在 Jenkins 中組態 GitHub Authentication Plugin,並輸入 Client ID 和 Client Secret。最後,使用 GitHub 帳戶登入 Jenkins,並組態相應的許可權。
使用分享函式庫擴充套件 Jenkins
在前面的章節中,我們學習瞭如何為多個應用程式編寫 CI/CD 管道。在實作這些管道步驟時,我們呼叫了多個自定義函式。這些函式在多個 Jenkinsfile 中重複出現。
為什麼需要分享函式庫?
為了避免在不同的管道中複製和貼上相同的程式碼,並減少冗餘,我們可以在 Jenkins 中將公共程式碼集中在分享函式庫中。這樣,我們就可以在所有管道中參照相同的程式碼。
建立分享函式庫
分享函式庫是一組獨立的 Groovy 指令碼,儲存在 Git 儲存函式庫中。這意味著您可以對其進行版本控制、標記,並執行所有您習慣的 Git 操作。
在儲存函式庫中,建立一個 vars 資料夾,並為每個函式編寫一個 Groovy 指令碼。例如,建立一個名為 commitAuthor.groovy 的檔案,並定義一個名為 call 的函式。該函式的主體將在呼叫 commitAuthor 指令時執行。
#!/usr/bin/env groovy
def call() {
sh 'git show -s --pretty=%an > .git/commitAuthor'
def commitAuthor = readFile('.git/commitAuthor').trim()
sh 'rm .git/commitAuthor'
commitAuthor
}
內容解密:
#!/usr/bin/env groovy:指定使用 Groovy 執行該指令碼。def call():定義一個名為call的函式,這是分享函式庫函式的入口點。sh 'git show -s --pretty=%an > .git/commitAuthor':執行 Git 命令以取得提交作者,並將結果輸出到.git/commitAuthor檔案中。def commitAuthor = readFile('.git/commitAuthor').trim():讀取.git/commitAuthor檔案中的內容,並去除空白字元。sh 'rm .git/commitAuthor':刪除.git/commitAuthor檔案。commitAuthor:傳回提交作者的名稱。
組態 Jenkins 使用分享函式庫
建立分享函式庫後,需要告訴 Jenkins 如何使用它。進入作業組態,在「Pipeline Libraries」下新增一個函式庫,設定如下:
- 名稱:用於在管道指令碼中參照的簡短識別符號。
- 預設版本:可以是任何 Git 能夠理解的版本,例如分支、標籤或提交 ID 雜湊。
@startuml
skinparam backgroundColor #FEFEFE
title ELK集中式管理Jenkins日誌
|開發者|
start
:提交程式碼;
:推送到 Git;
|CI 系統|
:觸發建置;
:執行單元測試;
:程式碼品質檢查;
if (測試通過?) then (是)
:建置容器映像;
:推送到 Registry;
else (否)
:通知開發者;
stop
endif
|CD 系統|
:部署到測試環境;
:執行整合測試;
if (驗證通過?) then (是)
:部署到生產環境;
:健康檢查;
:完成部署;
else (否)
:回滾變更;
endif
stop
@enduml圖表翻譯:
此圖示展示了 Jenkins 如何載入分享函式庫。Jenkins 從分享函式庫儲存函式庫載入分享函式庫,儲存函式庫中的 vars 資料夾包含了各種 Groovy 指令碼,例如 commitAuthor.groovy。
載入分享函式庫到管道
要在管道中載入分享函式庫,需要使用 @Library 註解在管道定義的頂部匯入它。然後透過其名稱呼叫目標函式。
@Library('shared-library') _
pipeline {
agent any
stages {
stage('Checkout') {
steps {
git 'https://github.com/user/repo.git'
echo "Commit Author: ${commitAuthor()}"
}
}
}
}
內容解密:
@Library('shared-library') _:匯入名為shared-library的分享函式庫。pipeline { ... }:定義一個 Jenkins 管道。stage('Checkout') { ... }:定義一個名為「Checkout」的階段。git 'https://github.com/user/repo.git':從指定的 Git 儲存函式庫簽出程式碼。echo "Commit Author: ${commitAuthor()}":呼叫commitAuthor()函式並輸出提交作者的名稱。