docker+prom+grafana+altermanager

docker基礎

docker run -it --name centos -v $HOME:/tmp -p 8080:8080 centos
docker inspect container   #查看已啓動容器啓動命令
docker container prune    #刪除退出的容器
docker ps -a --no-trunc    #查看容器啓動參數

反查dockerfile

方法一:
docker history --format {{.CreatedBy}} --no-trunc=true 0e0218889c33|sed "s?/bin/sh\ -c\ \#(nop)\ ??g"|sed "s?/bin/sh\ -c?RUN?g" | tac

方法二:
apt-get install npm    #管理前端包工具
npm install npx
npx dockerfile-from-image node:8 > dockerfile   #解析dockerfile

修改容器鏡像的啓動命令 -- docker 修改啓動命令

#使用宿主機網絡,並將容器名稱修改爲prometheus,-d後臺運行
docker run -d -p 9090:9090 --name prometheus --net=host prom/prometheus

#將容器裏文件拷貝出來到root目錄
docker cp prometheus:/etc/prometheus/prometheus.yml /root/

#修改後掛載加進去
docker run -d -v /opt/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml   \
-p 9090:9090 --name prometheus --net=host prom/prometheus

docker logs contianid   #查看日誌
docker search  java    #從docker hub中搜索java鏡像,可以查看版本

容器端口

9100 node-export
9090 prometheus
3000 grafana

啓動

  • 啓動node-exporter
docker run -d --name=node-exporter -p 9100:9100 prom/node-exporter
  • 啓動grafana

    密碼:admin,admin;配置文件/etc/grafana
    docker run -d --name=grafana -p 3000:3000 grafana/grafana
  • 啓動prom
    
    #將容器裏文件拷貝出來到root目錄
    docker cp prometheus:/etc/prometheus/prometheus.yml /root/

#修改後掛載加進去
docker run -d -v /opt/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml \
-p 9090:9090 --name prometheus --net=host prom/prometheus


# docker 鏡像自啓動
- 在運行docker容器時可以加如下參數來保證每次docker服務重啓後容器也自動重啓:

docker run --restart=always
如果已經啓動了則可以使用如下命令:
docker update --restart=always <CONTAINER ID>


# 配置文件
## prom配置
配置幫助
```yaml

global:
  #默認情況下抓取目標的頻率.
  [ scrape_interval: <duration> | default = 1m ]

  # 抓取超時時間.
  [ scrape_timeout: <duration> | default = 10s ]

  # 評估規則的頻率.
  [ evaluation_interval: <duration> | default = 1m ]

  # 與外部系統通信時添加到任何時間序列或警報的標籤
  #(聯合,遠程存儲,Alertma# nager).
  external_labels:
    [ <labelname>: <labelvalue> ... ]

# 規則文件指定了一個globs列表. 
# 從所有匹配的文件中讀取規則和警報.
rule_files:
  [ - <filepath_glob> ... ]

# 抓取配置列表.
scrape_configs:
  [ - <scrape_config> ... ]

# 警報指定與Alertmanager相關的設置.
alerting:
  alert_relabel_configs:
    [ - <relabel_config> ... ]
  alertmanagers:
    [ - <alertmanager_config> ... ]

# 與遠程寫入功能相關的設置.
remote_write:
  [ - <remote_write> ... ]

# 與遠程讀取功能相關的設置.
remote_read:
  [ - <remote_read> ... ]

具體配置

root@ubuntu:~# cat prometheus.yml 
# 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.
    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

  - job_name: prometheus
    static_configs:
    - targets: ['192.168.191.128:9090']
      labels:
        instance: prometheus
  - job_name: 'consul' #prometheus與consul配置段
    consul_sd_configs:
      - server: '192.168.191.128:8500'
        services: [ ]
  - job_name: node-exporter
    static_configs:
    - targets: ['192.168.191.128:9100']
      labels:
        instance: node-exporter

動態配置file_sd_config:

  • 修改/usr/local/prometheus/*.json增加刪除,支持動態更新
    
    在prometheus.yaml配置文件最後增加
    - job_name: 'node-discorvery'   #發現規則名稱
    file_sd_configs:                       #選擇適配器
      - files: 
        - /usr/local/prometheus/*.json   #匹配文件

在對應目錄/usr/local/prometheus/*.json添加,容器啓動時需要掛載進去
[
{
"targets": [ "10.10.2.99:9100"],
"labels": {
"job": "linux-bj",
"idc": "bj-jiuxianqiao"
}
},
{
"targets": [ "10.10.2.62:9100","10.10.1.35:9100"],
"labels": {
"job": "linux-gx",
"idc": "gz-daxuecheng"
}
}
]
















## rule_files:配置
- 配置告警規則,在prometheus.yml中指定規則文件目錄
- prometheus根據這些規則信息,會推送報警信息到alertmanager中。
```yaml

