參考網址:監控大挑戰 - 以 Zabbix 為例
為什麼選擇Zabbix?
目前常見的監控軟體有三者
- Zabbix
- Cacti
- Nagios
NagiOs的介面
Cacti的介面
Zabbix的介面
監控產品 | Zabbix | Nagios | Cacti |
---|
圖形介面 | 好看 | 不是特別好 | 還行 |
監控性能 | 併發監控,對CPU要求較高 | 併發監控,對CPU要求較高 | 輪詢監控,效能低 |
配置難度 | 較低,有圖形化介面使用 | 需使用CommandLine | 需使用CommandLine |
自動發現 | 支持 | 不支持 | 不支持 |
異常通知方式 | Email,簡訊,webhook,Line… | Email,簡訊,webhook,Line… | 較弱,預設只支援Email |
Zabbix是什麼
Zabbix是一種開源的網絡監視和警報系統,用於監視各種網絡設備,包括服務器、網絡設備和應用程序等。Zabbix提供了一個可擴展的架構,可用於監視多個位置的數千個設備。
Zabbix支持各種監視方式,包括SNMP、JMX、IPMI和VMware監視,還可以通過自定義監視腳本進行擴展。Zabbix還提供了一個強大的報警系統,可以通過電子郵件、SMS和其他方式發送警報,以便快速解決問題。
Zabbix還提供了一個用戶友好的Web界面,可以輕鬆設置監視器和警報。Zabbix的開源設計使其成為一個非常有用的監視解決方案,可以滿足各種規模的企業和組織的需求
Zabbix術語
Zabbix Server
- Zabbix server是agent程序報告系統可用性、系統完整性和統計數據的核心組件,是所有配置訊息、統計訊息和操作數據的核心儲存器
Zabbix資料庫存取
- 所有配置訊息和Zabbix收集到的數據都被儲存在資料庫中
Zabbix Web介面
- 為了從任何地方和任何平台都可以輕鬆地訪問Zabbix,我們提供基於Web的Zabbix介面,該介面是Zabbix Server的一部分,通常(但不一定)跟Zabbix Server運行在同一台物理主機上
Zabbix Proxy 代理服務器
- Zabbix Proxy可以替Zabbix Server收集性能和可用性數據。Proxy代理服務器是Zabbix軟體可選擇部屬的一部分,當然,Proxy代理服務器可以幫助單台Zabbix Server分擔負載壓力
Zabbix Agent 監控代理
- Zabbix agent 監控代理,部屬在監控目標上,能夠主動間空本地資源和應用程序,並將收集到的數據報告給Zabbix Server
Zabbix數據流
- 監控方面,為了創造一個監控項(item)用於採集數據,必須先創建一個主機(host)
- 告警方面,在監控項裡面創造觸發器(trigger),通過觸發器(trigger)來觸發告警動作(action)。因此如果你想收到Server XCPU負載過高的告警,必須滿足
- 為Server X創建一個Host並關聯一個用對CPU進行監控的監控項(item)
- 創建一個Trigger,設置成當CPU負載過高時會觸發
- Trigger被觸發,發送告警郵件
雖然看起來有很多步驟,但是使用模板的話操作起來其實非常簡單,Zabbix這樣的設計使得配置機制非常靈活易用
主機(Host)
主機組(host Group)
- 主機的邏輯組;包含了主機和模板。一個主機裡的主機和模板之間並沒有任何直接的關聯,通常在給不同用戶組的主機分配權限時,使用主機組
監控項(item)
觸發器(Trigger)
- 一個被用於定義問題閾值和"評估"監控項接受到的數據的邏輯表達式,當接收到的數據高於閾值時,觸發器從OK變成Problem狀態。當接收到的數據低於閾值時,觸發器保留/返回一個OK的狀態
事件(Event)
- 單次發生的需要注意的事情,例如觸發器狀態改變,或是發現有監控代理自動註冊
異常(Problem)
動作(Action)
- 一個對事件做出反應的預定義的操作
- 一個動作由操作(例如發出通知)和條件(當時操作正在發生)組成
升級(Escalation)
- 一個在動作內執行操作的自定義場景;發生通知/執行遠程命令的序列
媒介(Media)
通知(Notification)
遠程命令(remote command)
- 一個預定義好的,滿足一些條件的情況下,可以在被監控主機上自動執行的命令
模板(template)
- 一組可以被應用到一個或多個主機上的實體(監控項、觸發器、圖形、聚合圖形、應用、LLD、Web場景)的集合
- 模板的任務就是加快對主機監控任務的實施;也可以使監控任務的批量修改更簡單。模板是直接關連到每台單獨的主機上
應用(Application)
Web場景(Web Scenario)
前端(FrontEnd)
Zabbix API
- Zabbix API允許你使用JSON RPC協議(是一個無狀態且輕量級的遠程過程調用
Remote Procedure Call
傳送協議,其傳遞內容透過JSON為主)來創建、更新和獲取Zabbix對象(如主機、監控項、圖形和其他)信息或者執行任何其他的字定義的任務
Zabbix Server
- Zabbix軟件實現監控的核心程序,主要功能是與Zabbix proxies和Agents進行交互、觸發器計算、發送告警通知、並將資料集中保存
Zabbix Agent
- 一個部屬在監控對象上的,能夠主動監控本地資源和應用的程序
- Zabbix Agent部屬在監控的目標上,主動監測本地的資源和應用(硬體驅動、記憶體、處理器統計等等)
- Zabbix Agent收集本地的操作訊息並將資料報告給Zabbix Server用於進一步處理。一旦出現異常(比如硬碟空間已滿或者有崩潰的服務器Process),Zabbix Server會主動警告管理員指定機器上的異常。Zabbix Agents的極端高校源於他可以利用本地系統調用來完成統計數據的收集
被動(Passive) 和 主動(Active)檢查
- Zabbix Agent可以執行被動和主動兩種檢查方式
- 被動檢查(Passive Check)模式中Agent應答數據請求,Zabbix Server(或者Proxy)詢問Agent資料,如CPU負仔狀況,然後Zabbix Agent回傳結果
- 主動檢查(Active Checks) 處理過程將相對複雜。Agent必須首先從Zabbix server索取監控項列表以進行獨立處理,然後週期性的發送新的值給Server
執行被動或主動檢查是通過選擇相應的監測項目類型來配置的。Item Type. Zabbix Agent處理監控項類型有Zabbix agent和 Zabbix Agent(Active)
Zabbix Proxy
- 一個幫助Zabbix server收集數據,分擔Zabbix Server負擔的程式
- Zabbix Proxy是一個可以從一個或多個受監控設備收集監控數據,並將訊息結果發送到Zabbix Server的Process,基本上是代表Server工作的。所有收集的數據都在本地進行快取,然後傳送到Proxy所屬的Zabbix Server。
- 部屬Proxy是可選的,但是可能會非常有益於分散單個Zabbix Sever的負載,如果只有Proxy收集數據,Server上的進程就會減少,CPU消耗和磁碟I/O負載
- Zabbix Proxy是完成遠端區域,分支機構,沒有本地管理員的網路集中監控的理想解決方案
- Zabbix Proxy需要使用獨立的資料庫
使用Docker安裝 Zabbix
首先先點到下列網站
https://www.zabbix.com/documentation/5.0/en/manual/installation/containers
並在這邊選擇要使用的版本
這次是使用官網提供的,也就是用mysql當database的版本
並按照下列的cmd指令輸入,下面的參數,若有需要變可以在自行修改
1
| docker network create --subnet 172.20.0.0/16 --ip-range 172.20.240.0/20 zabbix-net
|
1
| docker run --name postgres-server -t -e POSTGRES_USER="zabbix" -e POSTGRES_PASSWORD="zabbix_pwd" -e POSTGRES_DB="zabbix" --network=zabbix-net --restart unless-stopped -d postgres:latest
|
1
| docker run --name zabbix-snmptraps -t -v /zbx_instance/snmptraps:/var/lib/zabbix/snmptraps:rw -v /var/lib/zabbix/mibs:/usr/share/snmp/mibs:ro --network=zabbix-net -p 162:1162/udp --restart unless-stopped -d zabbix/zabbix-snmptraps:alpine-5.0-latest
|
1
| docker run --name zabbix-server-pgsql -t -e DB_SERVER_HOST="postgres-server" -e POSTGRES_USER="zabbix" -e POSTGRES_PASSWORD="zabbix_pwd" -e POSTGRES_DB="zabbix" -e ZBX_ENABLE_SNMP_TRAPS="true" --network=zabbix-net -p 10051:10051 --volumes-from zabbix-snmptraps --restart unless-stopped -d zabbix/zabbix-server-pgsql:alpine-5.0-latest
|
1
| docker run --name zabbix-web-nginx-pgsql -t -e ZBX_SERVER_HOST="zabbix-server-pgsql" -e DB_SERVER_HOST="postgres-server" -e POSTGRES_USER="zabbix" -e POSTGRES_PASSWORD="zabbix_pwd" -e POSTGRES_DB="zabbix" --network=zabbix-net -p 443:8443 -p 80:8080 -v /etc/ssl/nginx:/etc/ssl/nginx:ro --restart unless-stopped -d zabbix/zabbix-web-nginx-pgsql:alpine-5.0-latest
|
透過termianl訪問Container中的資料庫,以psql為例
1
| docker exec -it [containerId] bash
|
1
| psql -U zabbix -h localhost zabbix
|
當全部都設置好後
訪問 http://localohst/ 即可訪問Zabbix頁面
帳號:Admin
密碼:zabbix
在Window下安裝 Zabbix Agent
這邊待補啦,不過先講一下Zabbix的Server端要怎麼對應
Host Name:要和當初設定Agent的Name一致
Group:Templates/Operating systems
Agent:當Agent的那一台主機的IP
Temlate:Template OS Windows by Zabbix agent
API的使用
可以到下列的網站使用線上的Zabbix API Test
https://sbcode.net/zabbix/zabbix-api-test-form/
url都是 http://localhost/api_jsonrpc.php,差別在於Body的內容
測試用API,用以返回版本號
1
2
3
4
5
6
7
| {
"jsonrpc": "2.0",
"method": "apiinfo.version",
"id": 1,
"auth": null,
"params": {}
}
|
返回的結果
1
2
3
4
5
| {
"jsonrpc": "2.0",
"result": "5.0.32",
"id": 1
}
|
登入用的API,用來取得Token
1
2
3
4
5
6
7
8
9
10
| {
"jsonrpc": "2.0",
"method": "user.login",
"params": {
"user": "Admin",
"password": "zabbix"
},
"id": 1,
"auth": null
}
|
返回的結果
1
2
3
4
5
| {
"jsonrpc": "2.0",
"result": "1a6022b1a01b787b2129d011763c73e6",
"id": 1
}
|
result就是Token值
返回目前存在的Agent
記得把Auth的值改成login返回的token
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| {
"jsonrpc": "2.0",
"method": "host.get",
"params": {
"output": [
"hostid",
"host"
],
"selectInterfaces": [
"interfaceid",
"ip"
]
},
"id": 2,
"auth": "1a6022b1a01b787b2129d011763c73e6"
}
|
返回的結果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
| {
"jsonrpc": "2.0",
"result": [
{
"hostid": "10084",
"host": "Zabbix server",
"interfaces": [
{
"interfaceid": "1",
"ip": "127.0.0.1"
}
]
},
{
"hostid": "10438",
"host": "Ian",
"interfaces": [
{
"interfaceid": "2",
"ip": "192.168.100.51"
}
]
},
{
"hostid": "10440",
"host": "Bill",
"interfaces": [
{
"interfaceid": "4",
"ip": "192.168.100.57"
}
]
},
{
"hostid": "10439",
"host": "Jess",
"interfaces": [
{
"interfaceid": "3",
"ip": "192.168.100.51"
}
]
}
],
"id": 2
}
|
Zabbix API介紹
https://sbcode.net/zabbix/zabbix-api-test-form/
在很多的API Parameter中,會常常看到
這段。這句話的意思是這樣的
output代表你想要返回的value值有什麼下面會有詳細的介紹
而extend則代表「請提供給我,更多的資訊」,詳細的差異如下
我們假設
host.get的返回值為下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
| {
"jsonrpc": "2.0",
"result": [
{
"hostid": "10084",
"proxy_hostid": "0",
"host": "Zabbix server",
"status": "0",
"disable_until": "1679972679",
"error": "Get value from agent failed: cannot connect to [[127.0.0.1]:10050]: [111] Connection refused",
"available": "2",
"errors_from": "1679019319",
"lastaccess": "0",
"ipmi_authtype": "-1",
"ipmi_privilege": "2",
"ipmi_username": "",
"ipmi_password": "",
"ipmi_disable_until": "0",
"ipmi_available": "0",
"snmp_disable_until": "0",
"snmp_available": "0",
"maintenanceid": "0",
"maintenance_status": "0",
"maintenance_type": "0",
"maintenance_from": "0",
"ipmi_errors_from": "0",
"snmp_errors_from": "0",
"ipmi_error": "",
"snmp_error": "",
"jmx_disable_until": "0",
"jmx_available": "0",
"jmx_errors_from": "0",
"jmx_error": "",
"name": "Zabbix server",
"flags": "0",
"templateid": "0",
"description": "",
"tls_connect": "1",
"tls_accept": "1",
"tls_issuer": "",
"tls_subject": "",
"tls_psk_identity": "",
"tls_psk": "",
"proxy_address": "",
"auto_compress": "1",
"inventory_mode": "-1"
}
],
"id": 2
}
|
但我們並不想要那麼多資訊,我們可能只想要其中幾項,比如說proxy_hostid,status而已,那我們就可以把我們Parameters的參數修改成這樣
1
| {"output": ["hostid","proxy_hostid"]}
|
回傳的結果就會變成這樣
使用Zabbix來取得CPU Utilization (in %)
- 先使用
host.get
來取得所有host資訊
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| {
"jsonrpc": "2.0",
"method": "host.get",
"params": {
"output": [
"hostid",
"host"
],
"selectInterfaces": [
"interfaceid",
"ip"
]
},
"id": 2,
"auth": "7cdc68d62750b0ed7ae693d1d7a52466"
}
|
返回的結果如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| {
"jsonrpc": "2.0",
"result": [
{
"hostid": "10084",
"host": "Zabbix server",
"interfaces": [
{
"interfaceid": "1",
"ip": "127.0.0.1"
}
]
},
{
"hostid": "10438",
"host": "Ian",
"interfaces": [
{
"interfaceid": "2",
"ip": "192.168.100.51"
}
]
},
{
"hostid": "10440",
"host": "Bill",
"interfaces": [
{
"interfaceid": "4",
"ip": "192.168.100.57"
}
]
}
],
"id": 2
}
|
- 透過item.get取得hostId的資料
假設我們現在要找到hostId=10440的資料,我們的API BODY要這樣送
1
2
3
4
5
6
7
8
9
10
11
12
| {
"jsonrpc": "2.0",
"method": "item.get",
"params": {
"output":["name","description","lastvalue"],
"filter":{
"hostid":"10440"
}
},
"id": 2,
"auth": "7cdc68d62750b0ed7ae693d1d7a52466"
}
|
其中 output的值代表,只顯示name,description,lastvalue這幾個key的資料,filter則代表我只要key-value為hostid:10440的資料
返回的結果很長,這邊講個大概就好
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| {
"jsonrpc": "2.0",
"result": [
{
"itemid": "37631",
"name": "Interface Intel(R) Ethernet Connection (14) I219-V(乙太網路): Outbound packets with errors",
"description": "The number of outgoing packets with errors on the network interface.",
"lastvalue": "0"
},
{
"itemid": "37632",
"name": "Interface Intel(R) Ethernet Connection (14) I219-V(乙太網路): Inbound packets discarded",
"description": "The number of incoming packets dropped on the network interface.",
"lastvalue": "0"
},
{
"itemid": "37633",
"name": "Interface Intel(R) Ethernet Connection (14) I219-V(乙太網路): Inbound packets with errors",
"description": "The number of incoming packets with errors on the network interface.",
"lastvalue": "0"
},
{
"itemid": "37634",
"name": "Interface Intel(R) Ethernet Connection (14) I219-V(乙太網路): Bits received",
"description": "Incoming traffic on the network interface.",
"lastvalue": "6431168"
}
...
//以下略..
}
|
- 找到CPU Utilization的資訊
搜尋關鍵字 CPU
這邊,那個lastValue其實就是最新的CPU使用率,這樣就成功取得CPU的使用率囉!
- 取得CPU Utilization的使用率
API Body如下
1
2
3
4
5
6
7
8
9
10
11
| {
"jsonrpc": "2.0",
"method": "history.get",
"params": {
"history": "0",
"itemids": "37631",
"output": "extend"
},
"auth": "7cdc68d62750b0ed7ae693d1d7a52466",
"id": 1
}
|
返回的結果如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| {
"jsonrpc": "2.0",
"result": [
{
"itemid": "37568",
"clock": "1679900528",
"value": "5.186729",
"ns": "297585693"
},
{
"itemid": "37568",
"clock": "1679900648",
"value": "6.917095",
"ns": "233421931"
}
// ... 略
]
}
|
使用Docker安裝,可能導致API路徑不正確
最近在學習zabbix時,安裝在Linux系統下時,透過Postman是可以正常取得資料的
但是當我用Docker把Zabbix架設在Window環境下時卻一直出現
的錯誤
發現錯誤
兩邊的版本、設置、Server Port都一樣,完全不知道到底發生了什麼問題,後來是透過網頁的開發人員工具才發現一小處的不同
這是Linux環境下的API請求
這是Window下的API請求
聰明的你一定發現了,肏你媽的這兩個API請求的URL完全不一樣啊,幹你媽的
解決方法
我個人猜應該是Docker在部屬的時候,不知道為什麼裡面檔案的結構層級直接跳過了\zabbix這一層,直接變成http://localhost/api_jsonrpc.php
的路徑。
將URL改成正確地之後就能正常訪問了