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

        共 41705字,需瀏覽 84分鐘

         ·

        2021-04-22 08:25

        點擊上方“程序員大白”,選擇“星標(biāo)”公眾號

        重磅干貨,第一時間送達(dá)

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

        文章轉(zhuǎn)自:DevOps技術(shù)棧

        一、Prometheus簡介

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

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

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

        2.基本原理

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

        其大概的工作流程是:

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

        3.Prometheus的特性

        • 多維度數(shù)據(jù)模型。

        • 靈活的查詢語言。

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

        • 通過基于HTTP的pull方式采集時序數(shù)據(jù)。

        • 可以通過中間網(wǎng)關(guān)進(jìn)行時序列數(shù)據(jù)推送。

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

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

        4.Prometheus的組件

        • Prometheus Server 主要負(fù)責(zé)數(shù)據(jù)采集和存儲,提供PromQL查詢語言的支持。

        • Alertmanager 警告管理器,用來進(jìn)行報警。

        • Push Gateway 支持臨時性Job主動推送指標(biāo)的中間網(wǎng)關(guān)。

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

        • Grafana 監(jiān)控數(shù)據(jù)展示W(wǎng)eb UI。

        5.服務(wù)發(fā)現(xiàn)

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

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

        二、部署PrometheusServer

        1. 使用官方鏡像運行

        由于Prometheus官方鏡像沒有開啟熱加載功能,而且時區(qū)相差八小時,所以我們選擇了自己制作鏡像,當(dāng)然你也可以使用官方的鏡像,提前創(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實現(xiàn)微信郵件報警。

        2. 制作鏡像

        現(xiàn)在我們創(chuàng)建自己的Prometheus鏡像,當(dāng)然你也可以直接使用我制作的鏡像

        $ docker pull zhanganmin2017/prometheus:v2.9.0  

        首先去Prometheus下載二進(jìn)制文件安裝包解壓到package目錄下,我的Dockerfile目錄結(jié)構(gòu)如下:

        $ 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的文件,這是因為在容器中的進(jìn)程我們選擇使用supervisor進(jìn)行管理,當(dāng)然如果不想使用的化可以進(jìn)行相應(yīng)的修改。

        制作prometheus-start.sh啟動腳本,Supervisor啟動Prometheus會調(diào)用該腳本

        #!/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秒后沒有異常退出,就表示進(jìn)程正常啟動了,默認(rèn)1秒
        autorestart=false   ; 關(guān)閉程序退出后自動重啟,可選值:[unexpected,true,false],默認(rèn)為unexpected,表示進(jìn)程意外殺死才重啟
        startretries=0      ; 啟動失敗自動重試次數(shù),默認(rèn)是3
        user=root            ; 用哪個用戶啟動進(jìn)程,默認(rèn)是root
        redirect_stderr=true            ; 把stderr重定向到stdout,默認(rèn)false
        stdout_logfile_maxbytes=20MB  ; stdout 日志文件大小,默認(rèn)是50MB
        stdout_logfile_backups=30        ; stdout 日志文件備份數(shù),默認(rèn)是10; 
        # stdout 日志文件,需要注意當(dāng)指定目錄不存在時無法正常啟動,所以需要手動創(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守護(hù)文件,容器啟動后執(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)控主機(jī)的文件

        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: " 服務(wù)停止運行 "
              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進(jìn)程管理工具和SSH服務(wù),指定了字符集和時區(qū)。

        生成鏡像并運行容器服務(wù)

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

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

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


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

        容器正常運行后,進(jìn)入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' #添加的標(biāo)簽
          - 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頁面已經(jīng)可以看到node-exporter,然后我們就可以定義報警規(guī)則和展示看板了,這部分內(nèi)容在后面配置Alertmanager和Grafana上會詳細(xì)介紹。

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

        各節(jié)點主機(jī)部署容器監(jiān)控組件cadvisor-exporter,我這邊Docker網(wǎng)絡(luò)使用的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 端口

        現(xiàn)在我們進(jìn)入Prometheus容器,在prometheus.yml主機(jī)文件中添加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,說明正常接收數(shù)據(jù)。

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

        容器部署Redis服務(wù)監(jiān)控組件redis_exporter,--redis.passwd指定認(rèn)證口令,如果你的redis訪問沒有密碼那么就無需指定后面參數(shù)。

        $ 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.部署應(yīng)用監(jiān)控組件

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

        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. 然后在中間件啟動參數(shù)添加以下內(nèi)容,指定配置文件和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. 部署進(jìn)程監(jiān)控組件

        因為我們?nèi)萜魇鞘褂脝为毜木W(wǎng)絡(luò)部署的,相當(dāng)于胖容器的方式,所以需要在監(jiān)控的容器中部署process-exporter進(jìn)程監(jiān)控組件來監(jiān)控容器的進(jì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'  #匹配進(jìn)程,支持正則 

        啟動參數(shù):

        $ 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,現(xiàn)在我們熱加載更新Prometheus的主機(jī)文件

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

        四、部署Alertmanager報警組件

        1. Alertmanager 概述

        Alertmanager處理客戶端應(yīng)用程序(如Prometheus服務(wù)器)發(fā)送的告警。它負(fù)責(zé)對它們進(jìn)行重復(fù)數(shù)據(jù)刪除,分組和路由,以及正確的接收器集成,例如電子郵件,PagerDuty或OpsGenie。它還負(fù)責(zé)警報的靜默和抑制。

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

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

        設(shè)置警報和通知的主要步驟如下:

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

        2. 部署Alertmanager組件

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

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

        2. 訪問apps創(chuàng)建第三方應(yīng)用,點擊創(chuàng)建應(yīng)用按鈕 -> 填寫應(yī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ā)送已解決通知

        參數(shù)說明:

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

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

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

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

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

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

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

        運行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語句編寫

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

        編寫主機(jī)監(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: "宿主機(jī)內(nèi)存使用率超過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: "宿主機(jī)CPU使用率超過80%."
             value: "{{ $value }}"
         - alert: HostLoad
           expr: node_load5 > 20
           for: 1m
           labels:
             name: Load
             severity: Warning
           annotations:
             summary: "{{ $labels.appname }} "
             description: " 主機(jī)負(fù)載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: " 宿主機(jī) [ {{ $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: " 宿主機(jī) [{{ $labels.device }}]磁盤1分鐘平均寫入IO負(fù)載較高."
             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: " 宿機(jī) [{{ $labels.device }}]磁盤1分鐘平均讀取IO負(fù)載較高."
             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: " 宿主機(jī) [{{ $labels.device }}] 網(wǎng)卡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: " 宿主機(jī) [{{ $labels.device }}] 網(wǎng)卡5分鐘內(nèi)平均發(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: " 容器內(nèi)存使用超過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 }}] 網(wǎng)卡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 }}] 網(wǎng)卡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: " 服務(wù)停止運行 "
              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連接數(shù)超過最大連接數(shù)的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連接數(shù)超過最大連接數(shù)的80%. "
              value: "{{ $value }}"

        編寫服務(wù)停止監(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: " 進(jìn)程停止運行 "
              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展示看板后的數(shù)據(jù)展示語句,需要注意的是,我們?nèi)萜魇褂玫氖桥秩萜鞯姆绞?,即?dāng)作虛擬機(jī)來使用,所以需要添加應(yīng)用和服務(wù)停止的Exporter,如果你的容器守護(hù)進(jìn)程直接就是應(yīng)用的話,只需要監(jiān)控容器的啟停就可以了。

        測試微信報警

        五、Grafana展示組件

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

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

        Grafana是一個用于可視化大型測量數(shù)據(jù)的開源系統(tǒng),它的功能非常強大,界面也非常漂亮,使用它可以創(chuàng)建自定義的控制面板,你可以在面板中配置要顯示的數(shù)據(jù)和顯示方式,它支持很多不同的數(shù)據(jù)源,比如:Graphite、InfluxDB、OpenTSDB、Elasticsearch、Prometheus 等,而且它也支持眾多的插件 。

        1. 部署Grafana服務(wù)容器

        $ 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數(shù)據(jù)源

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

        使用編號導(dǎo)入模板,Grafana服務(wù)需要聯(lián)網(wǎng),否則需要到Grafana模板下載JSON文件導(dǎo)入。

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

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

        六、PromQL語句

        七、使用Concul HTTP注冊方式實現(xiàn)服務(wù)發(fā)現(xiàn)

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

        1. consul 內(nèi)部原理

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

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

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

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

        2. 使用docker部署consul 集群

        #啟動第1個Server節(jié)點,集群要求要有3個Server,將容器8500端口映射到主機(jī)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. 服務(wù)注冊到Consul

        使用HTTP API 方式注冊node-exporter服務(wù)到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

        注冊多個服務(wù)到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 服務(wù)發(fā)現(xiàn)

        consul 可以使用的元標(biāo)簽:

        __meta_consul_address:目標(biāo)的地址
        __meta_consul_dc:目標(biāo)的數(shù)據(jù)中心名稱
        __meta_consul_tagged_address_<key>:每個節(jié)點標(biāo)記目標(biāo)的地址鍵值
        __meta_consul_metadata_<key>:目標(biāo)的每個節(jié)點元數(shù)據(jù)鍵值
        __meta_consul_node:為目標(biāo)定義的節(jié)點名稱
        __meta_consul_service_address:目標(biāo)的服務(wù)地址
        __meta_consul_service_id:目標(biāo)的服務(wù)ID
        __meta_consul_service_metadata_<key>:目標(biāo)的每個服務(wù)元數(shù)據(jù)鍵值
        __meta_consul_service_port:目標(biāo)的服務(wù)端口
        __meta_consul_service:目標(biāo)所屬服務(wù)的名稱
        __meta_consul_tags:標(biāo)記分隔符連接的目標(biāo)的標(biāo)記列表

        修改Prometheus.yml 文件,使用relabel將consul的元標(biāo)簽重寫便于查看

          - job_name: 'consul'
            consul_sd_configs:
              - server: '192.168.16.173:8900'
                services: []  #匹配所有service
            relabel_configs:
              - source_labels: [__meta_consul_service] #service 源標(biāo)簽
                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頁面

        應(yīng)用注冊到consul

        在不需要開發(fā)修改代碼的前提下,我們可以使用Prometheus的jmx-exporter收集應(yīng)用的相關(guān)指標(biāo),在應(yīng)用中間件tomcat/weblogic等調(diào)用jmx-exporter,具體方式查看https://www.jianshu.com/p/dfd6ba5206dc

        啟動應(yīng)用后會啟動12345端口暴露jvm數(shù)據(jù),現(xiàn)在我們要做的就是將這個端口注冊到Consul上,然后Prometheus會從consul 拉取應(yīng)用主機(jī)。

        使用腳本實現(xiàn)

         $ 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模板

        國產(chǎn)小眾瀏覽器因屏蔽視頻廣告,被索賠100萬(后續(xù))

        年輕人“不講武德”:因看黃片上癮,把網(wǎng)站和786名女主播起訴了

        中國聯(lián)通官網(wǎng)被發(fā)現(xiàn)含木馬腳本,可向用戶推廣色情APP

        張一鳴:每個逆襲的年輕人,都具備的底層能力


        關(guān)


        ,學(xué),西學(xué)學(xué)護(hù),質(zhì),結(jié),關(guān)[],學(xué)習(xí)進(jìn)!


        瀏覽 23
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

        分享
        舉報
          
          

            1. 成年黄色片 | 老师我想要(h)小说 | 亚洲日韩视频 | 野花社区 | 日日夜夜操视频 |