alertmanager_config:配置

  • 指定Prometheus服務器向其發送警報的Alertmanager實例
  • 提供參數以配置如何與這些Alertmanagers進行通信。
  • Alertmanagers支持靜態指定或者動態發現指定
  • relabel_configs允許從發現的實體中選擇Alertmanagers,並對使用的API路徑提供高級修改,該路徑通過__alerts_path__標籤公開
    # Alertmanager configuration   #告警配置
    alerting:
    alertmanagers:  
    - static_configs:  #告警規則,也可以基於動態的方式進行告警。
    - targets:     
      # - alertmanager:9093

remote_write

指定後端的存儲的寫入api地址。

remote_read

指定後端的存儲的讀取api地址。

relabel_config

  • 重新標記是一種強大的工具,可以在抓取目標之前動態重寫目標的標籤集。 每個抓取配置可以配置多個重新標記步驟。 它們按照它們在配置文件中的出現順序應用於每個目標的標籤集。標籤默認在prometheus web console可以看到相關的標籤:
    docker+prom+grafana+altermanager

使用

promtheus使用

docker+prom+grafana+altermanager

node_cpu_seconds_total{cpu="0"}
docker+prom+grafana+altermanager

grafana使用

grafana的dashboard地址

prometheus exporter

Process-exporter 進程監控

docker search process-exporter   #查看排名最高的
docker pull opvizorpa/process-exporter   #下載
docker inspect 9ec6749205fc      #查看鏡像啓動配置信息:9256端口
apt-get install nginx         #安裝nginx測試

docker run -d --rm -p 9256:9256 --privileged -v /proc:/host/proc -v `pwd`:/config ncabatoff/process-exporter --procfs /host/proc -config.path /config/filename.yml

# 本地安裝
[root@host-10-10-2-62 ~]# wget https://github.com/ncabatoff/process-exporter/releases/download/v0.5.0/process-exporter-0.5.0.linux-amd64.tar.gz
[root@host-10-10-2-62 ~]# tar -xf process-exporter-0.5.0.linux-amd64.tar.gz -C /usr/local/

# 開機自啓動
[root@host-10-10-2-62 process-exporter-0.5.0.linux-amd64]# cat /etc/systemd/system/process-exporter.service 
[Unit]
Description=node exporter
Documentation=node exporter

[Service]
ExecStart=/usr/local/process-exporter-0.5.0.linux-amd64/process-exporter -config.path /usr/local/process-exporter-0.5.0.linux-amd64/process-name.yaml 

[Install]
WantedBy=multi-user.target

# 配置文件根據變量名匹配到配置文件:  
{{.Comm}} 包含原始可執行文件的basename,/proc/stat 中的換句話說,2nd 字段  
{{.ExeBase}} 包含可執行文件的basename  
{{.ExeFull}} 包含可執行文件的完全限定路徑  
{{.Matches}} 映射包含應用命令行tlb所產生的所有匹配項

# 增加監控nginx配置文件
root@ubuntu:~# cat process-name.yaml 
process_names:
  - name: "{{.Matches}}"
    cmdline:
    - 'nginx'

# 監控所有進程
[root@host-10-10-2-62 process-exporter-0.5.0.linux-amd64]# cat process-name.yaml 
process_names:
  - name: "{{.Comm}}"
    cmdline:
    - '.+'

# prometheus server添加監控
  - job_name: 'process'
    static_configs: 
      - targets: ['10.10.2.62:9256']

# 進程查詢
統計有多少個進程數:sum(namedprocess_namegroup_states)

統計有多少個殭屍進程:sum(namedprocess_namegroup_states{state="Zombie"})

pushgateway

配置

pushgateway 9091

docker pull prom/pushgateway

docker run -d \
--name=pushgateway \
-p 9091:9091 \
prom/pushgateway

訪問ip+9091

prometheus配置文件中prometheus.yml添加target:
  - job_name: pushgateway
    static_configs:
      - targets: ['192.168.191.128:9091']
        labels:
          instance: pushgateway

URL:http://<ip>:9091/metrics/job/<JOBNAME>{/<LABEL_NAME>/<LABEL_VALUE>},

測試推送數據

echo "some_metric 3.14" | curl --data-binary @- http://192.168.191.128:9091/metrics/job/some_job

