基于 Docker 的 Prometheus 监控方案

prometheus

Author:rab



一、规划

1.1 架构图

architecture

我们将按照架构图来实现。

1.2 主机规划

由于主机资源问题,暂且以两台服务器进行演示。

Hostserver备注
192.168.56.141Prometheus、Node_exporterPrometheus 服务、采集插件
192.168.56.142Grafana、Alertmanager、Node_exporter、DingTalk监控展示、告警服务、采集插件

版本:

  • CentOS:7.9

  • Prometheus:2.37.0

  • Grafana:9.0.3

  • Alertmanager:0.20.0

  • node-exporter:1.4.0

  • Dingding:1.4.0

二、部署

相关组件下载地址:https://prometheus.io/download/

前提:已经对服务器做了相关初始化,且安装了 docker 容器引擎。

2.1 Prometheus

官方文档:https://prometheus.io/docs/introduction/overview/

1、pull 镜像

docker pull bitnami/prometheus:2.37.0

# 本次采用最新稳定版

2、创建监控用户

groupadd -g 2000 monitor
useradd -u 2000 -g monitor monitor

3、创建相关目录

mkdir -p /home/data/prometheus/{etc,data,rules}

# etc:配置文件目录
# data:数据目录
# rules:规则目录

4、创建配置文件

vim /home/data/prometheus/etc/prometheus.yml

# 或先启动临时容器再copy也是可以的
# my global config
global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

# Alertmanager configuration
alerting:
  alertmanagers:
  - static_configs:
    - targets:
      # - alertmanager:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'prometheus'

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
    - targets: ['localhost:9090']

5、目录授权

chown monitor. -R /home/data/prometheus

6、启动容器

运行容器前,先看看这个镜像容器启动后会执行什么命令

docker inspect -f '{{.Config.Cmd}}' bitnami/prometheus:2.37.0

image-20220924181619392

docker run -d --user root \
    --name=prometheus \
    --privileged=true \
    --restart=always \
    -p 9090:9090 \
    -v /home/data/prometheus/etc/prometheus.yml:/etc/prometheus/prometheus.yml \
    -v /home/data/prometheus/rules:/etc/prometheus/rules \
    -v /home/data/prometheus/data:/data/prometheus \
    -v /etc/localtime:/etc/localtime \
    bitnami/prometheus:2.37.0 \
    --config.file="/etc/prometheus/prometheus.yml" \
    --storage.tsdb.path="/data/prometheus" \
    --web.enable-lifecycle \
    
# --config.file、--storage.tsdb.path可进行传参,会替换上图中得默认值(自己根据需求是否修改即可)

7、访问验证

image-20220718122145247

8、热更新

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

# 我docker方式部署的热加载无效,正在找原因

9、语法检测

这一点的好处在于检测你更新配置后是否有语法错误

docker exec prometheus promtool check config /etc/prometheus/prometheus.yml

确保无误后即可重启或热更新 Prometheus。

2.2 Grafana

官方文档:https://grafana.com/docs/

1、pull 镜像

docker pull grafana/grafana:9.0.3

2、创建监控用户

groupadd -g 2000 monitor
useradd -u 2000 -g monitor monitor

3、创建相关目录

mkdir -p /home/data/grafana/data
mkdir -p /home/data/grafana/logs

4、启动临时容器(copy相关配置文件)

docker run -d -p 3000:3000 --name=tmp grafana/grafana:9.0.3

# 复制配置文件
docker cp tmp:/etc/grafana/ /home/data/grafana/
# 退出临时容器
exit
# 修改文件名
mv /home/data/grafana/grafana /home/data/grafana/etc
# 删除临时容器
docker stop tmp
docker rm tmp

5、目录授权

chown -R monitor. /home/data/grafana
chmod 777 -R /home/data/grafana

6、启动容器

docker run -d --user root \
    --name=grafana \
    --privileged=true \
    --restart=always \
    -p 3000:3000 \
    -v /home/data/grafana/etc:/etc/grafana \
    -v /home/data/grafana/data:/var/lib/grafana \
    -v /home/data/grafana/logs:/var/log/grafana \
    -v /etc/localtime:/etc/localtime \
    grafana/grafana:9.0.3

7、登录验证

默认用户:admin

默认密码:admin

输入完成之后,会提示你再次输入新的登录密码。

image-20220718134653471

功能界面

image-20220718134806098

8、忘记密码

如果忘记密码,如何重置?

# 语法:grafana-cli <登录用户> reset-admin-password <新密码>

docker exec grafana grafana-cli admin reset-admin-password admin@123

