文章目的:
1、向沒聽過或者剛聽過但是還對這個監控系統沒有任何概念的開發者介紹Prometheus的應用場景。
2、向有需要深入的了解的人推薦一些博客、書籍。
3、內心真實想法:本想寫個系統一點的,但是列出那些博文書籍之后,感覺已經沒有必要了。。。
什么是Prometheus?
prometheus是一個開源的監控系統。。。算了官方的話一大把看得太累
那么到底什么是Prometheus
呢,他確實是用來做監控系統的,但是這里我們先不討論它,我們來看個小工具node_exporter
什么是 node_exporter
舉個例子,如果你有一臺服務器,你想要獲取它運行時候的參數,比如當前的CPU負載、系統負載、內存消耗、硬盤使用量、網絡IO等等,那么你就可以在服務器上運行一個node_exporter
,它能幫你把這些參數收集好,并且暴露出一個HTTP接口以便你訪問查詢。廢話不多說我們直接試一試
準備一臺Linux服務器,外網互通:
IP:10.19.70.139
系統:ubuntu 16.04
登錄系統進入/opt
目錄(目錄隨便指定,空間大于待會兒下載的文件大小即可)
下載并運行最新版的node_exporter 【如果你想看源碼,可以訪問gihub開源地址,它是Go語言編寫的,部署很方便】
cd /opt sudo wget https://github.com/prometheus/node_exporter/releases/download/v0.17.0/node_exporter-0.17.0.linux-amd64.tar.gz sudo tar -zxvf node_exporter-0.17.0.linux-amd64.tar.gz cd node_exporter-0.17.0.linux-amd64 sudo ./node_exporter
可以看到如下的輸出
訪問方式:IP+Port
我們訪問http://10.19.70.139:9100
點擊Metrics
(如果你使用老版本的node_exporter那么可能沒有這個Metric標題頁)就可以看到暴露出來的系統參數了
指標舉例
#HELP node_cpu_seconds_total Seconds the cpus spent in each mode.
#TYPE node_cpu_seconds_total counter
node_cpu_seconds_total{cpu="0",mode="idle"} 1.40181324e+06
這是其中一條指標,由指標名+{標簽鍵值對}+值
組成。
#HELP
開頭的行用來說明下面指標node_cpu_seconds_total
的意義:
指標node_cpu_seconds_total
用來表示CPU在每種模式下工作的秒數,而大括號里的稱之為標簽,以鍵值對的形式出現,可以用來細分同一個指標下的不同部分,比如這里的cpu="0"
表示CPU的第0個核心,mode="idle"
表示工作模式為idle,也就是沒被任何程序使用的空閑模式。
#TYPE
開始的第二行表示指標的數值類型為counter
類型。在Prometheus的規范中,counter
類型表示只增長的類型,也就是只會增加不會減少的值,且數值只能是正整數。大數值會啟用科學計數法。
此時可以看出指標node_cpu_seconds_total{cpu="0",mode="idle"} 1.40181324e+06
表示節點的CPU0的空閑時間共計1.40181324e+06秒。數值從系統開機時算起,重啟歸零。
問題與答案:
此時我們可以從頁面中看到很多類似的指標以及值,如果只打算監控這一臺,又或者只需要這一個值,我們可以自行編寫代碼訪問這個接口,匹配出想要的指標和值即可。但是如果有很多臺服務器,而且想要綜合多臺進行對比分析,更有甚者希望將指標繪制成圖表,或者說保留歷史數據以便查詢過去的某個時間點其服務器的運行狀態,那么這將會變得很麻煩。而
Prometheus
就是干這個事情的。
什么是Prometheus?
現在當我們再一次討論什么是Prometheus的時候,我想你心里一定有個大概的猜測了,如果你認真思考了上面的問題與答案
的話。我們想要獲取所有的服務器上node_exporter暴露出來的數據,就必須有個程序去定時訪問這些接口,如果想要增加或者修改這些接口,那么就需要有個配置文件來記錄這些服務器的地址,如果想要訪問歷史的某個時間點的數據,那么就必須按照時間順序存儲獲取到的指標和值。而如果想要將值繪制成圖,也需要有代碼去查詢、計算和渲染。最后你可能還希望當服務器的某個指標超過一定的閾值時,向指定的接口發出告警信息。一切的一切其實都可以使用Prometheus來解決,現在我們可以去了解什么是Prometheus了。
先上一張官方的架構圖
從架構圖中可以看到,我們先前驗證的node_exporter屬于jobs/exporter部分,稱之為exporter
導出器,是Prometheus主要的指標來源。
Prometheus Server
是服務核心組件,存儲使用時序數據庫TSDB
將數據保存在硬盤上,由于官方對SSD做了專門的優化,所以使用SSD性能會更優。
配置方式包含多種,可以直接在寫在yaml
文件中,但如果配置較長也可以寫入其他文件并啟用文件發現
(file_sd)功能讓其自行偵聽配置文件變化,甚至可以使用consul或者kubernetes這樣的服務發現
來動態更新配置以適應頻繁的節點變更。
Prometheus使用pull
模型從節點暴露出來的端口拉取配置,這相比push方式更容易避免節點異常帶來的干擾和繁瑣的工作。
pushgateway
類似于一個中轉站,Prometheus的server端只會使用pull方式拉取數據,但是某些節點因為某些原因只能使用push方式推送數據,那么它就是用來接收push而來的數據并暴露給Prometheus的server拉取的中轉站。
Prometheus支持告警系統,自帶的alertmanager
可以通過在配置文件中添加規則的方式,計算并發出警報,它支持多種發送方式比如pagerduty、Email等等。
對于已經存儲的歷史數據,Prometheus提供了PromQL
語言進行查詢,并自帶了一個簡易的UI界面,可以在界面上進行查詢、繪圖、查看配置、告警等等。
架構圖中,Grafana等其他API客戶端可以通過PromQL查詢語言查詢Prometheus中存儲的數據。在這里,大部分用戶喜歡將Grafana與Prometheus配合使用,因為Prometheus自帶的UI界面太過簡陋,而Grafana提供的界面非常的美觀,且可以長期保留。
話休繁緒,跑一個測試看看
Prometheus的官方下載地址為 https://prometheus.io/download/
我們另起一個ssh連接到服務器,選擇一個版本下載并啟動
cd /opt
sudo wget https://github.com/prometheus/prometheus/releases/download/v2.6.0/prometheus-2.6.0.linux-amd64.tar.gz
sudo tar -zxvf prometheus-2.6.0.linux-amd64.tar.gz
cd prometheus-2.6.0.linux-amd64/
編輯配置文件sudo vim prometheus.yml
在scrape_configs欄添加如下配置
- job_name: "node"
static_configs:
- targets: ["localhost:9100"]
此時的配置文件加上原來已經默認存在的,如下(可能因為版本不同而不同):
#my global config
global:
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
#scrape_timeout is set to the global default (10s).
#Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
#- alertmanager:9093
#Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
#- "first_rules.yml"
#- "second_rules.yml"
#A scrape configuration containing exactly one endpoint to scrape:
#Here it's Prometheus itself.
scrape_configs:
#The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
#metrics_path defaults to '/metrics'
#scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9090']
- job_name: "node"
static_configs:
- targets: ["localhost:9100"]
yaml文件要尤其注意縮頸,這里我默認你已經懂得了yaml文件的規則。
啟動Prometheus
sudo ./prometheus
此時Prometheus的輸出如下
level=info ts=2018-12-29T08:51:26.126230419Z caller=main.go:243 msg="Starting Prometheus" version="(version=2.6.0, branch=HEAD, revision=dbd1d58c894775c0788470944b818cc724f550fb)"
level=info ts=2018-12-29T08:51:26.126302838Z caller=main.go:244 build_context="(go=go1.11.3, user=root@bf5760470f13, date=20181217-15:14:46)"
level=info ts=2018-12-29T08:51:26.126419034Z caller=main.go:245 host_details="(Linux 4.4.0-132-generic #158-Ubuntu SMP Thu Aug 2 09:08:04 UTC 2018 x86_64 master1 (none))"
level=info ts=2018-12-29T08:51:26.126497022Z caller=main.go:246 fd_limits="(soft=1000000, hard=1000000)"
level=info ts=2018-12-29T08:51:26.126567171Z caller=main.go:247 vm_limits="(soft=unlimited, hard=unlimited)"
level=info ts=2018-12-29T08:51:26.127332045Z caller=main.go:561 msg="Starting TSDB ..."
level=info ts=2018-12-29T08:51:26.127414745Z caller=web.go:429 component=web msg="Start listening for connections" address=0.0.0.0:9090
level=info ts=2018-12-29T08:51:26.135164421Z caller=main.go:571 msg="TSDB started"
level=info ts=2018-12-29T08:51:26.135204665Z caller=main.go:631 msg="Loading configuration file" filename=prometheus.yml
level=info ts=2018-12-29T08:51:26.136207062Z caller=main.go:657 msg="Completed loading of configuration file" filename=prometheus.yml
level=info ts=2018-12-29T08:51:26.136232588Z caller=main.go:530 msg="Server is ready to receive web requests."
最后一行顯示Server is ready to receive web requests.
,也就是服務已經準備好了。我們訪問鏈接
http://10.19.70.139:9090
在首頁可以看到Prometheus自帶的UI界面如下
從界面中可以看到,標題欄Graph鏈接到圖形查詢界面,在輸入框中允許輸入查詢語句,點擊execute執行,insert metric at cursor下拉列表中列舉了當前所有的存在的指標可以不用輸入而直接選擇。
往下,默認的console欄表示查詢結果以文字的形式顯示,而Graph欄表示繪制圖表。
我們試一下,在輸入框中輸入先前的指標名node_cpu_seconds_total
單機Execute。
可以看到很多指標被列舉了出來
為了更精確的查詢,我們輸入node_cpu_seconds_total{cpu="0",mode="idle"}
可以看到很精確的查詢結果被展示出來
node_cpu_seconds_total{cpu="0",instance="localhost:9100",job="node",mode="idle"} 1420025.1
為了方便我直接拷貝出來了,可以看到,指標新增了很多的標簽
比如instance就表示IP地址和端口號,是配置文件中輸入的
點擊Graph查看圖形
可以看到圖形一直處于增長狀態,這是合理的,因為他是counter類型,而且我們還沒有做任何運算。
這個圖本身對開發者或者用戶而言并沒有什么作用可言,但是想象一下,如果我們截取每一分鐘內變化的數據,將其除以60秒,是否可以得到每秒中CPU0空閑率。這么理解,如果在某段時間計算出來的值越高,則說明CPU0的使用率越低,而數值越低,說明CPU0利用率越高,也就是越繁忙。
在搜索欄鍵入rate(node_cpu_seconds_total{cpu="0",mode="idle"}[1m])
這段的意思為選取1分鐘內的數據的差值以60秒,rate函數就是用來做這個事情的。
得到以下圖形
可以看出,我這臺服務器的CPU0一直還是比較閑的
當然也可以使用稍微復雜一點的公式計算出整個CPU的工作狀態
鍵入
(((count(count(node_cpu_seconds_total) by (cpu))) - avg(sum by (mode)(irate(node_cpu_seconds_total{mode='idle'}[5m])))) * 100) / count(count(node_cpu_seconds_total) by (cpu))
這段查詢語句表示計算出CPU所有核數的busy狀態總和在整個CPU時間的占比。從圖中可以看到CPU時而忙碌時而悠閑。
在targets面板,我們可以查看所有配置,如果該配置能夠成功拉取數據,則為狀態為綠色UP,否則為紅色DOWN。如果配置了alert規則,還可以在Alert面板查看到他們。
我這里就不一一演示了。
配置、存儲、圖表與告警
現在我們已經可以利用Prometheus進行數據拉取,并且繪制圖形了,但是對于生產環境中面臨的情況來說,完全不夠。我們要可配置、可存儲、隨時查看圖表、指定閾值告警等等。
為了與本機環境隔離,我將使用docker進行后續的演示,在這里我默認你已有了docker的基本知識以及可以使用docker-compose進行服務編排。
為了長期存儲,我們需要指定Prometheus的存儲目錄
為了繪圖與保留圖形以便二次查看,我們引入Grafana作為儀表板
對于告警,由于Prometheus自帶的告警配置相對復雜,這里我使用了Grafana所提供的告警,它的告警很簡單,所見即所得,拖動滑塊就可以配置閾值。
關閉先前啟動的prometheus
(測試的時候我換了虛擬機,可能后續IP地址會有變化)
在/opt目錄下建立配置目錄,為方便操作我切換到管理員權限
sudo su
cd /opt
mkdir -p prometheus/config/
mkdir -p grafana/data
chmod 777 grafana/data
mkdir -p /data/prometheus
chmod 777 /data/prometheus
編輯docker-compose.yml
文件并鍵入
version: '2'
networks:
monitor:
driver: bridge
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
hostname: prometheus
restart: always
volumes:
- /opt/prometheus/config:/etc/prometheus
- /data/prometheus:/prometheus
ports:
- "9090:9090"
expose:
- "8086"
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--log.level=info'
- '--web.listen-address=0.0.0.0:9090'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention=15d'
- '--query.max-concurrency=50'
networks:
- monitor
grafana:
image: grafana/grafana:latest
container_name: grafana
hostname: grafana
restart: always
volumes:
- /opt/grafana/data:/var/lib/grafana
ports:
- "3000:3000"
- "25:25"
networks:
- monitor
depends_on:
- prometheus
拷貝先前的配置文件prometheus.yml到/opt/prometheus/config目錄下并替換所有localhost為IP地址。
運行docker-compose up
啟動容器
此時可以看到docker-compose打印的日志部分如下
prometheus | level=info ts=2019-01-28T03:43:24.580746431Z caller=web.go:429 component=web msg="Start listening for connections" address=0.0.0.0:9090
grafana | t=2019-01-28T03:43:25+0000 lvl=info msg="HTTP Server Listen" logger=http.server address=0.0.0.0:3000 protocol=http subUrl= socket=
為了確保Prometheus可以順利拉取node_exporter上的數據,我們仍需要檢查下它的UI界面,訪問http://192.168.112.129:9090/targets
,選擇targets。
如下圖,status為UP,點擊前面的URL可以順利訪問到詳細信息則表示OK。
此時訪問http://10.19.70.139:3000/
就可以看到Grafana的登錄界面
初始密碼admin/admin
那么什么是Grafana
Grafana是一個跨平臺的開源的度量分析和可視化工具,可以通過將采集的數據查詢然后可視化的展示,并及時通知。它主要有以下六大特點:
1、展示方式:快速靈活的客戶端圖表,面板插件有許多不同方式的可視化指標和日志,官方庫中具有豐富的儀表盤插件,比如熱圖、折線圖、圖表等多種展示方式;
2、數據源:Graphite,InfluxDB,OpenTSDB,Prometheus,Elasticsearch,CloudWatch和KairosDB等;
3、通知提醒:以可視方式定義最重要指標的警報規則,Grafana將不斷計算并發送通知,在數據達到閾值時通過Slack、PagerDuty等獲得通知;
4、混合展示:在同一圖表中混合使用不同的數據源,可以基于每個查詢指定數據源,甚至自定義數據源;
5、注釋:使用來自不同數據源的豐富事件注釋圖表,將鼠標懸停在事件上會顯示完整的事件元數據和標記;
6、過濾器:Ad-hoc過濾器允許動態創建新的鍵/值過濾器,這些過濾器會自動應用于使用該數據源的所有查詢。
注:偷個懶,上面這段Grafana的介紹來自別人的博文可視化工具Grafana:簡介及安裝,有興趣可以看看。
進入初始界面之后會看到這樣的家目錄
稍作解釋,中間的一欄
Install Grafana、Add data source、Create your first dashboard等等是操作流程,表示已經完成了哪些操作以及進度,從左往右。
添加數據源
點擊 Add data source
,選擇Prometheus,在URL輸入框鍵入http://192.168.112.129:9090
,點擊save & test
,如果出現下圖中的綠色提示,則表示配置有效,否則可能是地址或者端口等其他錯誤,需要自行修改。
點擊左側的Home回到家目錄
接下來是create一個Dashboard,這里,如果需要自定義一些圖表,則可以手動添加。然而我們的node_exporter是開源的項目,而且也有他的開源的對應的圖表,那么我們可以直接使用開源的圖表以簡化操作。現在我們來看看如何搜索和添加開源的圖表。(對于很多需要監控的應用比如mysql、kafka等等,都可以去網上尋找開源的exporter和相應的dashboard圖表,比如Prometheus的開源地址,【Default port allocations】)
單機左上角的Home
選擇搜索功能
我們選擇數據源為Prometheus
并鍵入node_exporter
使用Enter
鍵開始搜索。
從搜索結果中選擇一條,比如第一條,單機
界面中可以看到關于這個圖表的簡介,點擊copy它的ID。
回到原先的Home界面,選擇import dashboard
在Grafana.com Dashboard欄粘貼先前拷貝的ID
它會自動識別出dashboard的相關信息
我們需要選擇它的數據源,這里是Prometheus,然后Import即可
在這個面板上,Name可以修改為自己想要的,Folder可以對該dashboard分類存放,其他也可以看到作者信息等。
添加完畢會自動來到dashboard頁面【該dashboard需要node_exporter0.16以上版本,如果不是可以更換node_exporter版本或者選擇其他dashboard】
在這里,我重新挑選了一個ID為5174
的dashboard這是我最喜歡的的node_exporter版本。
import之后,在主界面此時并沒有圖像顯示出來。點擊右上角的設置,選擇Variables
選擇第一行 $node ,替換node_boot_time_seconds
為up
,此時可以在最下方看到配置的主機IP地址,也有可能是localhost,最后選擇Update
依葫蘆畫瓢,替換$port
,中的參數為label_values(up, instance)
。
這里注意一點,$port的編輯界面中,Hide參數先選擇為空(如果默認為variable的話),否則port參數在主界面就看不到了。
點擊左側save之后,選擇回到dashboard主界面。
此時,node_exporter的數據就以圖表的形式展示出來了。
將系統指標以圖形的形式展示出來,這無疑是有趣且實用的。
現在依然有一些問題
比如Prometheus的存儲數據庫默認只保留15天的數據,Grafana存儲的配置以及圖表都還在容器之中它自己生成的sqlit數據庫中長期存儲并不友好。
為了更適應老板的需求,我們可以添加時序數據庫InfluxDB作為后端存儲,可以修改grafana的存儲為mysql以便自己做一些自定義操作的時候方便一點,添加pushgateway接收來自腳本推送的指標。這時我們的yml文件可以是這個樣子的.
version: '2'
networks:
monitor:
driver: bridge
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
hostname: prometheus
restart: always
volumes:
- /home/ubuntu/monitors/prometheus/config:/etc/prometheus
- /data/monitors/prometheus_data:/prometheus
ports:
- "9090:9090"
expose:
- "8086"
depends_on:
- influxdb
#environment:
#- storage.tsdb.retention=168h0m0s
#- storage.tsdb.retention=15d
#- log.level=debug
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--log.level=info'
- '--web.listen-address=0.0.0.0:9090'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention=15d'
- '--query.max-concurrency=50'
logging:
driver: "json-file"
options:
max-size: "1g"
networks:
- monitor
grafana:
image: grafana/grafana:latest
container_name: grafana
hostname: grafana
restart: always
volumes:
- /home/ubuntu/monitors/grafana/config:/etc/grafana
- /home/ubuntu/monitors/grafana/logs:/var/log/grafana
- /home/ubuntu/monitors/grafana/data:/var/lib/grafana
- /home/ubuntu/monitors/grafana/dashboards:/etc/grafana/provisioning/dashboards
ports:
- "3000:3000"
- "25:25"
- "465:465"
user: "104"
networks:
- monitor
depends_on:
- db
db:
image: mysql:5.7
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: root
hostname: mysql
restart: always
volumes:
- /home/ubuntu/monitors/mysql/config:/etc/mysql
- /home/ubuntu/monitors/mysql/data:/var/lib/mysql
- /home/ubuntu/monitors/mysql/log:/var/log/mysql
networks:
- monitor
pushgateway:
image: prom/pushgateway:latest
container_name: pushgateway
hostname: pushgateway
restart: always
ports:
- "9091:9091"
networks:
- monitor
influxdb:
image: influxdb:latest
container_name: influxdb
hostname: influxdb
restart: always
volumes:
- /home/ubuntu/monitors/influxdb/config:/etc/influxdb
- /data/monitors/influxdb/data:/root/.influxdb
#command: -config /etc/influxdb/influxdb.conf
ports:
- "8086:8086"
- "8083:8083"
expose:
- "8086"
environment:
- INFLUXDB_DB=prometheus
- INFLUXDB_ADMIN_ENABLED=true
- INFLUXDB_ADMIN_USER=admin
- INFLUXDB_ADMIN_PASSWORD=admin
- INFLUXDB_USER=prom
- INFLUXDB_USER_PASSWORD=prom
- INFLUXDB_CONFIG_PATH=/etc/influxdb/influxdb.conf
networks:
- monitor
logging:
driver: "json-file"
options:
max-size: "1g"
從文件描述中可以看出,我重新指定了Prometheus的存儲數據庫為InfluxDB,指定Grafana存儲圖表的數據庫為熟悉的MySQL,設置日志不超過1G等,當然,這些也需要Prometheus和Grafana的配合。
在Prometheus的配置文件中,添加遠程讀寫。
scrape_configs:
- job_name: mx-discovery
file_sd_configs:
- files:
- '/etc/prometheus/fileconfig/mx-nodes.json'
remote_write:
- url: "http://influxdb:8086/api/v1/prom/write?db=prometheus&u=prom&p=prom"
remote_read:
- url: "http://influxdb:8086/api/v1/prom/read?db=prometheus&u=prom&p=prom"
file_sd_configs表示啟動prometheus的文件發現功能。也就是說,可以將配置主機等信息寫入文件中,如果用戶修改了配置,比如增加或刪除了某些主機,那么Prometheus會自動發現這些更改而不用每次reload甚至重啟。
所以文件可以是這樣的
[
{
"targets": ["192.168.1.8:9100"],
"labels": {
"alias": "test1",
"job": "node"
}
},
{
"targets": ["192.168.1.9:9100"],
"labels": {
"alias": "test2",
"job": "node"
}
}
]
還有Grafana的配置(如果找不到配置,或者容器無法將配置映射出來,那么直接進入容器拷貝一份出來即可)
[database]
# You can configure the database connection by specifying type, host, name, user and password
# as separate properties or as on string using the url properties.
type = mysql
host = mysql:3306
name = grafana
user = grafana
password =grafana
url = mysql://grafana:grafana@mysql:3306/grafana
[session]
# Either "memory", "file", "redis", "mysql", "postgres", default is "file"
#provider = file
provider = mysql
provider_config = `grafana:grafana@tcp(mysql:3306)/grafana`
關于了解入門,我就只介紹這么多了,更多的可以參考官網或者其他一些更專業的博文。
附錄
Prometheus官方文檔英文
Grafana官方文檔英文
prometheus + grafana安裝部署(centos6.8)
Prometheus入門與實踐
全面學習Prometheus
Prometheus 非官方中文手冊
Prometheus實戰
Prometheus-book
大米哥-Prometheus普羅米修斯監控-合集專題付費視頻專題
Grafana的一些實用技巧
Prometheus:Up & Running這本書對Prometheus介紹的很系統,可以用來學習提高,也可以用來當工具書,不過也是英文的,國內是可以下載到的。(我放的這個地址注冊后可以免費看幾天,作為了解)。