# 一次性推送多條數據
cat <<EOF | curl --data-binary @http://192.168.2.14:9091/metrics/job/some_job/instance/some_instance
 # TYPE some_metric counter
 some_metric{label="val1"} 42
# TYPE another_metric gauge
# HELP another_metric Just an example.
another_metric 2398.283
EOF
  • 可以發現 pushgateway 中的數據我們通常按照 job 和 instance 分組分類,所以這兩個參數不可缺少。

docker+prom+grafana+altermanager

統計當前tcp併發連接數,推送到pushgateway

[root@host-10-10-2-109 ~]# cat count_netstat_esat_connections.sh 
#!/bin/bash
instance_name=`hostname -f | cut -d'.' -f1`  #獲取本機名,用於後面的的標籤
label="count_netstat_established_connections"  #定義key名
count_netstat_established_connections=`netstat -an | grep -i ESTABLISHED | wc -l`  #獲取數據的命令
echo "$label: $count_netstat_established_connections"
echo "$label  $count_netstat_established_connections" | curl --data-binary @- http://10.10.2.109:9091/metrics/job/pushgateway_test/instance/$instance_name
  • 域名中label 表示標籤名稱,後面跟的是數值。Job 後面定義的是pushgateway_test(與prometheus定義的一致,域名),instance_name 變量表示主機名。

docker+prom+grafana+altermanager

  • 眼尖的會發現這裏頭好像不太對勁,剛剛提交的指標所屬 job 名稱爲 exported_job="pushgateway_test" ,而 job 顯示爲 job="pushgateway" ,這顯然不太正確,那這是因爲啥?其實是因爲 Prometheus 配置中的一個參數 honor_labels (默認爲 false)決定的。
  - job_name: pushgateway
    honor_labels: true
    static_configs:
      - targets: ['10.10.2.109:9091'] 
        labels:
          instance: pushgateway 

docker+prom+grafana+altermanager

python 接口pushgateway 數據推送:

1、安裝prometheus\_client模塊:
apt install python-pip
pip install prometheus_client

2、簡單示例文件:

[root@host-10-10-2-109 ~]# cat client.py 
from prometheus_client import CollectorRegistry, Gauge, push_to_gateway
registry = CollectorRegistry()
g = Gauge('job_last_success_unixtime', 'Last time a batch job successfully finished', registry=registry)
g.set_to_current_time()
push_to_gateway('localhost:9091', job='batchA', registry=registry)
#執行腳本
[root@host-10-10-2-109 ~]# python client.py 

3、查詢結果:
docker+prom+grafana+altermanager

docker+prom+grafana+altermanager

4、稍微更改一下,獲取的是ping 的數據:

[root@host-10-10-2-109 ~]# cat client_ping.py 
#!/usr/bin/python
from prometheus_client import CollectorRegistry, Gauge, push_to_gateway
registry = CollectorRegistry()
g = Gauge('ping', 'pingtime',['dst_ip','city'], registry=registry) #Guage(metric_name,HELP,labels_name,registry=registry)
g.labels('192.168.1.10','shenzhen').set(42.2)    #設置標籤
g.labels('192.168.1.11','shenzhen').set(41.2)
g.labels('192.168.1.12','shenzhen').set(32.1)  
push_to_gateway('localhost:9091', job='ping_status', registry=registry)
[root@host-10-10-2-109 ~]# python client_ping.py 

docker+prom+grafana+altermanager
docker+prom+grafana+altermanager

promql

範圍向量

  • s - seconds
  • m - minutes
  • h - hours
  • d - days
  • w - weeks
  • y - years
    prometheus_http_requests_total{handler="/api/v1/query"}[5m]
    時間位移操作:
    prometheus_http_requests_total{} offset 5m #返回5分鐘前的樣本,瞬時位移
    prometheus_http_requests_total{}[1d] offset 1d  #返回昨天一天的數據樣本,區間位移


標量浮點值

標量浮點值可以直接寫成形式[-](digits)[.(digits)]

例如: 20
標量只有一個數字,沒有時序。需要注意的是,當使用表達式count(http_requests_total),返回的數據類型,依然是瞬時向量。用戶可以通過內置函數scalar()將單個瞬時向量轉換爲標量。

字符串:string

"this is a string"
'these are unescaped: \n \\ \t'
`these are not unescaped: \n ' " \t`

Promql操作符

使用PromQL除了能夠方便的按照查詢和過濾時間序列以外,PromQL還支持豐富的操作符,用戶可以使用這些操作符對進一步的對事件序列進行二次加工。這些操作符包括:數學運算符,邏輯運算符,布爾運算符等等。

