使用 Zabbix 監控 Jenkins
筆者最近的工作涉及到使用 Zabbix 監控 Jenkins。在谷歌上搜索到的文章非常少,能操作的就更少了。所以決定寫一篇文章介紹如何使用 Zabbix 監控 Jenkins。
下圖為整體架構圖:
整體並不復雜,大體步驟如下:
- 在 Jenkins 上安裝 Metrics 插件,使 Jenkins 暴露 metrics api。
- 配置 Zabbix server 及 agent 以實現監控及告警
為方便讀者實驗,筆者將自己做實驗的代碼上傳到了 GitHub,鏈接在文章末尾。使用的是 Docker Compose 技術(方便一次性啟動所有的系統)。
接下來,我們詳細介紹 Metrics插件及如何實現 Zabbix 監控 Jenkins。
1. 使 Jenkins 暴露 metrics api
安裝 Metrics 插件,在系統配置中,會多出“Metrics”的配置,如下圖:
配置項不復雜。我們需要點擊“Generate...”生成一個 Access Key(生成後,記得要保存)。這個 Key 用於身份校驗,後面我們會用到。
保存後,我們在瀏覽器中輸入URL:http://localhost:8080/metrics/<剛生成的 Access Key>
驗證 Jenkins 是否已經暴露 metrics。如果看到如下圖,就說明可以進行下一步了。
1.1 Metrics 插件介紹
Metrics 插件是基於 dropwizard/metrics 實現。它通過4個接口暴露指標數據:/metrics,/ping,/threads,/healthcheck。
1.2 Metrics 插件:/metrics 接口介紹
點擊上圖中的metric
鏈接(http://localhost:8080/metrics/<Access Key>/metrics
),它暴露了以下指標數據:
{
version: "3.0.0",
gauges: {...},
counters: {...},
histograms: {...},
meters: {...},
timers: {...}
}
從數據結構中可以看出它將指標分成 5 種數據類型:
- Gauges:某項指標的瞬時值,例如:當前 Jenkins executor 的總個數(jenkins.executor.count.value)
- Counters:某項指標的總數值,例如:http 請求活動連接數(http.activeRequests)
- Meters:一段時間內,某事件的發生概率,例如:Jenkins成功執行的任務每分鐘的執行次數(jenkins.runs.success.m1_rate)
- Histogram:統計指標的分布情況。例如:Jenkins executor 數量的分布(jenkins.executor.count.history)
- Timer:某項指標的持續時間。例如:Jenkins 任務等待時間(jenkins.job.waiting.duration)
由於指標非常之多,我們就不分別介紹了。具體有哪些指標,讀者朋友可以從代碼倉庫中的 metrics.json 文件了解。
1.2 Metrics 插件其它接口介紹
-
/ping:接口返回
pong
代表 Jenkins 存活,如下圖: -
/threads:返回 Jenkins 的線程信息
-
/healthcheck:返回以下指標:
{ disk-space: { healthy: true }, plugins: { healthy: true, message: "No failed plugins" }, temporary-space: { healthy: true }, thread-deadlock: { healthy: true } }
2. 配置 Zabbix server 與 agent 實現監控及告警
Zabbix server 通過與 Zabbix agent 進行通信實現數據的采集。而 Zabbix agent 又分為被動和主動兩種模式。我們使用的是被動模式,也就是Zabbix server 向 agent 索要數據。
所以,我們需要在 Zabbix agent 所在機器放一個獲取 Jenkins 指標數據的腳本。再配置 Zabbix server 定時從該 agent 獲取數據,最後配置觸發器(trigger)實現告警。
接下來的關於 Zabbix 的配置,基於我的 jenkins-zabbix 實驗環境,讀者朋友需要根據自己的實際情況變更。
2.1 配置 Zabbix server 如何從 agent 獲取指標數據
首先,我們需要告訴 Zabbix server 要與哪些 Zabbix agent 通信。所以,第一步是創建主機,如下圖:
第二步,在主機列表中點擊“Iterms”進行該主機的監控項設置:
第三步,進入創建監控項頁面:
第四步,創建監控項:
這裏需要解釋其中幾個選項為什麽要那樣填:
- Type:是 Zabbix server 采集指標的類型,我們選擇的是 Zabbix agent,如上文所說。
- Key:由於我們要監控的指標並不是 Zabbix 預定義的。所以,需要使用用戶自定義參數來實現監控 Jenkins 指標。Key 填的值為:jenkins.metrics[gauges.jenkins.node.count.value.value]。
jenkins.metrics
是需要執行的真正的 Key 名稱。而[]
內是傳給該 Key 對應的命令的參數。對於初學者,Zabbix 這部分概念非常不好理解。也許這樣會更好理解:在使用用戶自定義參數來實現監控的情況下,Zabbix server 會將這個 Key 發送給 agent,然後 agent 根據這個 Key 執行指定的 邏輯 以獲取指標數據。這個 邏輯 通常是一段腳本(shell命令或Python腳本等)。而腳本也是可以傳參的,[]
中的值就是傳給腳本的參數。具體更多細節,下文會繼續介紹。 - Type of information:監控數據的數據類型,由於我們監控的是 Jenkins node 節點的個數,所以,使用數字整型。
- Update interval:指 Zabbix server 多長時間向 agent 獲取一次數據,為方便實驗,我們設置為 2s。
到此,Zabbix server 端已經配置完成。
2.2 配置 Zabbix agent 使其有能力從 Jenkins 獲取指標數據
當 Zabbix agent 接收到 server 端的請求,如 jenkins.www.yigouyule2.cn metrics[gauges.jenkins.node.count.value.value]
。Zabbix agent 會讀取自己的配置(agent 啟動時會配置),配置內容如下:
## Zabbix Agent Configuration File for Jenkins Master
UserParameter=jenkins.metrics[*], python /usr/lib/zabbix/externalscripts/jenkins.metrics.py $1
根據 Key 名稱(jenkins.metrics)找到相應的命令,即:python /usr/lib/zabbix/externalscripts/jenkins.metrics.py $1
。並執行它,同時將參數 gauges.jenkins.node.count.value.value
傳入到腳本 jenkins.metrics.py 中。jenkins.metrics.py 需要我們在 Jenkins agent 啟動前放到 /usr/lib/zabbix/externalscripts/ 目錄下。
jenkins.metrics.py 的源碼在 jenkins-zabbix 實驗環境中可以找到,篇幅有限,這裏就簡單介紹一下其中的邏輯。
jenkins.metrics.py 所做的事情,無非就是從 Jenkins master 的 metrics api 獲取指標數據。但是由於 api 返回的是 JSON 結構,並不是 Zabbix server 所需要的格式。所以,jenkins.metrics.py 還做了一件事情,就是將 JSON 數據進行扁平化,比如原來的數據為:{"gauges":{"jenkins.node.count.value": { "value": 1 }}}
扁平化後變成: gauges.jenkins.node.count.value.value=1
。
如果 jenkins.metrics.py 腳本沒有接收參數的執行,它將一次性返回所有的指標如:
......
histograms.vm.memory.pools.Metaspace.used.window.15m.stddev=0.0
histograms.vm.file.descriptor.ratio.x100.window.5m.p75=0.0
histograms.vm.memory.pools.PS-www.muming157.com Old-Gen.used.window.5m.count=4165
gauges.vm.runnable.count.value=10
timers.jenkins.task.waiting.duration.mean=www.ysyl157.com 0.0
histograms.vm.memory.www.dasheng178.com non-heap.committed.history.p99=123797504.0
gauges.vm.memory.pools.PS-Eden-Space.used.value=19010928
gauges.jenkins.node.count.value.value=1
histograms.vm.memory.pools.Code-Cache.used.window.15m.mean=44375961.6
......
但是,如果接收到具體參數,如 gauges.jenkins.node.count.value.value
,腳本只返回該參數的值。本例中,它將只返回 1
。
jenkins.metrics.py 腳本之所以對 JSON 數據進行扁平化,是因為 Zabbix server 一次只拿一個指標的值(這點需要向熟悉 Zabbix 的人求證,筆者從文檔中沒有找到明確的說明)。
註意:在 2.1 節中,如果 Key 值設置為:jenkins.metrics,Zabbix server 不會拿 jenkins.metrics.py 返回的所有的指標值自動創建對應的監控項。所以,Key 值必須設置為類似於 jenkins.metrics[gauges.jenkins.node.count.value.value] 這樣的值。
3. 配置 Zabbix server 監控指標,並告警
在經過 2.2 節的配置後,如果 Zabbix server 采集到數據,可通過_Monitoring -> Latest data -> Graph_菜單(如下圖),看到圖形化的報表:
圖形化的報表:
有了指標數據就可以根據它進行告警了。告警在 Zabbix 中稱為觸發器(trigger)。如下圖,我們創建了一個當 Jenkins node 小於 2 時,就觸發告警的觸發器:
至於最終觸發器的後續行為是發郵件,還是發短信,屬於細節部分,讀者朋友可根據自己的情況進行設置。
小結
在理解了 Zabbix server 與 agent 之間的通信原理的前提下,使用 Zabbix 監控 Jenkins 是不難的。筆者認為難點在於自動化整個過程。上文中,我們創建主機和添加監控項的過程,是手工操作的。雖然 Zabbix 能通過自動發現主機,自動關聯模板來自動化上述過程,但是創建”自動化發現主機“和”自動關聯動作“依然是手工操作。這不符合”自動化一切“的”追求“。
最後,如果讀者朋友不是歷史包袱原因而選擇 Zabbix,筆者在這裏推薦 Prometheus,一款《Google 運維解密》推薦的開源監控系統。
使用 Zabbix 監控 Jenkins