Docker環境部署Prometheus實踐

lhrbest發表於2020-10-27

Docker環境部署Prometheus實踐

一、Prometheus簡介

Prometheus是由SoundCloud開發的開源監控報警系統和時序列資料庫(TSDB)。

Prometheus使用Go語言開發,是Google BorgMon監控系統的開源版本。  2016年由Google發起Linux基金會旗下的原生雲基金會(Cloud Native Computing Foundation), 將Prometheus納入其下第二大開源專案。  Prometheus目前在開源社群相當活躍。  Prometheus和Heapster(Heapster是K8S的一個子專案,用於獲取叢集的效能資料。)相比功能更完善、更全面。Prometheus效能也足夠支撐上萬臺規模的叢集。

1.系統架構圖

Docker環境部署Prometheus實踐  image.png

2.基本原理

Prometheus的基本原理是通過HTTP協議週期性抓取被監控元件的狀態,任意元件只要提供對應的HTTP介面就可以接入監控。不需要任何SDK或者其他的整合過程。這樣做非常適合做虛擬化環境監控系統,比如VM、Docker、Kubernetes等。輸出被監控元件資訊的HTTP介面被叫做exporter 。目前網際網路公司常用的元件大部分都有exporter可以直接使用,比如Varnish、Haproxy、Nginx、MySQL、Linux系統資訊(包括磁碟、記憶體、CPU、網路等等)。

其大概的工作流程是:

  1. Prometheus server 定期從配置好的 jobs 或者 exporters 中拉 metrics,或者接收來自 Pushgateway 發過來的 metrics,或者從其他的 Prometheus server 中拉 metrics。
  2. Prometheus server 在本地儲存收集到的 metrics,並執行已定義好的 alert.rules,記錄新的時間序列或者向 Alertmanager 推送警報。
  3. Alertmanager 根據配置檔案,對接收到的警報進行處理,發出告警。
  4. 在Grafana圖形介面中,視覺化檢視採集資料。

3.Prometheus的特性

  • 多維度資料模型。

  • 靈活的查詢語言。

  • 不依賴分散式儲存,單個伺服器節點是自主的。

  • 通過基於HTTP的pull方式採集時序資料。

  • 可以通過中間閘道器進行時序列資料推送。

  • 通過服務發現或者靜態配置來發現目標服務物件。

  • 支援多種多樣的圖表和介面展示,比如Grafana等。

4.Prometheus的元件

  • Prometheus Server 主要負責資料採集和儲存,提供PromQL查詢語言的支援。

  • Alertmanager 警告管理器,用來進行報警。

  • Push Gateway 支援臨時性Job主動推送指標的中間閘道器。

  • Exporters  輸出被監控元件資訊的HTTP介面。

  • Grafana 監控資料展示Web UI。

5.服務發現

由於 Prometheus 是通過 Pull 的方式主動獲取監控資料,也就是每隔幾秒鐘去各個target採集一次metric。所以需要手工指定監控節點的列表,當監控的節點增多之後,每次增加節點都需要更改配置檔案,儘管可以使用介面去熱更新配置檔案,但仍然非常麻煩,這個時候就需要通過服務發現(service discovery,SD)機制去解決。

Prometheus 支援多種 服務發現機制,可以自動獲取要收集的 targets,包含的服務發現機制包括:azure、consul、dns、ec2、openstack、file、gce、kubernetes、marathon、triton、zookeeper(nerve、serverset),配置方法可以參考手冊的 配置頁面。可以說 SD 機制是非常豐富的,但目前由於開發資源有限,已經不再開發新的 SD 機制,只對基於檔案的 SD 機制進行維護。針對我們現有的系統情況,我們選擇了靜態配置方式。

二、部署PrometheusServer

1. 使用官方映象執行

由於Prometheus官方映象沒有開啟熱載入功能,而且時區相差八小時,所以我們選擇了自己製作映象,當然你也可以使用官方的映象,提前建立Prometheus配置檔案prometheus.yml和Prometheus規則檔案rules.yml,然後通過如下命令掛載到官方映象中執行:

$ docker run -d -p 9090:9090 --name=prometheus \  -v  /root/prometheus/conf/:/etc/prometheus/  \ prom/prometheus

使用官方映象部署可以參考我的這篇文章: Docker部署Prometheus實現微信郵件報警

2. 製作映象

現在我們建立自己的Prometheus映象,當然你也可以直接使用我製作的映象

$ docker pull zhanganmin2017/prometheus:v2.9.0

首先去 Prometheus下載二進位制檔案安裝包解壓到package目錄下,我的Dockerfile目錄結構如下:

$ tree prometheus-2.9.0/ prometheus-2.9.0/ ├── conf │   ├── CentOS7-Base-163.repo │   ├── container-entrypoint │   ├── epel-7.repo │   ├── prometheus-start.conf │   ├── prometheus-start.sh │   ├── prometheus.yml │   ├── rules │   │   └── service_down.yml │   └── supervisord.conf ├── Dockerfile └── package     ├── console_libraries     ├── consoles     ├── LICENSE     ├── NOTICE     ├── prometheus     ├── prometheus.yml     └── promtool 5 directories, 26 files