數學運算

PromQL支持的所有數學運算符如下所示:

 + (加法)
  - (減法)
  * (乘法)
  / (除法)
  % (求餘)
  ^ (冪運算)

舉例說明例如我們查詢主機的內存大小,返回的是Bytes,如果我要把他轉換成G可以使用一下表達式:

node_memory_MemTotal_bytes / 1024 /1024 /1024

返回的結果是一個瞬時向量。兩個瞬時向量之間的數學計算例如:

node_disk_written_bytes_total + node_disk_read_bytes_total #返回的是多塊磁盤之間的讀寫IO

那麼我們會發現是根據表達式的標籤進行數學運算,分別算出vda、vdb的磁盤io.

布爾運算

在PromQL通過標籤匹配模式,用戶可以根據時間序列的特徵維度對其進行查詢。而布爾運算則支持用戶根據時間序列中樣本的值,對時間序列進行過濾,常常用在我們的告警規則當中。

Prometheus支持以下布爾運算符如下:


 == (相等)
 != (不相等)
 > (大於)
 < (小於)
 >= (大於等於)
 <= (小於等於)

使用bool修飾符、返回匹配的查詢結果:

例如:通過數學運算符我們可以很方便的計算出,當前所有主機節點的內存使用率:

(node_memory_bytes_total - node_memory_free_bytes_total) / node_memory_bytes_total

而在我們寫告警規則的時候我們需要篩選出,內存使用率超過百分之95的主機、則可以使用布爾運算表達式:

(node_memory_bytes_total - node_memory_free_bytes_total) / node_memory_bytes_total &gt; 0.95

集合運算符

使用瞬時向量表達式能夠獲取到一個包含多個時間序列的集合,我們稱爲瞬時向量。 通過集合運算,可以在兩個瞬時向量與瞬時向量之間進行相應的集合操作。目前,Prometheus 支持以下集合運算符:

and (並且)
or (或者)
unless (排除)

vector1 and vector2 會產生一個由 vector1 的元素組成的新的向量。該向量包含 vector1 中完全匹配 vector2 中的元素組成。

vector1 or vector2 會產生一個新的向量,該向量包含 vector1 中所有的樣本數據,以及 vector2 中沒有與 vector1 匹配到的樣本數據。

vector1 unless vector2 會產生一個新的向量,新向量中的元素由 vector1 中沒有與 vector2 匹配的元素組成。

操作運算符優先級

在 Prometheus 系統中,二元運算符優先級從高到低的順序爲:

 ^
*, /, %
 +, -
 ==, !=, <=, <, >=, >
 and, unless
or

具有相同優先級的運算符是滿足結合律的(左結合)。例如,2 3 % 2 等價於 (2 3) % 2。運算符 ^ 例外,^ 滿足的是右結合,例如,2 ^ 3 ^ 2 等價於 2 ^ (3 ^ 2)。

聚合運算

Prometheus還提供了下列內置的聚合操作符,這些操作符作用於瞬時向量。可以將瞬時表達式返回的樣本數據進行聚合,形成一個新的時間序列。

 sum (求和)
 min (最小值)
 max (最大值)
 avg (平均值)
 stddev (標準差)
 stdvar (標準差異)
 count (計數)
 count_values (對value進行計數)
 bottomk (後n條時序)
 topk (前n條時序)
 quantile (分佈統計)

使用聚合操作的語法如下:

&lt;aggr-op&gt;([parameter,] &lt;vector expression&gt;) [without|by (&lt;label list&gt;)]

其中只有count_values, quantile, topk, bottomk支持參數(parameter)。

without用於從計算結果中移除列舉的標籤,而保留其它標籤。by則正好相反,結果向量中只保留列出的標籤,其餘標籤則移除。通過without和by可以按照樣本的問題對數據進行聚合。

sum(http_requests_total) without (instance)
等於:
sum(http_requests_total) by (code,handler,job,method)

如果只需要計算整個應用的HTTP請求總量,可以直接使用表達式:

sum(http_requests_total)
查詢數據的平均值:
avg(http_requests_total)
查詢最靠前的3個值:
topk(3, http_requests_total)

常用函數

Prometheus爲不同的數據類型提供了非常多的計算函數,有個小技巧就是遇到counter數據類型,在做任何操作之前,先套上一個rate()或者increase()函數。下面介紹一些比較常用的函數幫助理解:

increase()函數

該函數配合counter數據類型使用,獲取區間向量中的第一個和最後一個樣本並返回其增長量。如果除以一定時間就可以獲取該時間內的平均增長率:

