一、prometheus 介绍
1.1、prometheus 简介
Prometheus(普罗米修斯)是由 SoundCloud 开源的监控告警解决方案,自2012年成为社区开源项目,拥有非常活跃的开发人员和用户社区。同时为强调开源及独立维护,Prometheus于2016年加入云原生云计算基金会(CNCF),成为继Kubernetes之后的第二个托管项目。
官方网站:https://prometheus.io
项目托管:https://github.com/prometheus
1.2、Prometheus 特点
- 多维数据模型:由度量名称和键值对标识的时间序列数据。
- PromSQL:一种灵活的查询语言,可以利用多维数据完成复杂的查询。
- 不依赖分布式存储,单个服务器节点可直接工作。
- 基于HTTP的pull方式采集时间序列数据。
- 推送时间序列数据通过PushGateway组件支持。
- 通过服务发现或静态配置发现目标。
- 多种图形模式及仪表盘支持(grafana)。
1.3、Prometheus 组件
- Prometheus Server:用于抓取指标、存储时间序列数据。
- push gateway:对于那些生存时间很短的job工作,让job主动把监控指标push到getway,Prometheus再从getway中拉取。
- exporter:用于暴露已有的第三方服务的 metrics 给 Prometheusalertmanager。
- alertmanager:告警组件,会将Prometheus Server的数据进行去除重复数据,分组,并路由到对收的接受方式,发出报警。
- Web UI:Prometheus内置一个简单的Web控制台,可以查询指标,查看配置信息或者Service Discovery等,实际工作中,查看指标或者创建仪表盘通常使用Grafana,Prometheus作为Grafana的数据源。
1.4、Prometheus 工作原理
通过HTTP周期性抓取被监控组件的状态,任意组件只要提供对应的HTTP接口并符合Prometheus定义的数据格式,就可以接入Prometheus监控;Prometheus Server负责定时在目标上抓取metrics(指标)数据,每个抓取目标都需要暴露一个HTTP服务接口用于Prometheus定时抓取。这种调用被监控对象获取监控数据的方式被称为Pull(拉);Pull方式体现了Prometheus独特的设计哲学与大多数采用Push(推)方式的监控不同。
二、部署 Prometheus
(1) 下载
mkdir -pv /usr/local/soft/package && cd /usr/local/soft/package
wget https://github.com/prometheus/prometheus/releases/download/v2.29.2/prometheus-2.29.2.linux-amd64.tar.gz
(2) 解压并重命名
tar -xf prometheus-2.29.2.linux-amd64.tar.gz -C /usr/local/soft
cd /usr/local/soft
mv prometheus-2.29.2.linux-amd64 prometheus
(3) 配置
配置共分为三部分,分别是全局配置、告警配置、收集数据配置
vim /usr/local/soft/prometheus/prometheus.yml
#全局配置
global:
scrape_interval: 15s #每隔15秒向目标抓取一次数,默认为一分钟
evaluation_interval: 15s #每隔15秒执行一次告警规则,默认为一分钟
# scrape_timeout: 600s #抓取数据的超时时间,默认为10s
#告警配置
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093 #alertmanager所部署机器的ip和端口
#定义告警规则和阈值的yml文件
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
#收集数据配置
#以下是Prometheus自身的一个配置.
scrape_configs:
#这个配置是表示在这个配置内的时间序例,每一条都会自动添加上这个{job_name:"prometheus"}的标签.
- job_name: "prometheus"
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs: #静态配置
- targets: ["localhost:9090"]
(4) 启停
cd /usr/local/soft/prometheus
#校验配置文件
./promtool check config ./prometheus.yml
#启动
nohup ./prometheus --config.file=./prometheus.yml \
--web.listen-address=0.0.0.0:9090 \
--web.enable-lifecycle \
--storage.tsdb.retention=90d \
--storage.tsdb.path=./data &
##启动参数介绍
--config.file #加载prometheus的配置文件
--web.listen-address #监听prometheus的web地址和端口
--web.enable-lifecycle #热启动参数,可以在不中断服务的情况下重启加载配置文件
--storage.tsdb.retention #数据持久化的时间
--storage.tsdb.path #数据持久化的保存路径
#停止
ps -ef | grep prometheus | grep -v grep | awk '{print $2}' | xagrs kill -9
#或者
curl -XPOST http://localhost:9090/-/quit
#重载
curl -XPOST http://localhost:9090/-/reload
(5) 以 systemd 的方式管理 prometheus 的启停(非必选)
cat > /usr/lib/systemd/system/prometheus.service <<EOF
[Unit]
Description=The Prometheus Server
After=network.target
[Service]
ExecStart=/usr/local/soft/prometheus/prometheus \
--config.file=/usr/local/soft/prometheus/prometheus.yml \
--web.listen-address=0.0.0.0:9090 \
--web.enable-lifecycle \
--storage.tsdb.retention=90d \
--storage.tsdb.path="/usr/local/soft/prometheus/data/"
Restart=on-failure
RestartSec=15s
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload && systemctl enable prometheus && systemctl restart prometheus
(6) web 访问
通过浏览器访问 http://IP:9090 即可
三、部署 node_exporter
(1) 下载
cd /usr/local/soft/package
wget https://github.com/prometheus/node_exporter/releases/download/v1.2.2/node_exporter-1.2.2.linux-amd64.tar.gz
(2) 解压并重命名
tar -xf node_exporter-1.2.2.linux-amd64.tar.gz -C /usr/local/soft
cd /usr/local/soft
mv node_exporter-1.2.2.linux-amd64 node_exporter
(3) 启停
#启动
nohup ./node_exporter --web.listen-address=0.0.0.0:4220 &
##启动参数介绍
注意:相关启动的参数
--web.listen-address #node_expoetrt暴露的端口
--collector.systemd #从systemd中收集
--collector.systemd.unit-whitelist ##白名单,收集目标
".+" #从systemd中循环正则匹配单元
"(docker|sshd|nginx).service" #白名单,收集目标,收集参数node_systemd_unit_state
#停止
ps -ef | grep node_exporter | grep -v grep | awk '{print $2}' | xagrs kill -9
(4) 以 systemd 的方式管理 node_exporter 的启停(非必选)
cat > /usr/lib/systemd/system/node_exporter.service <<EOF
[Unit]
Description=The node_exporter Server
After=network.target
[Service]
ExecStart=/usr/local/soft/node_exporter/node_exporter \
--web.listen-address=0.0.0.0:4220 \
--collector.systemd \
--collector.systemd.unit-whitelist=(sshd|docker).service
Restart=on-failure
RestartSec=15s
SyslogIdentifier=node_exporter
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload && systemctl enable node_exporter && systemctl restart node_exporter
四、部署 alertmanager
(1) 下载
cd /usr/local/soft/package
wget https://github.com/prometheus/alertmanager/releases/download/v0.23.0/alertmanager-0.23.0.linux-amd64.tar.gz
(2) 解压并重命名
tar -xf alertmanager-0.23.0.linux-amd64.tar.gz -C /usr/local/soft
cd /usr/local/soft
mv alertmanager-0.23.0.linux-amd64 alertmanager
(3) 配置
配置共分为六部分,分别是global配置、templates配置、route配置、receivers配置、inhibit_rules配置、静默配置
#global配置
global:
resolve_timeout: 5m #在报警恢复的时候不是立马发送的,在接下来的这个时间内,如果没有此报警信息触发,才发送报警恢复消息
smtp_smarthost: 'smtp.exmail.qq.com:465' #发件人对应邮件提供商的smtp地址,此处为腾讯企业邮箱stmp配置
smtp_from: 'xxx@company.com' #发件人邮箱地址
smtp_auth_username: 'xxx@company.com' #发件人的登陆用户名,默认和发件人地址一致
smtp_auth_password: 'xxxxxxx' #发件人的登陆密码,也可以是授权码。
smtp_require_tls: false #是否需要tls协议,默认是true
#templates配置
templates:
- '/usr/local/soft/alertmanager/email.tmpl' #自定义通知的模板的目录或者文件
#route配置
route: #每个输入警报进入根路由
group_by: ['alertname','cluster','service'] #将传入的报警中有这些标签的分为一个组,比如, cluster=A 和 alertname=LatencyHigh 会分成一个组
group_wait: 30s #指分组创建多久后才可以发送压缩的警报,也就是初次发警报的延时,这样会确保第一次通知的时候, 有更多的报警被压缩在一起
group_interval: 5m #当第一个通知发送,等待多久发送压缩的警报
repeat_interval: 1h #如果报警发送成功, 等待多久重新发送一次
receiver: 'email' #默认警报接收者
#receivers配置
receivers:
- name: 'email' #警报名称
email_configs:
- to: 'xxx@xxx.com' #接收警报的email
send_resolved: true #是否发送警报解除邮件
html: '{{ template "email.htm" . }}' #模板
headers: { Subject: "{{ .CommonLabels.severity }} {{ .CommonAnnotations.summary }}" } #标题
#报警抑制规则
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance'] #通过上面的配置,可以在alertname相同的情况下,critaical的报警会抑制warning级别的报警信息。
#静默配置
#静默配置是通过web界面配置的,通常用于服务升级或者长时间的服务故障,确保在接下来的时间内不会在收到同样报警信息
(4) 启停
#启动
nohup ./alertmanager --config.file="alertmanager.yml" --web.listen-address=":9093" &
#停止
ps -ef |grep alertmanager |grep -v grep |awk '{print $2}' | xargs kill -9
#重载
curl -XPOST http://localhost:9093/-/reload
(5) 以 systemd 的方式管理 alertmanager 的启停(非必选)
cat > /usr/lib/systemd/system/alertmanager.service <<EOF
[Unit]
Description=The Prometheus Server
After=network.target
[Service]
ExecStart=/usr/local/soft/alertmanager/alertmanager \
--config.file=/usr/local/soft/alertmanager/alertmanager.yml \
--web.listen-address=0.0.0.0:9093
Restart=on-failure
RestartSec=15s
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload && systemctl enable alertmanager && systemctl restart alertmanager
(6) web 访问
通过浏览器访问 http://IP:9093 即可
五、部署 grafana
(1) 下载
cd /usr/local/soft/package
wget https://dl.grafana.com/enterprise/release/grafana-enterprise-8.1.2.linux-amd64.tar.gz
(2) 解压并重命名
tar -xf grafana-enterprise-8.1.2.linux-amd64.tar.gz -C /usr/local/soft
cd /usr/local/soft
mv grafana-enterprise-8.1.2.linux-amd64 grafana
(3) 启动
#启动
nohup /usr/local/soft/grafana/bin/grafana-server &
#停止
ps -ef |grep grafana-server |grep -v grep |awk '{print $2}' | xargs kill -9
(4) 访问
通过浏览器访问 http://IP:3000 ,默认用户名和密码为admin/admin,第一次登陆系统会要求修改密码
六、监控案例
6.1、监控mysql
6.1.1、安装 mysqld_exporter
mysqld_exporter 安装在 mysql 服务器上,或者单独安装均可
(1) 下载
mkdir -pv /usr/local/soft/package && cd /usr/local/soft/package
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.13.0/mysqld_exporter-0.13.0.linux-amd64.tar.gz
(2) 解压并重命名
tar -xf mysqld_exporter-0.13.0.linux-amd64.tar.gz -C /usr/local/soft
cd /usr/local/soft
mv mysqld_exporter-0.13.0.linux-amd64 mysqld_exporter
(3) 配置mysql的监控账号
cd /usr/local/soft/mysqld_exporter
vim my.cnf
[client]
user=root
password=123456
host=localhost
port=3306
#sock="/tmp/mysql_3306.sock" #如果数据库需要sock文件就配置上,否则不需要此配置
(4) 启停
#启动
nohup /usr/local/soft/mysqld_exporter/mysqld_exporter \
--web.listen-address=":9104" \
--config.my-cnf=/usr/local/soft/mysqld_exporter/my-38.cnf &
#停止
ps -ef | grep mysqld_exporter | grep -v grep | awk '{print $2}' | xargs kill -9
如果在一台服务器上,启动多个 mysqld_exporter ,可通过监听不同端口实现:
nohup /usr/local/soft/mysqld_exporter/mysqld_exporter \
--web.listen-address=":9104" \
--config.my-cnf=/usr/local/soft/mysqld_exporter/my-38.cnf &
nohup /usr/local/soft/mysqld_exporter/mysqld_exporter \
--web.listen-address=":9105" \
--config.my-cnf=/usr/local/soft/mysqld_exporter/my-22.cnf &
nohup /usr/local/soft/mysqld_exporter/mysqld_exporter \
--web.listen-address=":9106" \
--config.my-cnf=/usr/local/soft/mysqld_exporter/my-245.cnf &
6.1.2、配置 prometheus
(1) 修改 prometheus 配置文件
vim /usr/local/soft/prometheus/prometheus.yml
global:
scrape_interval: 15s .
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets:
- 172.16.16.18:9093 #alertmanager地址
rule_files: #报警规则文件
- "/usr/local/soft/prometheus/rules/mysql_rule.yml"
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
- job_name: "node-exporter"
static_configs:
- targets: ["localhost:4220"]
- job_name: "mysql" #配置 mysql job
file_sd_configs: #配置文件自动发现
- files:
- /usr/local/soft/prometheus/conf.d/mysql_export.json
(2) 配置文件自动发现
cd /usr/local/soft/prometheus
mkdir conf.d
vim conf.d/mysql_export.json
[
{
"labels":{ #配置自定义标签
"desc": "172.16.16.38",
"group": "mysql",
"host_ip": "172.16.16.38",
"hostname": "mysql-master"
},
"targets": ["172.16.16.18:9104"] #配置metrics地址
},
{
"labels":{
"desc": "172.16.16.22",
"group": "mysql",
"host_ip": "172.16.16.22",
"hostname": "mysql-slave01"
},
"targets": ["172.16.16.18:9105"]
},
{
"labels":{
"desc": "172.16.16.245",
"group": "mysql",
"host_ip": "172.16.16.245",
"hostname": "mysql-slave02"
},
"targets": ["172.16.16.18:9106"]
}
]
(3) 配置告警规则
cd /usr/local/soft/prometheus
mkdir rules
vim rules/mysql_rule.yml
groups:
- name: mysqlAlerts
rules:
- alert: mysql告警
expr: mysql_up{job="mysql"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "{{$labels.desc}} mysql已停止运行超过1m"
description: "{{$labels.desc}} mysql中断超过1m"
message: "{{$labels.desc}} mysql已停止运行"
console: "请检查{{$labels.desc}}节点的mysql是否正常"
- alert: mysql slave节点IO线程异常
expr: mysql_slave_status_slave_io_running{job="mysql"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "{{$labels.desc}} mysql slave节点IO线程已停止运行超过1m"
description: "{{$labels.desc}} mysql slave节点IO线程中断超过1m"
message: "{{$labels.desc}} mysql slave节点IO线程已停止运行"
console: "请检查{{$labels.desc}}节点的mysql是否正常"
- alert: mysql slave节点SQL线程异常
expr: mysql_slave_status_slave_sql_running{job="mysql"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "{{$labels.desc}} mysql slave节点SQL线程已停止运行超过1m"
description: "{{$labels.desc}} mysql slave节点SQL线程中断超过1m"
message: "{{$labels.desc}} mysql slave节点SQL线程已停止运行"
console: "请检查{{$labels.desc}}节点的mysql是否正常"
6.1.3、配置 alertmanager
6.1.3.1、配置邮件告警
(1) 修改 alertmanager 配置文件
cd /usr/local/soft/alertmanager
vim alertmanager.yml
global:
resolve_timeout: 5m
smtp_smarthost: "smtp.qq.com:465" #配置邮件告警
smtp_from: "xxxx@qq.com"
smtp_auth_username: "xxxx@qq.com"
smtp_auth_password: "fafafafafafafa"
smtp_require_tls: false
templates:
- '/usr/local/soft/alertmanager/email.tmpl' #配置模板
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 30m
receiver: 'email'
receivers:
- name: 'email'
email_configs:
- to: 'xxx@company.com' #配置邮件接收人
send_resolved: true
html: '{{ template "email.htm" . }}' #模板
headers: { Subject: "[{{ .Status }}]{{ .CommonLabels.severity }} {{ .CommonAnnotations.summary }}" } #标题
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']
(2) 创建模板文件
vim email.tmpl
{{ define "email.htm" }}
{{ range .Alerts.Resolved }}
<pre>
告警已解除!
历史告警信息如下:
</pre>
{{ end }}
{{ range .Alerts }}
<pre>
========start==========
告警程序: {{ .Labels.job }}
告警级别: {{ .Labels.severity }} 级别
告警类型: {{ .Labels.alertname }}
故障主机: {{ .Labels.desc }}
告警主题: {{ .Annotations.summary }}
告警详情: {{ .Annotations.description }}
处理方法: {{ .Annotations.console }}
触发时间: {{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
========end==========
</pre>
{{ end }}
{{ end }}
6.1.3.2、配置钉钉告警
(1) 下载钉钉告警插件
cd /usr/local/soft/package
wget https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v2.0.0/prometheus-webhook-dingtalk-2.0.0.linux-amd64.tar.gz
(2) 解压并重命名
tar -xf prometheus-webhook-dingtalk-2.0.0.linux-amd64.tar.gz -C /usr/local/soft/
cd /usr/local/soft/
mv prometheus-webhook-dingtalk-2.0.0.linux-amd64 prometheus-webhook-dingtalk
(3) 创建钉钉自定义机器人
在电脑端钉钉的任一个群点击 群设置 --> 智能群助手 --> 添加机器人,进入后添加“自定义机器人”,然后按要求操作,获取 Webhook 和 加密串。
(4) 修改钉钉告警插件的配置文件
cd /usr/local/soft/prometheus-webhook-dingtalk
cp config.example.yml config.yml
vim config.yml
## Request timeout
# timeout: 5s
## Uncomment following line in order to write template from scratch (be careful!)
#no_builtin_template: true
## Customizable templates path
#templates:
# - contrib/templates/legacy/template.tmpl
## You can also override default template using `default_message`
## The following example to use the 'legacy' template from v0.3.0
#default_message:
# title: '{{ template "legacy.title" . }}'
# text: '{{ template "legacy.content" . }}'
## Targets, previously was known as "profiles"
##将webhook地址复制到url,加密串复制到secret
targets:
webhook1:
url: https://oapi.dingtalk.com/robot/send?access_token=b7a4392cacc6ac5962e8671486ffafa28aa14337e037455dbd11dc3e4a7b8db8
# secret for signature
secret: SEC4b4c021b752a0216ced1ba953a6ed78bf4202ca8c9106c6841a92ba502547a5f
message:
title: '{{ template "legacy.title" . }}'
text: '{{ template "legacy.content" . }}'
#mobiles: ['156xxxx8827', '189xxxx8325']
(5) 启动钉钉告警插件
cd /usr/local/soft/prometheus-webhook-dingtalk
nohup ./prometheus-webhook-dingtalk --config.file=./config.yml &
(6) 测试
curl http://localhost:8060/dingtalk/webhook1/send -H 'Content-Type: application/json' -d '{"msgtype": "text","text": {"content": "监控告警"}}'
(7) 配置 alertmanager
cd /usr/local/soft/alertmanager/
vim alertmanager.yml
global:
resolve_timeout: 5m
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 5m
receiver: 'dingtalk'
receivers: #配置钉钉告警
- name: 'dingtalk'
webhook_configs:
- url: 'http://localhost:8060/dingtalk/webhook1/send'
send_resolved: true
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']
结合两种方式告警的示例如下:
global:
resolve_timeout: 5m
smtp_smarthost: "smtp.qq.com:465"
smtp_from: "1954938301@qq.com"
smtp_auth_username: "1954938301@qq.com"
smtp_auth_password: "wgwgolvivcogfabj"
smtp_require_tls: false
templates:
- '/usr/local/soft/alertmanager/email.tmpl'
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 5m
receiver: 'dingtalk' #默认告警接收者
routes: #子路由
- receiver: 'email'
match:
severity: 'critical' #标签severity为critical时触发
receivers:
- name: 'email'
email_configs:
- to: 'huy@ktpis.com'
send_resolved: true
html: '{{ template "email.htm" . }}'
headers: { Subject: "[{{ .Status | title }}]{{ .CommonLabels.severity }} {{ .CommonAnnotations.summary }}" }
- name: 'dingtalk'
webhook_configs:
- url: 'http://localhost:8060/dingtalk/webhook1/send'
send_resolved: true
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'dev', 'instance']