9、插件安装

  • 在线安装

    docker exec grafana grafana-cli plugins list-remote | more   # 查看远程可用插件
    id: abhisant-druid-datasource version: 0.0.6
    id: aceiot-svg-panel version: 0.0.11
    id: ae3e-plotly-panel version: 0.5.0
    id: agenty-flowcharting-panel version: 0.9.1
    id: aidanmountford-html-panel version: 0.0.2
    id: akumuli-datasource version: 1.3.12
    id: alexanderzobnin-zabbix-app version: 4.2.10
    ...
    ...
    

    根据这些远程可用插件即可进行安装

    # 案例:grafana-cli plugins install <插件名> <插件版本号>
    grafana-cli plugins install alexanderzobnin-zabbix-app 4.2.10
    
    # 指定安装路径
    grafana-cli --pluginsDir=/data/grafana/plugins plugins install alexanderzobnin-zabbix-app 4.1.5
    

    安装语法

    COMMANDS:
       install                  install <plugin id> <plugin version (optional)>
       list-remote              list remote available plugins
       list-versions            list-versions <plugin id>
       update, upgrade          update <plugin id>
       update-all, upgrade-all  update all your installed plugins
       ls                       list all installed plugins
       uninstall, remove        uninstall <plugin id>
       help, h                  Shows a list of commands or help for one command
    
  • 手动安装

    如果在线安装失败,可进行手动安装

    第一步:访问grafana官网 https://grafana.com/grafana/plugins?orderBy=weight&direction=asc

    第二步:查找要下载的插件,如:Pie Chart

    第三步:根据安官网提供的装步骤下载即可

    # 在线下载zip包
    wget -nv https://grafana.com/api/plugins/grafana-piechart-panel/versions/latest/download -O /tmp/grafana-piechart-panel.zip
    # 或上传
    unzip -q /tmp/grafana-piechart-panel.zip -d /tmp
    mv /tmp/grafana-piechart-panel-* /var/lib/grafana/plugins/grafana-piechart-panel
    sudo service grafana-server restar
    

2.3 Node_Exporter

node_exporter 作为 Prometheus 的 agent 端,部署在被采集数据的 Host 上,其负责采集数据供 Prometheus 进行抓取。这里采用二进制方式部署即可。

1、下载二进制包

https://github.com/prometheus/node_exporter

image-20220924165651183

2、配置 systemd 管理