increase(node_cpu_seconds_total[2m]) / 120 #主機節點最近兩分鐘內的平均CPU使用率

rate()函數

該函數配合counter類型數據使用,取counter在這個時間段中的平均每秒增量。

rate(node_cpu_seconds_total[2m]) #直接計算區間向量在時間窗口內平均增長速率

sum()函數

在實際工作中CPU大多是多核的,而node_cpu會將每個核的數據都單獨顯示出來,我們其實不會關注每個核的單獨情況,而是關心總的CPU情況。使用sum()函數進行求和後可以得出一條總的數據,但sum()是將所有機器的數據都進行了求和,所以還要再使用by (instance)或者by (cluster_name)就可以取出單個服務器或者一組服務器的CPU數據。上面的公式可以進化爲:

sum( increase(node_cpu_seconds_total[1m]) ) #先找出每一個,然後再合併

Topk():該函數可以從大量數據中取出排行前N的數值,N可以自定義。比如監控了100臺服務器的320個CPU,用這個函數就可以查看當前負載較高的那幾個,用於報警:

topk(3, http_requests_total) #統計最靠前的3個值。

predict_linear()函數:對曲線變化速率進行計算,起到一定的預測作用。比如當前這1個小時的磁盤可用率急劇下降,這種情況可能導致磁盤很快被寫滿,這時可以使用該函數,用當前1小時的數據去預測未來幾個小時的狀態,實現提前告警:

predict_linear( node_filesystem_free_bytes{mountpoint="/"}[1h],4*3600 ) &lt; 0 #如果未來4小時後磁盤使用率爲負數就會報警

cpu利用率表達式拆解

1、先把key找出來,比如是爲了查看CPU的使用率,那麼就應該使用node_cpu這個key

2、在node_cpu這個key的基礎上把idle的CPU時間和全部CPU時間過濾出來,使用{}做過濾

node_cpu_seconds_total{ mode='idle' }  #找出空閒CPU的值
node_cpu_seconds_total  #不寫其他參數代表ALL

3、使用increase()函數把1分鐘的數據抓取出來,這個時候取出來的是每個CPU的數據

increase(node_cpu_seconds_totalmode='idle'}[1m])

4、使用sum()函數求和每個CPU的數據,得到單獨一個數據:

sum( increase(node_cpu_seconds_total{mode='idle'}[1m]) )

5、sum()函數雖然把每個CPU的數據進行了求和,但是還把每臺服務器也進行了求和,所有服務器的CPU數據都相同了,還需要進行一次處理。這裏又引出了一個新函數 by (instance)。它會把sum求和到一起的數值按照指定方式進行拆分,instance代表的是機器名。如果不寫by (instance)的話就需要在{}中寫明需要哪個實例的數據。

sum( increase(node_cpu_seconds_total{mode='idle'}[1m]) ) by (instance) #空閒CPU一分鐘增量

6、獲取CPU空閒時間佔比:

sum(increase(node_cpu_seconds_total{mode="idle"}[1m])) by(instance) /sum(increase(node_cpu_seconds_total[1m])) by(instance)

7、CPU的利用率:

1-(sum(increase(node_cpu_seconds_total{mode="idle"}[1m])) by(instance) /sum(increase(node_cpu_seconds_total[1m])) by(instance)) * 100

最終計算可能爲負數,可能好多granafa模板都這樣,當cpu處於多核、低負載的情況下,值的差異會被放大,從而導致出現負數的情況。

幾個比較常用的表達式

1、計算cpu 的使用率:

100 - (avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100)

2、內存的使用率:

(node_memory_MemFree_bytes+node_memory_Cached_bytes+node_memory_Buffers_bytes) / node_memory_MemTotal_bytes * 100

3、磁盤使用率

100 - (node_filesystem_free_bytes{mountpoint="/",fstype=~"ext4|xfs|rootfs"} / node_filesystem_size_bytes{mountpoint="/",fstype=~"ext4|xfs|rootfs"} * 100)

4、主機節點cpu iowait 佔百分比:
avg(irate(node_cpu_seconds_total{mode="iowait"}[5m])) by (instance) * 100

5、系統1分鐘時候的負載:
sum by (instance) (node_load1)

6、網卡流量:
avg(irate(node_network_receive_bytes_total{device=~"eth0|eth1|ens33|ens37"}[1m]))by (environment,instance,device)

參考博客

- alinode 官方鏡像分析並提取 Dockerfile | Web技術試煉地
- hub.docker.com針對docker中的grafana,提供的官方幫助文檔
ncabatoff/process-exporter: Prometheus exporter

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章