<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Docker環(huán)境部署Prometheus+Grafana監(jiān)控系統(tǒng)

          共 41744字,需瀏覽 84分鐘

           ·

          2021-03-17 12:13

          原文鏈接:https://www.jianshu.com/p/dde0dc1761ec

          一、Prometheus簡介

          Prometheus是由SoundCloud開發(fā)的開源監(jiān)控報警系統(tǒng)和時序列數據庫(TSDB)。

          Prometheus使用Go語言開發(fā),是Google BorgMon監(jiān)控系統(tǒng)的開源版本。2016年由Google發(fā)起Linux基金會旗下的原生云基金會(Cloud Native Computing Foundation), 將Prometheus納入其下第二大開源項目。Prometheus目前在開源社區(qū)相當活躍。Prometheus和Heapster(Heapster是K8S的一個子項目,用于獲取集群的性能數據。)相比功能更完善、更全面。Prometheus性能也足夠支撐上萬臺規(guī)模的集群。

          1.系統(tǒng)架構圖

          2.基本原理

          Prometheus的基本原理是通過HTTP協(xié)議周期性抓取被監(jiān)控組件的狀態(tài),任意組件只要提供對應的HTTP接口就可以接入監(jiān)控。不需要任何SDK或者其他的集成過程。這樣做非常適合做虛擬化環(huán)境監(jiān)控系統(tǒng),比如VM、Docker、Kubernetes等。輸出被監(jiān)控組件信息的HTTP接口被叫做exporter 。目前互聯網公司常用的組件大部分都有exporter可以直接使用,比如Varnish、Haproxy、Nginx、MySQL、Linux系統(tǒng)信息(包括磁盤、內存、CPU、網絡等等)。

          其大概的工作流程是:

          1. Prometheus server 定期從配置好的 jobs 或者 exporters 中拉 metrics,或者接收來自 Pushgateway 發(fā)過來的 metrics,或者從其他的 Prometheus server 中拉 metrics。
          2. Prometheus server 在本地存儲收集到的 metrics,并運行已定義好的 alert.rules,記錄新的時間序列或者向 Alertmanager 推送警報。
          3. Alertmanager 根據配置文件,對接收到的警報進行處理,發(fā)出告警。
          4. 在Grafana圖形界面中,可視化查看采集數據。

          3.Prometheus的特性

          • 多維度數據模型。

          • 靈活的查詢語言。

          • 不依賴分布式存儲,單個服務器節(jié)點是自主的。

          • 通過基于HTTP的pull方式采集時序數據。

          • 可以通過中間網關進行時序列數據推送。

          • 通過服務發(fā)現或者靜態(tài)配置來發(fā)現目標服務對象。

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

          4.Prometheus的組件

          • Prometheus Server 主要負責數據采集和存儲,提供PromQL查詢語言的支持。

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

          • Push Gateway 支持臨時性Job主動推送指標的中間網關。

          • Exporters 輸出被監(jiān)控組件信息的HTTP接口。

          • Grafana 監(jiān)控數據展示Web UI。

          5.服務發(fā)現

          由于 Prometheus 是通過 Pull 的方式主動獲取監(jiān)控數據,也就是每隔幾秒鐘去各個target采集一次metric。所以需要手工指定監(jiān)控節(jié)點的列表,當監(jiān)控的節(jié)點增多之后,每次增加節(jié)點都需要更改配置文件,盡管可以使用接口去熱更新配置文件,但仍然非常麻煩,這個時候就需要通過服務發(fā)現(service discovery,SD)機制去解決。

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

          二、部署PrometheusServer

          1. 使用官方鏡像運行

          由于Prometheus官方鏡像沒有開啟熱加載功能,而且時區(qū)相差八小時,所以我們選擇了自己制作鏡像,當然你也可以使用官方的鏡像,提前創(chuàng)建Prometheus配置文件prometheus.yml和Prometheus規(guī)則文件rules.yml,然后通過如下命令掛載到官方鏡像中運行:

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

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

          2. 制作鏡像

          現在我們創(chuàng)建自己的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

          分別創(chuàng)建圖中的目錄,可以看到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 日志文件,需要注意當指定目錄不存在時無法正常啟動,所以需要手動創(chuàng)建目錄(supervisord 會自動創(chuàng)建日志文件)
          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守護文件,容器啟動后執(zhí)行的腳本

          #!/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配置監(jiān)控主機的文件

          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規(guī)則文件,這個也可以等到容器創(chuàng)建后再編寫,這里我們就直接寫好添加到鏡像中

          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 [email protected]
          # 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  LANG=zh_CN.UTF-8 
          RUN  echo "export LANG=zh_CN.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服務,指定了字符集和時區(qū)。

          生成鏡像并運行容器服務

          $ 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

          訪問prometheus Web頁面 IP:9090

          三、部署監(jiān)控組件Exporter

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

          1. 部署主機監(jiān)控組件

          各節(jié)點主機使用主機網絡模式部署主機監(jiān)控組件node-exporter,官方不建議將其部署為Docker容器,因為該node_exporter設計用于監(jiān)控主機系統(tǒng)。需要訪問主機系統(tǒng),而且通過容器的方式部署發(fā)現磁盤數據不太準確。二進制部署就去看項目文檔吧

          $ 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,然后我們就可以定義報警規(guī)則和展示看板了,這部分內容在后面配置Alertmanager和Grafana上會詳細介紹。

          2.部署容器監(jiān)控組件

          各節(jié)點主機部署容器監(jiān)控組件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 端口

          現在我們進入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狀態(tài)為UP,說明正常接收數據。

          3. 部署Redis監(jiān)控組件

          容器部署Redis服務監(jiān)控組件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'   #需要監(jiān)控的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.部署應用監(jiān)控組件

          中間件部署JVM監(jiān)控組件jmx_exporter, 這種方式是適用于代碼中沒有暴露應用metrics信息的服務,無需進行代碼改動,在應用啟動時調用該jar包暴露jmx信息,然后在Prometheus分別指定應用的地址即可。

          1. 首先下載jar :https://github.com/prometheus/jmx_exporter(jmx_prometheus_javaagent-0.11.0.jar )
          2. 下載配置文件,有tomcat和weblogic注意區(qū)分: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. 部署進程監(jiān)控組件

          因為我們容器是使用單獨的網絡部署的,相當于胖容器的方式,所以需要在監(jiān)控的容器中部署process-exporter進程監(jiān)控組件來監(jiān)控容器的進程,

          軟件包下載:

          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服務器)發(fā)送的告警。它負責對它們進行重復數據刪除,分組和路由,以及正確的接收器集成,例如電子郵件,PagerDuty或OpsGenie。它還負責警報的靜默和抑制。

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

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

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

          1. 設置并配置Alertmanager;
          2. 配置Prometheus對Alertmanager訪問;
          3. 在普羅米修斯創(chuàng)建警報規(guī)則;

          2. 部署Alertmanager組件

          首先需要創(chuàng)建Alertmanager的報警通知文件,我這里使用企業(yè)微信報警,其中企業(yè)微信需要申請賬號認證,方式如下:

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

          2. 訪問apps創(chuàng)建第三方應用,點擊創(chuàng)建應用按鈕 -> 填寫應用信息:

          3. 創(chuàng)建報警組,獲取組ID:

          新建alertmanager.yml報警通知文件

          global:
            resolve_timeout: 2m
            smtp_smarthost: smtp.163.com:25
            smtp_from: [email protected]
            smtp_auth_username: [email protected]
            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: '[email protected]'
              send_resolved: true
          - name: 'wechat'
            wechat_configs:
            - corp_id: 'wwd402ce40b4720f24'
              to_party: '2'
              agent_id: '1000002'
              api_secret: '9nmYa4p12OkToCbh_oNc'
              send_resolved: true ## 發(fā)送已解決通知

          參數說明:

          • corp_id: 企業(yè)微信賬號唯一 ID, 可以在我的企業(yè)中查看。

          • to_party: 需要發(fā)送的組。

          • agent_id: 第三方企業(yè)應用的 ID,可以在自己創(chuàng)建的第三方企業(yè)應用詳情頁面查看。

          • api_secret: 第三方企業(yè)應用的密鑰,可以在自己創(chuàng)建的第三方企業(yè)應用詳情頁面查看。

          然后我們創(chuàng)建企業(yè)微信的消息模板,template/wechat.tmpl

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

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

          運行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

          3. 配置報警規(guī)則

          Prometheus的報警規(guī)則通過PromQL語句編寫

          進入Prometheus容器的rules目錄,上面我們制作鏡像的時候已經創(chuàng)建好并掛載到了容器中,現在我們編寫其他的規(guī)則文件

          編寫主機監(jiān)控規(guī)則文件,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 }} ]分區(qū)使用超過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分鐘內平均發(fā)送流量超過10Mbps."
               value: "{{ $value }}3Mbps"

          編寫容器監(jiān)控規(guī)則文件,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分鐘平均發(fā)送流量超過10Mbps."
                value: "{{ $value }}Mbps"

          編寫redis監(jiān)控規(guī)則文件,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 }}"

          編寫服務停止監(jiān)控規(guī)則,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 }}"

          編寫報警規(guī)則可以參考后面Grafana展示看板后的數據展示語句,需要注意的是,我們容器使用的是胖容器的方式,即當作虛擬機來使用,所以需要添加應用和服務停止的Exporter,如果你的容器守護進程直接就是應用的話,只需要監(jiān)控容器的啟停就可以了。

          測試微信報警

          五、Grafana展示組件

          雖然 Prometheus 提供的 Web UI 也可以很好的查看不同指標的視圖,但是這個功能非常簡單,只適合用來調試。要實現一個強大的監(jiān)控系統(tǒng),還需要一個能定制展示不同指標的面板,能支持不同類型的展現方式(曲線圖、餅狀圖、熱點圖、TopN 等),這就是儀表盤(Dashboard)功能。

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

          Grafana是一個用于可視化大型測量數據的開源系統(tǒng),它的功能非常強大,界面也非常漂亮,使用它可以創(chuàng)建自定義的控制面板,你可以在面板中配置要顯示的數據和顯示方式,它支持很多不同的數據源,比如: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

          2. 添加Prometheus數據源

          3. 導入監(jiān)控模板

          使用編號導入模板,Grafana服務需要聯網,否則需要到Grafana模板下載JSON文件導入。

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

          • 主機監(jiān)控展示看板Node-exporter導入 8919 模板
          • 容器監(jiān)控展示看板cadvisor-exporter導入193 模板
          • 應用監(jiān)控展示看板jmx-exporter導入8563 模板
          • Redis監(jiān)控展示看板Redis-exporter導入2751 模板
          • 進程監(jiān)控展示看板Process-exporter導入249 模板

          六、PromQL語句

          七、使用Concul HTTP注冊方式實現服務發(fā)現

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

          1. consul 內部原理

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

          集群內的Consul節(jié)點通過gossip協(xié)議(流言協(xié)議)維護成員關系,也就是說某個節(jié)點了解集群內現在還有哪些節(jié)點,這些節(jié)點是Client還是Server。單個數據中心的流言協(xié)議同時使用TCP和UDP通信,并且都使用8301端口。跨數據中心的流言協(xié)議也同時使用TCP和UDP通信,端口使用8302。

          集群內數據的讀寫請求既可以直接發(fā)到Server,也可以通過Client使用RPC轉發(fā)到Server,請求最終會到達Leader節(jié)點,在允許數據輕微陳舊的情況下,讀請求也可以在普通的Server節(jié)點完成,集群內數據的讀寫和復制都是通過TCP的8300端口完成。

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

          2. 使用docker部署consul 集群

          #啟動第1個Server節(jié)點,集群要求要有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節(jié)點,并加入集群
          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節(jié)點,并加入集群
          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節(jié)點,并加入集群
          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端口:

          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

          4. Prometheus 配置consul 服務發(fā)現

          consul 可以使用的元標簽:

          __meta_consul_address:目標的地址
          __meta_consul_dc:目標的數據中心名稱
          __meta_consul_tagged_address_<key>:每個節(jié)點標記目標的地址鍵值
          __meta_consul_metadata_<key>:目標的每個節(jié)點元數據鍵值
          __meta_consul_node:為目標定義的節(jié)點名稱
          __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       # 執(zhí)行的動作
                - 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頁面

          應用注冊到consul

          在不需要開發(fā)修改代碼的前提下,我們可以使用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

          執(zhí)行腳本注冊到consul

          配置Grafana JVM 監(jiān)控模板

          Load 8563模板


          - END -

          公眾號后臺回復「加群」加入一線高級工程師技術交流群,一起交流進步。

           推薦閱讀 

          31天拿下K8s含金量最高的CKA證書!【本周開班】
          Kubernetes 運維架構師實戰(zhàn)集訓營 
          60道Python常見面試題,做對80% Offer任你挑!
          搞懂 Prometheus 告警神器 Alertmanager
          Zabbix 通過 API 監(jiān)控 Kubernetes
          Kubernetes 學習筆記總結超詳細!
          Kubernetes生產環(huán)境最佳實踐
          高性能 Nginx HTTPS 調優(yōu) - 如何為 HTTPS 提速 30%



          點亮,服務器三年不宕機

          瀏覽 44
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧洲亚洲韩国在线观看 | а√资源新版在线天堂 | 国产美女日逼视频 | 色婷婷视频在线播放 | 日本美女美穴 |