分別建立圖中的目錄,可以看到conf目錄中有一些名為supervisord的檔案,這是因為在容器中的程式我們選擇使用supervisor進行管理,當然如果不想使用的化可以進行相應的修改。

製作prometheus-start.sh啟動指令碼,Supervisor啟動Prometheus會呼叫該指令碼

#!/bin/bash /bin/prometheus \  --config.file=/data/prometheus/prometheus.yml \  --storage.tsdb.path=/data/prometheus/data \  --web.console.libraries=/data/prometheus/console_libraries \  --web.enable-lifecycle \  --web.console.templates=/data/prometheus/consoles

製作Prometheus-start.conf啟動檔案,Supervisord的配置檔案

[program:prometheus] command=sh /etc/supervisord.d/prometheus-start.sh   ; 程式啟動命令 autostart=false     ; 在supervisord啟動的時候不自動啟動 startsecs=10        ; 啟動10秒後沒有異常退出,就表示程式正常啟動了,預設1秒 autorestart=false   ; 關閉程式退出後自動重啟,可選值:[unexpected,true,false],預設為unexpected,表示程式意外殺死才重啟 startretries=0      ; 啟動失敗自動重試次數,預設是3 user=root            ; 用哪個使用者啟動程式,預設是root redirect_stderr=true            ; 把stderr重定向到stdout,預設false stdout_logfile_maxbytes=20MB  ; stdout 日誌檔案大小,預設是50MB stdout_logfile_backups=30        ; stdout 日誌檔案備份數,預設是10;  # stdout 日誌檔案,需要注意當指定目錄不存在時無法正常啟動,所以需要手動建立目錄(supervisord 會自動建立日誌檔案) stdout_logfile=/data/prometheus/prometheus.log stopasgroup=true killasgroup=tru

製作supervisord.conf啟動檔案