vim /usr/lib/systemd/system/node_exporter.service
[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target

[Service]
User=prometheus
ExecStart=/home/data/prometheus/exporters/node_exporter/node_exporter --collector.textfile.directory /home/data/node_texfile --collector.systemd --collector.systemd.unit-include="(docker|sshd).service"

[Install]
WantedBy=default.target

# 具体参数参考我有道云笔记《Exporter+Promethue+Grafana监控平台》部分

3、启动并设置开机自启

systemctl daemon-reload
systemctl start node_exporter.service
systemctl enable node_exporter.service

5、验证

这里以 141 服务器演示

浏览器访问:http://192.168.56.141:9100/metrics

image-20220924170321058

2.4 Alertmanager

官方文档:https://prometheus.io/docs/alerting/latest/alertmanager/

告警采用 Alertmanager 进行管理,其告警原理可简单概括为:当采集数据值达到告警阈值时(在prometheus设定的告警规则),就会触发 Alertmanager 进行告警(经过分组、删除重复等处理),告警通过可邮件等方式发送给相应的运维人员。主要配置步骤:

  • 设置和配置 Alertmanager;
  • 配置 Prometheus 与 Alertmanager 之间的对话;
  • 在 Prometheus 中创建警报规则。

prometheus--->触发阈值--->超出持续时间--->alertmanager--->分组|抑制|静默--->媒体类型--->邮件|钉钉|微信等。

这里我采用单节点部署,一般我们生产环境中 Alertmanager 采用集群部署。

2.4.1 部署与配置

1、先看容器启动时会加载哪些参数

image-20220924193728233

2、创建本地持久化目录

mkdir -p /home/data/alertmanager/{conf,data}

3、创建配置文件

vim /home/data/alertmanager/conf/config.yml
global:
  resolve_timeout: 5m
  smtp_smarthost: 'smtp.163.com:465'                # 邮箱服务器
  smtp_from: 'xxxx@163.com'                         # 邮箱地址(发送用户)
  smtp_auth_username: 'xxxx@163.com'                # 邮箱登录地址
  smtp_auth_password: 'xxxxxxxxx'                   # 邮箱授权码(注意是授权码,不是登录密码)
  smtp_require_tls: false

templates:
- '/etc/alertmanager/template/*.tmpl'

route:
  group_by: ['alertname']
  group_wait: 20s
  group_interval: 5m
  repeat_interval: 3h
  receiver: 'ops'
  # continue: false
  routes:
  - match:
      severity: critical
    receiver: 'dev'
    # continue: true
  - match_re:
      severity: ^(warning|critical)$
    receiver: 'test'

receivers:
- name: 'ops'
  email_configs:
  - to: 'xxxx@qq.com'
    send_resolved: true

- name: 'dev'
  email_configs:
  - to: 'xxxx@qq.com'
    send_resolved: true
    
- name: 'test'
  email_configs:
  - to: 'xxxx@126.com'
    send_resolved: true

inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['alertname', 'dev', 'instance']

4、运行容器

docker run -d --restart=always --name=alertmanager --privileged=true \
  -p 9093:9093 \
  -v /home/data/alertmanager/conf/config.yml:/opt/bitnami/alertmanager/conf/config.yml \
  -v /home/data/alertmanager/data:/opt/bitnami/alertmanager/data \
  -v /etc/localtime:/etc/localtime \
  bitnami/alertmanager:0.24.0

5、web 验证

浏览器访问:http://192.168.56.142:9093/

image-20220924201055281

6、Prometheus 配置

配置与 Alertmanager 通信

...
# Alertmanager configuration
alerting:
  alertmanagers:
  - static_configs:
    - targets:
      - 192.168.56.142:9093
...

Alertmanager 自身也进行了数据采集,自然也可以进行状态监控

image-20220924204227389

2.4.2 告警规则

Alertmanager 配置完成后,还需要在 prometheus 配置文件中进行告警配置:

rule_files:
  - "first_rules.yml"      # 记录规则
  - "second_rules.yml"     # 告警规则

修改 Prometheus 配置文件,定义这两个文件得路径

docker 目录映射规则:/home/data/prometheus/rules:/etc/prometheus/rules

所以我只需要在 /home/data/prometheus/rules 目录下创建规则即可

...
rule_files:
  - '/etc/prometheus/rules/*_rules.yml'
  - '/etc/prometheus/rules/*_alerts.yml'
...
2.4.2.1 记录规则

新建记录规则文件:简单测试被采集服务器得健康状况

cd /home/data/prometheus/rules
vim host_rules.yml
groups:
- name: host.rules
  rules:
    - record: instance:node_stat:up
      expr: up{job="linux"} == 0
2.4.2.2 告警规则

主机节点基础告警

cd /home/data/prometheus/rules
vim host_alerts.yml
groups:
- name: host.alter
  rules:
    - alert: host_up
      expr: instance:node_stat:up == 0
      for: 20s
      labels:
        severity: warning
      annotations:
        summary: "{{ $labels.instance }} 已停止运行超过20s!请手动检查服务健康状态"

在 Prometheus 服务上可看见定义的告警规则

image-20220924232204472

2.4.3 告警验证

以上记录规则和告警规则都完成后,现在就模拟服务器故障,看是否发送告警。

1、先看看健康状态

image-20220924231451970

2、停掉 141 服务器的 node_exporter 插件

# 141
systemctl stop node_exporter.service

# 142
systemctl stop node_exporter.service

下图是我 126 邮箱收到的信息,原因是根据 Alertmanager 的路由策略来分发的,即当收到 wornning 告警时会匹配到该邮件并发送邮件。

image-20220924233102780

三、应用案例

3.1 主机发现

3.1.1 静态配置

node_exporter 部署完成后,还需要在 Prometheus 服务配置文件中进行配置,以此来 pull node_exporter 采集的数据。

什么是静态配置?所谓的静态配置就是在 Prometheus 配置文件中直接指定目标 Host。

1、修改 Prometheus 配置文件

...
...
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
    # - targets: ['localhost:9090']

  - job_name: 'linux'
    static_configs:
    - targets: ['192.168.56.141:9100', '192.168.56.142:9100']
...
...

2、Prometheus 服务热更新或重启

先检测语法是否错误再重启或热加载,否则你也是启动不了的。

docker restart prometheus
3.1.2 动态配置
3.1.2.1 基于本地文件

动态配置是将被采集的目标 Host 写入一个 json 文件中,Prometheus 服务会定期去扫描其中的目标主机,如果有新的主机添加,则 Prometheus 自动获取无需热更或重启 Prometheus 服务。

1、修改 Prometheus 配置文件

...
...
  - job_name: 'linux'
    file_sd_configs:
      - files:
        - /data/prometheus/target/nodes/*.json
        refresh_interval: 1m
...
...

这个 json 文件可以是一个泛文件:/data/prometheus/target/nodes/*.json 表示 Prometheus 或每隔 1 分钟查找 /data/prometheus/target/nodes/ 目录下的所有以 .json 结尾的文件。

2、编写 json 文件

# 创建存放json目录(对于docker部署的Prometheus,该目录在容器内部必须能读取得到)
# 上面得配置文件中/data/prometheus/目录已经被映射到/home/data/prometheus/data/目录下了
# 所以直接在/home/data/prometheus/data/目录下创建相关文件即可
mkdir -p /home/data/prometheus/data/target/nodes

# 在*.json文件中添加目标主机IP
vim host.json
[{
  "targets": [
    "192.168.56.141:9100"
  ]
}]

# 先写一台Host IP进行测试,成功再添加另一台

3、Prometheus 语法检测

4、等 1 分钟时间后再去验证一下

可看到 141 服务器已经被添加上来了

image-20220924173134729

我再次添加 142 主机 IP,再次验证是否自动添加,同样修改配置文件

[{
  "targets": [
    "192.168.56.141:9100",
    "192.168.56.142:9100"
  ]
}]

再次验证:可看到在 1 分钟后 142 服务器被自动添加

image-20220924173427913

3.1.2.2 基于 DNS

1、Prometheus 配置

  - job_name: 'webapp'
    dns_sd_configs:
      - names: ['app.scedutek.com']  # 域名,保证该域名需做了解析
        refresh_interval: 5m         # 5每分钟执行(刷新)一次
        type: A
        port: 80

2、热更或重启 prometheus

docker restart prometheus

3.2 钉钉集成

1、获取钉钉 Token

https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxxxxxxx

2、准备配置文件

# 创建
mkdir -p /home/data/dingtalk/conf && cd /home/data/dingtalk/conf
docker cp tmp:/etc/prometheus-webhook-dingtalk/config.yml .

修改配置文件

cat config.yml

image-20221004223034790

上图中的 secret 在钉钉机器人中进行配置,具体看下图。

image-20221004222615046

3、运行钉钉插件容器

docker run -d \
  --name=dingtalk \
  --restart always \
  -p 8060:8060 \
  -v /home/data/dingtalk/conf/config.yml:/etc/prometheus-webhook-dingtalk/config.yml \
  timonwong/prometheus-webhook-dingtalk:latest

3、设置alertmanager 的yml的routereceivers

route:
  group_by: ['alertname']
  group_wait: 20s
  group_interval: 30s
  repeat_interval: 1m
  receiver: 'ops'
  # continue: false
  routes:
  - match:
      severity: critical
    receiver: 'dev'
    # continue: true
  - match_re:
      severity: ^(warning|critical)$
    receiver: 'webhook'

receivers:
- name: 'dev'
  email_configs:
  - to: '2222222@qq.com'
    send_resolved: true
- name: 'webhook'
  webhook_configs:
  - url: http://192.168.56.142:8060/dingtalk/webhook1/send
    send_resolved: true

image-20221004231759335

恢复告警

image-20221004232000604

3.3 Grafana 模板导入

官方参考模板:https://grafana.com/grafana/dashboards/

1、添加数据源为 Prometheus

image-20221005203521799

2、导入模板

我此处的模板是官方模板:11074

image-20221005203718190

3、数据展示

image-20221005203029392

该模板展示了 node 节点的基本情况,在大多数情况下已经够用了,当然你也可以根据自己公司的实际情况进行自定义配置。

3.4 容器监控

为了解决 docker stats 的问题(存储、展示),谷歌开源的 cadvisor 诞生了,``cadvisor不仅可以搜集一台机器上所有运行的容器信息,还提供基础查询界面和http接口,方便其他组件如Prometheus进行数据抓取,或者cadvisor + influxdb + grafna` 搭配使用。

3.4.1 Cadvisor 部署

1、pull 镜像

docker pull google/cadvisor:latest

2、启动容器

docker run \
  -itd -u root --privileged=true \
  --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 \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  google/cadvisor:latest

3、验证

http://192.168.56.142:8080/containers/

image-20221005210013965

4、监控指标展示(TXT)

http://192.168.56.142:8080/metrics

image-20221005215249368

3.4.2 Prometheus 配置

通过监控指标展示(TXT),类似于 noed_export 我们可以在 Prometheus 进行配置。

1、添加主机发现

vim /home/data/prometheus/data/target/nodes/Cadvisor.json

image-20221005223818508

2、验证

image-20221005223404707

Prometheus 数据持久化存储方案会在后续介绍,本次就简单介绍到这里,欢迎大家进行补充。

四、FAQ

4.1 钉钉配置

1、错误描述

level=error ts=2022-10-04T14:08:53.510Z caller=dingtalk.go:103 component=web target=webhook1 msg="Failed to send notification to DingTalk" respCode=310000 respMsg=description:关键词不匹配;solution:请联系群管理员查看此机器人的关键词,并在发送的信息中包含此关键词;

2、解决方案

在钉钉机器人配置处加签,如下图:

image-20221004222615046

4.2 其他

暂时没遇到其他问题,欢迎大家进行补充。

<点击跳转至开头>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云计算-Security

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值