[unix_http_server] file=/var/run/supervisor.sock   ; (the path to the socket file) chmod=0700                       ; sockef file mode (default 0700) [supervisord] logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) childlogdir=/var/log/supervisor            ; ('AUTO' child log dir, default $TEMP) user=root minfds=10240 minprocs=200 [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL  for a unix socket [program:sshd] command=/usr/sbin/sshd -D autostart=true autorestart=true stdout_logfile=/var/log/supervisor/ssh_out.log stderr_logfile=/var/log/supervisor/ssh_err.log [include] files = /etc/supervisord.d/*.conf

製作container-entrypoint守護檔案,容器啟動後執行的指令碼

#!/bin/sh set -x if [ ! -d "/data/prometheus" ];then     mkdir -p /data/prometheus/data fi mv /usr/local/src/* /data/prometheus/ exec /usr/bin/supervisord -n exit

在conf目錄下新建Prometheus.yml配置檔案,這個是Prometheus配置監控主機的檔案

global:   scrape_interval:   60s # Set the scrape interval to every 15 seconds. Default is every 1 minute.   evaluation_interval: 60s # Evaluate rules every 15 seconds. The default is every 1 minute. alerting:   alertmanagers:   - static_configs:     - targets: [ '192.168.133.110:9093'] rule_files:   - "rules/host_sys.yml" scrape_configs:   - job_name: 'Host'     static_configs:       - targets: ['10.1.250.36:9100']         labels:           appname: 'DEV01_250.36'   - job_name: 'prometheus'     static_configs:       - targets: [ '10.1.133.210:9090']         labels:           appname: 'Prometheus'

在conf目錄下新建rules目錄,編寫service_down.yml規則檔案,這個也可以等到容器建立後再編寫,這裡我們就直接寫好新增到映象中

groups: - name: servicedown   rules:   - alert: InstanceDown     expr: up == 0     for: 1m     labels:       name: instance       severity: Critical     annotations:       summary: " {{ $labels.appname }}"       description: " 服務停止執行 "       value: "{{ $value }}"

製作dockerfile 映象檔案

FROM docker.io/centos:7 MAINTAINER from zhanmin@1an.com # install repo RUN  rm -rf  /etc/yum.repos.d/*.repo ADD  conf/CentOS7-Base-163.repo /etc/yum.repos.d/ ADD  conf/epel-7.repo           /etc/yum.repos.d/ # yum install RUN yum install -q -y  openssh-server openssh-clients  net-tools \   vim  supervisor && yum clean all # install sshd RUN  ssh-keygen -q -N "" -t rsa -f /etc/ssh/ssh_host_rsa_key \   &&  ssh-keygen -q -N "" -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key \   &&  ssh-keygen -q -N "" -t ed25519 -f /etc/ssh/ssh_host_ed25519_key \   &&  sed -i 's/#UseDNS yes/UseDNS no/g' /etc/ssh/sshd_config # UTF-8 and CST +0800 ENV.UTF-8  RUN  echo "export.UTF-8" >> /etc/profile.d/lang.sh \     &&  ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \     && localedef -c -f UTF-8 -i zh_CN zh_CN.utf8 # install Prometheus COPY  package/prometheus                            /bin/prometheus COPY  package/promtool                              /bin/promtool COPY  package/console_libraries/                    /usr/local/src/console_libraries/ COPY  package/consoles/                             /usr/local/src/consoles/ COPY  conf/prometheus.yml               /usr/local/src/prometheus.yml    COPY  conf/rules/                                   /usr/local/src/rules/ # create user RUN  echo "root:123456" | chpasswd  # supervisord ADD  conf/supervisord.conf                               /etc/supervisord.conf ADD  conf/prometheus-start.conf                          /etc/supervisord.d/prometheus-start.conf ADD  conf/container-entrypoint                         /container-entrypoint ADD  conf/prometheus-start.sh                         /etc/supervisord.d/prometheus-start.sh RUN  chmod +x /container-entrypoint # cmd CMD  ["/container-entrypoint"]

Dockerfile中安裝了supervisor程式管理工具和SSH服務,指定了字符集和時區。

生成映象並執行容器服務

$ docker build -t zhanganmin2017/prometheus:v2.9.0 . $ docker run -itd  -h prometheus139-210 -m 8g  --cpuset-cpus=28-31  --name=prometheus139-210 --network trust139  --ip=10.1.133.28  -v /data/works/prometheus139-210:/data  192.168.166.229/1an/prometheus:v2.9.0 $ docker exec -it  prometheus139-210  /bin/bash $ supervisorctl  start  prometheus

訪問prometheus Web頁面 IP:9090


    Docker環境部署Prometheus實踐  www.unmin.club

三、部署監控元件Exporter

Prometheus 是使用 Pull 的方式來獲取指標資料的,要讓 Prometheus 從目標處獲得資料,首先必須在目標上安裝指標收集的程式,並暴露出 HTTP 介面供 Prometheus 查詢,這個指標收集程式被稱為 Exporter ,不同的指標需要不同的 Exporter 來收集,目前已經有大量的 Exporter 可供使用,幾乎囊括了我們常用的各種系統和軟體,官網列出了一份常用 Exporter 的清單 ,各個 Exporter 都遵循一份埠約定,避免埠衝突,即從 9100 開始依次遞增,這裡是完整的 Exporter 埠列表 。另外值得注意的是,有些軟體和系統無需安裝 Exporter,這是因為他們本身就提供了暴露 Prometheus 格式的指標資料的功能,比如 Kubernetes、Grafana、Etcd、Ceph 等。

1. 部署主機監控元件

各節點主機使用主機網路模式部署主機監控元件 node-exporter,官方不建議將其部署為Docker容器,因為該node_exporter設計用於監控主機系統。需要訪問主機系統,而且通過容器的方式部署發現磁碟資料不太準確。二進位制部署就去看專案文件吧

$ docker run -d \   --net="host" \   --pid="host" \   -v "/:/host:ro,rslave" \   quay.io/prometheus/node-exporter \   --path.rootfs=/host

容器正常執行後,進入Prometheus容器,在Prometheus.yml 檔案中新增node-exporter元件地址

$ docker exec -it  prometheus-133-210  /bin/bash $ vim /data/prometheus/prometheus.yml global:   scrape_interval:   60s # Set the scrape interval to every 15 seconds. Default is every 1 minute.   evaluation_interval: 60s # Evaluate rules every 15 seconds. The default is every 1 minute. rule_files:   - "rules/service_down.yml" scrape_configs:   - job_name: 'Host'     static_configs:       - targets: ['10.1.250.36:9100']  #node-exporter地址         labels:           appname: 'DEV01_250.36' #新增的標籤   - job_name: 'prometheus'     static_configs:       - targets: [ '10.2.139.210:9090']         labels:           appname: 'prometheus'

熱載入更新Prometheus

$  curl -X POST http://10.1.133.210:9090/-/reload

檢視Prometheus的web頁面已經可以看到node-exporter,然後我們就可以定義報警規則和展示看板了,這部分內容在後面配置Alertmanager和Grafana上會詳細介紹。


    Docker環境部署Prometheus實踐  image.png

2.部署容器監控元件

各節點主機部署容器監控元件cadvisor-exporter,我這邊Docker網路使用的macvlan方式,所以直接給容器分配了IP地址。

# docker run -d  -h cadvisor139-216  --name=cadvisor139-216  --net=none -m 8g   --cpus=4   --ip=10.1.139.216   --volume=/:/rootfs:ro   --volume=/var/run:/var/run:rw --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:ro  --volume=/dev/disk/:/dev/disk:ro     google/cadvisor:latest

同樣的,容器正常執行後,我們訪問Cadvisor的Web頁面 IP+8080 埠


    Docker環境部署Prometheus實踐  image.png

現在我們進入Prometheus容器,在prometheus.yml主機檔案中新增cadvisor元件

-----------   - job_name: 'Cadvisor'     static_configs:       - targets: [ '10.1.139.216:8080']         labels:           appname: 'DEV_Cadvisor01'

熱載入更新Prometheus

$  curl -X POST http://10.1.133.210:9090/-/reload

可以看到,Prometheus新增的cadvisor狀態為UP,說明正常接收資料。


    Docker環境部署Prometheus實踐  image.png

3. 部署Redis監控元件

容器部署Redis服務監控元件 redis_exporter--redis.passwd指定認證口令,如果你的redis訪問沒有密碼那麼就無需指定後面引數。

$ docker run -d  -h  redis_exporter139-218 --name redis_exporter139-218 --network trust139 --ip=10.1.139.218  -m 8g  --cpus=4  oliver006/redis_exporter --redis.passwd  123456

在prometheus.yml 新增redis-exporter

--------- - job_name: 'Redis-exporter'   #exporter地址     static_configs:       - targets: ['10.2.139.218:9121'']         labels:           appname: 'redis-exporter'   - job_name: 'RedisProxy'   #需要監控的redis地址     static_configs:       - targets:         - redis://10.2.139.70:6379         - redis://10.2.139.71:6379         labels:           appname: RedisProxy     metrics_path: /scrape     relabel_configs:       - source_labels: [__address__]         target_label: __param_target       - source_labels: [__param_target]         target_label: instance       - target_label: __address__         replacement: 10.2.139.218:9121

然後熱載入更新,步驟同上。

4.部署應用監控元件

中介軟體部署JVM監控元件 jmx_exporter, 這種方式是適用於程式碼中沒有暴露應用metrics資訊的服務,無需進行程式碼改動,在應用啟動時呼叫該jar包暴露jmx資訊,然後在Prometheus分別指定應用的地址即可。

  1. 首先下載jar : https://github.com/prometheus/jmx_exporter (jmx_prometheus_javaagent-0.11.0.jar )
  2. 下載配置檔案,有tomcat和weblogic注意區分: https://github.com/prometheus/jmx_exporter/tree/master/example_configs
  3. 然後在中介軟體啟動引數新增以下內容,指定配置檔案和jar包的路徑:

CATALINA_OPTS="-javaagent:/app/tomcat-8.5.23/lib/jmx_prometheus_javaagent-0.11.0.jar=12345:/app/tomcat-8.5.23/conf/config.yaml"

上面我指定暴露metrics資訊的埠為12345,所以我們在prometheus.yml檔案中新增即可:

---------   - job_name: 'MIDL'     static_configs:       - targets: ['192.168.166.18:12345','192.168.166.19:12345']         labels:           appname: 'ORDER'       - targets: ['10.2.139.111:12345','10.2.139.112:12345']         labels:           appname: 'WEB'

其他步驟同上,Prometheus熱載入更新即可。

5. 部署程式監控元件

因為我們容器是使用單獨的網路部署的,相當於胖容器的方式,所以需要在監控的容器中部署process-exporter程式監控元件來監控容器的程式,

軟體包下載:

wget https://github.com/ncabatoff/process-exporter/releases/download/v0.5.0/process-exporter-0.5.0.linux-amd64.tar.gz

配置檔案:process-name.yaml

process_names:   - name: "{{.Matches}}"     cmdline:     - 'redis-shake'  #匹配程式,支援正則

啟動引數:

$ nohup ./process-exporter -config.path process-name.yaml &

在Prometheus.yml 新增該容器的IP地址,埠號為9256

-----------   - job_name: 'process'     static_configs:       - targets: [ '10.2.139.186:9256']         labels:           appname: 'Redis-shake'

ok,現在我們熱載入更新Prometheus的主機檔案

$ curl -X POSThttp://10.2.139.210:9090/-/reload

四、部署Alertmanager報警元件

1. Alertmanager 概述

Alertmanager處理客戶端應用程式(如Prometheus伺服器)傳送的告警。 它負責對它們進行重複資料刪除,分組和路由,以及正確的接收器整合,例如電子郵件,PagerDuty或OpsGenie。 它還負責警報的靜默和抑制。

以下描述了Alertmanager實現的核心概念。 請參閱配置文件以瞭解如何更詳細地使用它們。

  • 分組(Grouping)
    分組將類似性質的告警分類為單個通知。 這在大型中斷期間尤其有用,因為許多系統一次失敗,並且可能同時發射數百到數千個警報。
    示例:發生網路分割槽時,群集中正在執行數十或數百個服務例項。 一半的服務例項無法再訪問資料庫。 Prometheus中的告警規則配置為在每個服務例項無法與資料庫通訊時傳送告警。 結果,數百個告警被髮送到Alertmanager。
    作為使用者,只能想要獲得單個頁面,同時仍能夠確切地看到哪些服務例項受到影響。 因此,可以將Alertmanager配置為按群集和alertname對警報進行分組,以便傳送單個緊湊通知。
    這些通知的接收器通過配置檔案中的路由樹配置告警的分組,定時的進行分組通知。
  • 抑制(Inhibition)
    如果某些特定的告警已經觸發,則某些告警需要被抑制。
    示例:如果某個告警觸發,通知無法訪問整個叢集。 Alertmanager可以配置為在該特定告警觸發時將與該叢集有關的所有其他告警靜音。 這可以防止通知數百或數千個與實際問題無關的告警觸發。
  • 靜默(SILENCES)
    靜默是在給定時間內簡單地靜音告警的方法。 基於匹配器配置靜默,就像路由樹一樣。 檢查告警是否匹配或者正規表示式匹配靜默。 如果匹配,則不會傳送該告警的通知。在Alertmanager的Web介面中可以配置靜默。
  • 客戶端行為(Client behavior)
    Alertmanager對其客戶的行為有特殊要求。 這些僅適用於不使用Prometheus傳送警報的高階用例。     #製作映象方式和Prometheus類似,稍作更改即可,此步省略。

設定警報和通知的主要步驟如下:

  1. 設定並配置Alertmanager;
  2. 配置Prometheus對Alertmanager訪問;
  3. 在普羅米修斯建立警報規則;

2. 部署Alertmanager元件

首先需要建立Alertmanager的報警通知檔案,我這裡使用企業微信報警,其中企業微信需要申請賬號認證,方式如下:

  1. 訪問 網站 註冊企業微信賬號(不需要企業認證)。

  2. 訪問 apps 建立第三方應用,點選建立應用按鈕 -> 填寫應用資訊:

  3. 建立報警組,獲取組ID:

Docker環境部署Prometheus實踐  image.png     Docker環境部署Prometheus實踐  image.png     Docker環境部署Prometheus實踐  image.png

新建alertmanager.yml報警通知檔案

global:   resolve_timeout: 2m   smtp_smarthost: smtp.163.com:25   smtp_from: 15xxx@163.com   smtp_auth_username: 15xxxx@163.com   smtp_auth_password: zxxx templates:   - '/data/alertmanager/conf/template/wechat.tmpl' route:   group_by: ['alertname_wechat']   group_wait: 1s   group_interval: 1s   receiver: 'wechat'   repeat_interval: 1h   routes:   - receiver: wechat     match_re:       serverity: wechat receivers: - name: 'email'   email_configs:   - to: '8xxxxx@qq.com'     send_resolved: true - name: 'wechat'   wechat_configs:   - corp_id: 'wwd402ce40b4720f24'     to_party: '2'     agent_id: '1000002'     api_secret: '9nmYa4p12OkToCbh_oNc'     send_resolved: true ## 傳送已解決通知

引數說明:

  • corp_id: 企業微信賬號唯一 ID, 可以在我的企業中檢視。

  • to_party: 需要傳送的組。

  • agent_id: 第三方企業應用的 ID,可以在自己建立的第三方企業應用詳情頁面檢視。

  • api_secret: 第三方企業應用的金鑰,可以在自己建立的第三方企業應用詳情頁面檢視。

然後我們建立企業微信的訊息模板,template/wechat.tmpl

{{ define "wechat.default.message" }} {{ range $i, $alert :=.Alerts }} 【系統報警】 告警狀態:{{   .Status }} 告警級別:{{ $alert.Labels.severity }} 告警應用:{{ $alert.Annotations.summary }} 告警詳情:{{ $alert.Annotations.description }} 觸發閥值:{{ $alert.Annotations.value }} 告警主機:{{ $alert.Labels.instance }} 告警時間:{{ $alert.StartsAt.Format "2006-01-02 15:04:05" }} {{ end }} {{ end }}

這個報警的模板其中的值是在Prometheus觸發的報警資訊中提取的,所以你可以根據自己的定義進行修改。

執行Alertmanager容器

$ docker run -d -p 9093:9093 --name alertmanager  -m 8g  --cpus=4 -v /opt/alertmanager.yml:/etc/alertmanager/alertmanager.yml -v /opt/template:/etc/alertmanager/template  docker.io/prom/alertmanager:latest

容器執行完成後檢視web頁面 IP:9093


    Docker環境部署Prometheus實踐  image.png

3. 配置報警規則

Prometheus的報警規則通過 PromQL語句編寫

進入Prometheus容器的rules目錄,上面我們製作映象的時候已經建立好並掛載到了容器中,現在我們編寫其他的規則檔案

編寫主機監控規則檔案,rules/host_sys.yml

cat host_sys.yml groups: - name: Host  rules:  - alert: HostMemory Usage    expr: (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Buffers_bytes + node_memory_Cached_bytes)) / node_memory_MemTotal_bytes * 100 >  90    for: 1m    labels:      name: Memory      severity: Warning    annotations:      summary: " {{ $labels.appname }} "      description: "宿主機記憶體使用率超過90%."      value: "{{ $value }}"  - alert: HostCPU Usage    expr: sum(avg without (cpu)(irate(node_cpu_seconds_total{mode!='idle'}[5m]))) by (instance,appname) > 0.8    for: 1m    labels:      name: CPU      severity: Warning    annotations:      summary: " {{ $labels.appname }} "      description: "宿主機CPU使用率超過80%."      value: "{{ $value }}"  - alert: HostLoad    expr: node_load5 > 20    for: 1m    labels:      name: Load      severity: Warning    annotations:      summary: "{{ $labels.appname }} "      description: " 主機負載5分鐘超過20."      value: "{{ $value }}"  - alert: HostFilesystem Usage    expr: (node_filesystem_size_bytes-node_filesystem_free_bytes)/node_filesystem_size_bytes*100>80    for: 1m    labels:      name: Disk      severity: Warning    annotations:      summary: " {{ $labels.appname }} "      description: " 宿主機 [ {{ $labels.mountpoint }} ]分割槽使用超過80%."      value: "{{ $value }}%"  - alert: HostDiskio writes    expr: irate(node_disk_writes_completed_total{job=~"Host"}[1m]) > 10    for: 1m    labels:      name: Diskio      severity: Warning    annotations:      summary: " {{ $labels.appname }} "      description: " 宿主機 [{{ $labels.device }}]磁碟1分鐘平均寫入IO負載較高."      value: "{{ $value }}iops"  - alert: HostDiskio reads    expr: irate(node_disk_reads_completed_total{job=~"Host"}[1m]) > 10    for: 1m    labels:      name: Diskio      severity: Warning    annotations:      summary: " {{ $labels.appname }} "      description: " 宿機 [{{ $labels.device }}]磁碟1分鐘平均讀取IO負載較高."      value: "{{ $value }}iops"  - alert: HostNetwork_receive    expr: irate(node_network_receive_bytes_total{device!~"lo|bond[0-9]|cbr[0-9]|veth.*|virbr.*|ovs-system"}[5m]) / 1048576  > 10    for: 1m    labels:      name: Network_receive      severity: Warning    annotations:      summary: " {{ $labels.appname }} "      description: " 宿主機 [{{ $labels.device }}] 網路卡5分鐘平均接收流量超過10Mbps."      value: "{{ $value }}3Mbps"  - alert: hostNetwork_transmit    expr: irate(node_network_transmit_bytes_total{device!~"lo|bond[0-9]|cbr[0-9]|veth.*|virbr.*|ovs-system"}[5m]) / 1048576  > 10    for: 1m    labels:      name: Network_transmit      severity: Warning    annotations:      summary: " {{ $labels.appname }} "      description: " 宿主機 [{{ $labels.device }}] 網路卡5分鐘內平均傳送流量超過10Mbps."      value: "{{ $value }}3Mbps"

編寫容器監控規則檔案,rules/container_sys.yml

groups: - name: Container   rules:   - alert: ContainerCPU     expr: (sum by(name,instance) (rate(container_cpu_usage_seconds_total{image!=""}[5m]))*100) > 200     for: 1m     labels:       name: CPU_Usage       severity: Warning     annotations:       summary: "{{ $labels.name }} "       description: " 容器CPU使用超200%."       value: "{{ $value }}%"   - alert: Memory Usage     expr: (container_memory_usage_bytes{name=~".+"} - container_memory_cache{name=~".+"})  / container_spec_memory_limit_bytes{name=~".+"}   * 100 > 200     for: 1m     labels:       name: Memory       severity: Warning     annotations:       summary: "{{ $labels.name }} "       description: " 容器記憶體使用超過200%."       value: "{{ $value }}%"   - alert: Network_receive     expr: irate(container_network_receive_bytes_total{name=~".+",interface=~"eth.+"}[5m]) / 1048576  > 10     for: 1m     labels:       name: Network_receive       severity: Warning     annotations:       summary: "{{ $labels.name }} "       description: "容器 [{{ $labels.device }}] 網路卡5分鐘平均接收流量超過10Mbps."       value: "{{ $value }}Mbps"   - alert: Network_transmit     expr: irate(container_network_transmit_bytes_total{name=~".+",interface=~"eth.+"}[5m]) / 1048576  > 10     for: 1m     labels:       name: Network_transmit       severity: Warning     annotations:       summary: "{{ $labels.name }} "       description: "容器 [{{ $labels.device }}] 網路卡5分鐘平均傳送流量超過10Mbps."       value: "{{ $value }}Mbps"

編寫redis監控規則檔案,redis_check.yml

groups: - name: redisdown   rules:   - alert: RedisDown     expr: redis_up == 0     for: 1m     labels:       name: instance       severity: Critical     annotations:       summary: " {{ $labels.alias }}"       description: " 服務停止執行 "       value: "{{ $value }}"   - alert: Redis linked too many clients     expr: redis_connected_clients / redis_config_maxclients * 100 > 80     for: 1m     labels:       name: instance       severity: Warning     annotations:       summary: " {{ $labels.alias }}"       description: " Redis連線數超過最大連線數的80%. "       value: "{{ $value }}"   - alert: Redis linked     expr: redis_connected_clients / redis_config_maxclients * 100 > 80     for: 1m     labels:       name: instance       severity: Warning     annotations:       summary: " {{ $labels.alias }}"       description: " Redis連線數超過最大連線數的80%. "       value: "{{ $value }}"

編寫服務停止監控規則,rules/service_down.yml

  - alert: ProcessDown     expr: namedprocess_namegroup_num_procs  == 0     for: 1m     labels:       name: instance       severity: Critical     annotations:       summary: " {{ $labels.appname }}"       description: " 程式停止執行 "       value: "{{ $value }}"   - alert: Grafana down     expr: absent(container_last_seen{name=~"grafana.+"} ) == 1     for: 1m     labels:       name: grafana       severity: Critical     annotations:       summary: "Grafana"       description: "Grafana容器停止執行"       value: "{{ $value }}"

編寫報警規則可以參考後面Grafana展示看板後的資料展示語句,需要注意的是,我們容器使用的是胖容器的方式,即當作虛擬機器來使用,所以需要新增應用和服務停止的Exporter,如果你的容器守護程式直接就是應用的話,只需要監控容器的啟停就可以了。

測試微信報警

Docker環境部署Prometheus實踐  image.png

五、Grafana展示元件

雖然 Prometheus 提供的 Web UI 也可以很好的檢視不同指標的檢視,但是這個功能非常簡單,只適合用來除錯。要實現一個強大的監控系統,還需要一個能定製展示不同指標的皮膚,能支援不同型別的展現方式(曲線圖、餅狀圖、熱點圖、TopN 等),這就是儀表盤(Dashboard)功能。

Prometheus 開發了一套儀表盤系統 PromDash ,不過很快這套系統就被廢棄了,官方開始推薦使用 Grafana 來對 Prometheus 的指標資料進行視覺化,這不僅是因為 Grafana 的功能非常強大,而且它和 Prometheus 可以完美的無縫融合。

Grafana 是一個用於視覺化大型測量資料的開源系統,它的功能非常強大,介面也非常漂亮,使用它可以建立自定義的控制皮膚,你可以在皮膚中配置要顯示的資料和顯示方式,它 支援很多不同的資料來源 ,比如:Graphite、InfluxDB、OpenTSDB、Elasticsearch、Prometheus 等,而且它也 支援眾多的外掛

1. 部署Grafana服務容器

$ docker run -d -h grafana139-211  -m 8g   --network trust139  --ip=10.2.139.211   --cpus=4 --name=grafana139-211 -e "GF_SERVER_ROOT_URL=http://10.2.139.211"   -e "GF_SECURITY_ADMIN_PASSWORD=passwd"    grafana/grafana

執行後訪問IP:3000,user:admin pass:passwd


    Docker環境部署Prometheus實踐  image.png

2.  新增Prometheus資料來源

Docker環境部署Prometheus實踐  image.png

3. 匯入監控模板

使用編號匯入模板,Grafana服務需要聯網,否則需要到 Grafana模板下載JSON檔案匯入。

Docker環境部署Prometheus實踐  image.png

下面是我使用的幾個模板,匯入後可以根據自己的情況定義變數值


    Docker環境部署Prometheus實踐  image.png

主機監控展示看板Node-exporter匯入 8919 模板
容器監控展示看板cadvisor-exporter匯入193 模板
應用監控展示看板jmx-exporter匯入8563 模板
Redis監控展示看板Redis-exporter匯入2751 模板
程式監控展示看板Process-exporter匯入249 模板

六、PromQL語句

七、使用Concul HTTP註冊方式實現服務發現

一般是用服務發現需要應用需要服務註冊,我們這邊因為微服務改造還沒完成,還有一些tomcat和weblogic中介軟體,而且選用的註冊中心是Eurka,所以為了在程式碼不改動的情況下使用服務發現,選擇了concul 作為註冊中心,因為是consul是可以通過http方式註冊的。

1. consul 內部原理

Docker環境部署Prometheus實踐  unmin.club.png

Consul分為Client和Server兩種節點(所有的節點也被稱為Agent),Server節點儲存資料,Client負責健康檢查及轉發資料請求到Server;Server節點有一個Leader和多個Follower,Leader節點會將資料同步到Follower,Server的數量推薦是3個或者5個,在Leader掛掉的時候會啟動選舉機制產生一個新的Leader。

叢集內的Consul節點通過gossip協議(流言協議)維護成員關係,也就是說某個節點了解叢集內現在還有哪些節點,這些節點是Client還是Server。單個資料中心的流言協議同時使用TCP和UDP通訊,並且都使用8301埠。跨資料中心的流言協議也同時使用TCP和UDP通訊,埠使用8302。

叢集內資料的讀寫請求既可以直接發到Server,也可以通過Client使用RPC轉發到Server,請求最終會到達Leader節點,在允許資料輕微陳舊的情況下,讀請求也可以在普通的Server節點完成,叢集內資料的讀寫和複製都是通過TCP的8300埠完成。

具體consul的原理及架構請訪問: http://blog.didispace.com/consul-service-discovery-exp/

2. 使用docker部署consul 叢集

#啟動第1個Server節點,叢集要求要有3個Server,將容器8500埠對映到主機8900埠,同時開啟管理介面 docker run -d --name=consul1 -p 8900:8500 -e CONSUL_BIND_INTERFACE=eth0 consul agent --server=true --bootstrap-expect=3 --client=0.0.0.0 -ui   #啟動第2個Server節點,並加入叢集 docker run -d --name=consul2 -e CONSUL_BIND_INTERFACE=eth0 consul agent --server=true --client=0.0.0.0 --join 172.17.0.1   #啟動第3個Server節點,並加入叢集 docker run -d --name=consul3 -e CONSUL_BIND_INTERFACE=eth0 consul agent --server=true --client=0.0.0.0 --join 172.17.0.2   #啟動第4個Client節點,並加入叢集 docker run -d --name=consul4 -e CONSUL_BIND_INTERFACE=eth0 consul agent --server=false --client=0.0.0.0 --join 172.17.0.2

瀏覽器訪問容器對映的8900埠:


    Docker環境部署Prometheus實踐  unmin.club

3. 服務註冊到Consul

使用HTTP API 方式註冊node-exporter服務到Consul

  curl -X PUT -d '{"id": "192.168.16.173","name": "node-exporter","address": "192.168.16.173","port": ''9100,"tags": ["DEV"], "checks": [{"http": "http://192.168.16.173:9100/","interval": "5s"}]}'     http://172.17.0.4:8500/v1/agent/service/register

解註冊:

curl --request PUT http://172.17.0.4:8500/v1/agent/service/deregister/192.168.166.14

註冊多個服務到consul,使用指令碼:

#!/bin/bash  all_IP=`cat  /opt/ip` name=cadvisor port=9100 for  I  in $all_IP do         curl -X PUT -d '{"id": "'$I'","name": "'$name'","address": "'$I'","port": '$port',"tags": ["cadvisor"], "checks": [{"http": "http://'$I':'$port'/","interval": "5s"}]}'     http://172.17.0.4:8500/v1/agent/service/register done

    Docker環境部署Prometheus實踐  unmin.club

4. Prometheus 配置consul 服務發現

consul 可以使用的元標籤:

__meta_consul_address:目標的地址 __meta_consul_dc:目標的資料中心名稱 __meta_consul_tagged_address_<key>:每個節點標記目標的地址鍵值 __meta_consul_metadata_<key>:目標的每個節點後設資料鍵值 __meta_consul_node:為目標定義的節點名稱 __meta_consul_service_address:目標的服務地址 __meta_consul_service_id:目標的服務ID __meta_consul_service_metadata_<key>:目標的每個服務後設資料鍵值 __meta_consul_service_port:目標的服務埠 __meta_consul_service:目標所屬服務的名稱 __meta_consul_tags:標記分隔符連線的目標的標記列表

修改Prometheus.yml 檔案,使用relabel將consul的元標籤重寫便於檢視

  - job_name: 'consul'     consul_sd_configs:       - server: '192.168.16.173:8900'         services: []  #匹配所有service     relabel_configs:       - source_labels: [__meta_consul_service] #service 源標籤         regex: "consul"  #匹配為"consul" 的service         action: drop       # 執行的動作       - source_labels: [__meta_consul_service]  # 將service 的label重寫為appname         target_label: appname       - source_labels: [__meta_consul_service_address]         target_label: instance       - source_labels: [__meta_consul_tags]         target_label:  job

Prometheus 熱載入更新

curl -X POST http://192.168.16.173:9090/-/reload

訪問Prometheus web頁面


    Docker環境部署Prometheus實踐  unmin.club

應用註冊到consul

在不需要開發修改程式碼的前提下,我們可以使用Prometheus的jmx-exporter收集應用的相關指標,在應用中介軟體tomcat/weblogic等呼叫jmx-exporter,具體方式檢視 https://www.jianshu.com/p/dfd6ba5206dc

啟動應用後會啟動12345埠暴露jvm資料,現在我們要做的就是將這個埠註冊到Consul上,然後Prometheus會從consul 拉取應用主機。

使用指令碼實現

 $ cat     ip TEST        192.168.166.10      192.168.166.11 UNMIN       192.168.166.12      192.168.166.13 ---------------         $ cat consul.sh #!/bin/bash port=12345 while read app do     echo ${app}     app_tmp=(${app})     echo ${app_tmp[0]}     length=${#app_tmp[@]}     echo ${length}     for((k=1;k<${length};k++));     do         echo ${app_tmp[k]}     curl -X PUT -d '{"id": "'${app_tmp[k]}'","name": "'${app_tmp[0]}'","address": "'${app_tmp[k]}'","port": '$port',"tags": ["MIDL"],"checks": [{"http": "http://'${app_tmp[k]}':'$port'/","interval": "5s"}]}'     http://172.17.0.4:8500/v1/agent/service/register                 done done < ip

執行指令碼註冊到consul


    Docker環境部署Prometheus實踐  unmin.club

配置Grafana JVM 監控模板

Load 8563模板

Docker環境部署Prometheus實踐  unmin.club

作者:Anson前行
連結:https://www.jianshu.com/p/dde0dc1761ec
來源:簡書






About Me

........................................................................................................................

● 本文作者:小麥苗,部分內容整理自網路,若有侵權請聯絡小麥苗刪除

● 本文在個人微 信公眾號( DB寶)上有同步更新

● QQ群號: 230161599 、618766405,微信群私聊

● 個人QQ號(646634621),微 訊號(db_bao),註明新增緣由

● 於 2020年10月 在西安完成

● 最新修改時間:2020年10月

● 版權所有,歡迎分享本文,轉載請保留出處

........................................................................................................................

小麥苗的微店https://weidian.com/s/793741433?wfr=c&ifr=shopdetail

● 小麥苗出版的資料庫類叢書: http://blog.itpub.net/26736162/viewspace-2142121/

小麥苗OCP、OCM、高可用、DBA學習班http://blog.itpub.net/26736162/viewspace-2148098/

● 資料庫筆試面試題庫及解答: http://blog.itpub.net/26736162/viewspace-2134706/

........................................................................................................................

請掃描下面的二維碼來關注小麥苗的微 信公眾號( DB寶)及QQ群(230161599、618766405)、新增小麥苗微 信(db_bao), 學習最實用的資料庫技術。

........................................................................................................................

 

 



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2730160/,如需轉載,請註明出處,否則將追究法律責任。

相關文章