一、kube-state-metrics
1.1 kube-state-metrics介绍
github地址:https://github.com/kubernetes/kube-state-metrics
镜像地址:https://hub.docker.com/r/bitnami/kube-state-metrics
博客介绍:https://xie.infoq.cn/article/9e1fff6306649e65480a96bb1
kube-state-metrics是通过监听API Server生成有关资源对象的状态指标,比如Deployment、Node、Pod,需要注意的是kube-state-metrics只是简单的提供一个metrics数据,并不会存储这些指标数据,所以我们可以使用Prometheus来抓取这些数据然后存储,主要关注的是业务相关的一些元数据,比如Deployment、Pod、副本状态等,调度了多少个replicas?现在可用的有几个?多少个Pod是running/stopped/terminated状态?Pod重启了多少次?目前由多少job在运行中
1.2 部署kube-state-metrics
- 编写基于deploy控制器的yaml文件
- 编写svc的yaml文件,端口暴露为NodePort
- 部署
1.3 验证数据
1.4 prometheus数据采集
- job_name: 'kube-state-metrics'
static_configs:
- targets: ["IP:PORT"]
k8s配置文件configmap缩进格式
1.5 验证prometheus状态
1.6 grafana导入模板
- 13824
- 14518
因为版本不同,可根据对应版本进行设置
Dashboard模板网址:https://grafana.com/grafana/dashboards/
二、监控示例
基于第三方exporter实现对目标服务的监控
2.1 tomcat
- 构建镜像
github地址:https://github.com/nlighten/tomcat_exporter
根据tomcat官方镜像添加jar包
ADD metrics.war /data/tomcat/webapps
ADD simpleclient-0.8.0.jar /usr/local/tomcat/lib/
ADD simpleclient_common-0.8.0.jar /usr/local/tomcat/lib/
ADD simpleclient_hotspot-0.8.0.jar /usr/local/tomcat/lib/
ADD simpleclient_servlet-0.8.0.jar /usr/local/tomcat/lib/
ADD tomcat_exporter_client-0.0.12.jar /usr/local/tomcat/lib/
- prometheus采集
- job_name: 'kube-state-metrics'
static_configs:
- targets: ["IP:PORT"]
k8s配置文件configmap缩进格式
- prometheus验证
- grafana导入模板
github地址:https://github.com/nlighten/tomcat_exporter/blob/master/dashboard/example.json
下载这个json文件导入grafana即可
2.2 redis
通过redis_exporter监控redis服务装态
github网址:https://github.com/oliver006/redis_exporter
- 部署redis
一个pod两个容器,redis和redis-exporter
- prometheus采集
- job_name: 'redis-metrics'
static_configs:
- targets: ["IP:PORT"]
k8s配置文件configmap缩进格式
- grafana导入模板
- 14615
- 11692
2.3 mysql
通过mysqld_exporter监控MySQL服务的运行状态
github网址:https://github.com/prometheus/mysqld_exporter
- 安装mariadb-server
apt install -y mariadb
- 修改配置文件/etc/mysql/mariadb.conf.d/50-server.cnf监听地址,修改为0.0.0.0
bind-address = 0.0.0.0
重启mariadb
- 创建mysql_exporter用户
create user 'mysql_exporter'@'localhost' identified by 'password';
- 测试用户名密码连接
mysql -umysql_exporter -hlocalhost -ppassword
- 下载mysql_exporter
# 下载
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.13.0/mysqld_exporter-0.13.0.linux-amd64.tar.gz
# 解压
tar xvf mysqld_exporter-0.13.0.linux-amd64.tar.gz
# 查看启动参数
./mysqld_exporter --help
- 创建免密登陆文件/root/.my.cnf
cat >> /root/.my.cnf <<EOF
[client]
user=mysql_exporter
password=123321
EOF
- 创建mysqld_service文件并启动
# 创建软链接
ln -sv /apps/mysqld_exporter-0.13.0.linux-amd64 /apps/mysqld_exporter
# 创建service文件
cat >> /etc/systemd/system/mysqld_exporter.service <<EOF
[Unit]
Description=Prometheus Mysql Exporter
After=network.target
[Service]
ExecStart=/apps/mysqld_exporter/mysqld_exporter --config.my-cnf=/root/.my.cnf
[Install]
WantedBy=multi-user.target
EOF
# 重新加载配置
systemctl daemon-reload
# 启动mysqld_exporter
systemctl start mysqld_exporter.service
- 验证metrics
- 验证prometheus
- grafana导入模板
- 13106
- 11323
2.4 haproxy
通过haproxy_exporter监控haproxy
github网址:https://github.com/prometheus/haproxy_exporter
- 安装haproxy
apt install -y haproxy
- 修改配置文件,监听一个服务
listen SERVICE
bind BIND_IP:PORT
mode tcp
server SERVER_NAME LISTEN_IP:PORT check inter 3s fall 3 rise 3
确保sock文件是admin用户(level后边的admin)
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
- 重启haproxy
systemctl restart haproxy
检查监听端口是否正常
- 下载haproxy_exporter
# 下载
wget https://github.com/prometheus/haproxy_exporter/releases/download/v0.13.0/haproxy_exporter-0.13.0.linux-amd64.tar.gz
# 解压
tar xvf haproxy_exporter-0.13.0.linux-amd64.tar.gz
# 创建软链接
ln -sv /apps/haproxy_exporter-0.13.0.linux-amd64 /apps/haproxy_exporter
- 配置文件启动haproxy_expoter
./haproxy_exporter --haproxy.scrape-uri=unix:/run/haproxy/admin.sock
端口默认监听9101
- 配置haproxy状态页
listen stats
bind :PORT
stats enable
stats uri /haproxy-status
stats realm HAProxy\ Stats\ Page
stats auth haadmin:123456
stats auth admin:123456
编辑/etc/haproxy/haproxy.cfg添加如上配置内容
- 状态页启动haproxy
./haproxy_exporter --haproxy.scrape-uri="http://admin:123456@127.0.0.1:PORT/haproxy-status;csv"
需要指定用户名密码,csv是指定以csv形式展示
- 验证exporter
- prometheus数据采集
- job_name: "haproxy-exporter"
static_configs:
- targets: ["127.0.0.1:9101"]
虚拟机prometheus.yml配置缩进格式
./promtool check config prometheus.yml # 修改后检查配置文件是否正确
- 重启prometheus
systemctl restart prometheus.service
- 验证prometheus
- grafana导入模板
- 367
- 2428
2.5 nginx
通过nginx_exporter监控ngix
github模块依赖网址:https://github.com/vozlt/nginx-module-vts
- 安装nginx
# 克隆依赖模块
git clone https://github.com/vozlt/nginx-module-vts.git
# 下载nginx源码
wget http://nginx.org/download/nginx-1.20.2.tar.gz
# 解压
tar xvf nginx-1.20.2.tar.gz
# 安装nginx编译依赖包
apt install -y libgd-dev libgeoip-dev libpcre3 libpcre3-dev libssl-dev gcc make
# 编译nginx
cd nginx-1.20.2
./configure --prefix=/apps/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-pcre \
--with-file-aio \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module \
--add-module=/usr/local/src/nginx-module-vts/
# make
make
# make install
make install
- 修改配置文件
http {
vhost_traffic_status_zone;
...
server {
...
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
}
}
}
- 启动nginx
# 检查配置文件
/apps/nginx/sbin/nginx -t
# 启动nginx
/apps/nginx/sbin/nginx
- 配置nginx的upstream
# http模块里边,server模块同级
upstream SERVICE {
server IP:PORT;
}
# server模块里边,转发首页
location / {
#root html;
#index index.html index.htm;
proxy_pass http://SERVICE;
}
- 检查状态页
可以以json模式显示数据
- 安装nginx_exporter
# 下载
wget https://github.com/hnlq715/nginx-vts-exporter/releases/download/v0.10.3/nginx-vts-exporter-0.10.3.linux-amd64.tar.gz
# 解压
tar xvf nginx-vts-exporter-0.10.3.linux-amd64.tar.gz
# 创建软链接
ln -sv /apps/nginx-vts-exporter-0.10.3.linux-amd64 nginx-vts-exporter
# 启动nginx_exporter
./nginx-vts-exporter -nginx.scrape_uri http://IP/status/format/json
默认监听端口号9913
- 验证数据
- prometheus数据采集
- job_name: "nginx-exporter"
static_configs:
- targets: ["127.0.0.1:9913"]
虚拟机prometheus.yml配置文件缩进格式
- prometheus验证数据
- grafana导入模板
- 2949
2.6 blockbox监控url
官方地址:https://prometheus.io/download/#blackbox_exporter
blockbox_exporter是prometheus官方提供的一个exporter,可以通过http,https,dns,tcp和icmp对被监控节点进行监控和数据采集
http/https:url/api可用性检测
TCP:端口监听检测
ICMP:主机存活检测
DNS:域名解析
- 部署blackbox_exporter
# 下载
wget https://github.com/prometheus/blackbox_exporter/releases/download/v0.19.0/blackbox_exporter-0.19.0.linux-amd64.tar.gz
# 解压
tar xvf blackbox_exporter-0.19.0.linux-amd64.tar.gz
# 创建软链接
ln -sv /apps/blackbox_exporter-0.19.0.linux-amd64 blackbox_exporter
- 创建blackbox-exporter.service文件
cat > /etc/systemd/system/blackbox-exporter.service <<EOF
[Unit]
Description=Prometheus Blackbox Exporter
Documentation=https://prometheus.io/download/#blackbox_exporter
After=network.target
[Service]
Type=simple
User=root
Group=root
Restart=on-failure
ExecStart=/apps/blackbox_exporter/blackbox_exporter --config.file=/apps/blackbox_exporter/blackbox.yml --web.listen-address=:9115
[Install]
WantedBy=multi-user.target
EOF
- 启动blackbox_exporter
systemctl daemon-reload
systemctl restart blackbox-exporter
- 验证数据
默认监听端口9115
- blackbox exporter监控url
prometheus数据采集
- job_name: "http_status"
metrics_path: /probe
params:
module: [http_2xx]
static_configs:
- targets: ["domainname1","domainname2"]
labels:
instance: http_status
group: web
relabel_configs:
- source_labels: [__address__] # relbel通过将__address__(当前目标地址)写入__param_tartget标签来创建一个label
target_label: __param_target # 监控目标domainname,作为__address__的value
- source_labels: [__param_target] # 监控目标
target_label: url # 将监控目标与url创建一个label
- target_label: __address__
replacement: BLACKBOX_EXPORTER:PORT
虚拟机prometheus.yml配置文件缩进格式
- 验证prometheus状态
- 查看blackbox页面
- blockbox_exporter监控icmp
prometheus数据采集
- job_name: "ping_status"
metrics_path: /probe
params:
module: [icmp]
static_configs:
- targets: ["IP1","IP2"]
labels:
instance: 'ping_status'
group: 'icmp'
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: ip # 将ip与__param_target创建一个label
- target_label: __address__
replacement: BLACKBOX_EXPORTER:PORT
虚拟机prometheus.yml配置文件缩进格式
- 验证prometheus状态
- blackbox_exporter监控端口
prometheus数据采集
# 端口监控
- job_name: "port_status"
metrics_path: /probe
params:
module: [tcp_connect]
static_configs:
- targets: ["IP:PORT","IP:PORT"]
labels:
instance: 'port_status'
group: 'port'
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: ip
- target_label: __address__
replacement: BLACKBOX_EXPORTER:PORT
- 验证prometheus状态
- grafana导入模板
- 9965
- 13587
三、告警
3.1 Alertmanager
prometheus-->触发阈值-->超出持续时间-->alertmanager-->分组|抑制|静默-->媒体类型-->邮件|钉钉|微信等
prometheus server通过配置监控规则,实现告警发送,然后把告警push给Alertmanager,匹配Alertmanager配置的Router,以WeChat、Email或Webhook方式发送给对应的Receiver
分组(group):将类似性质的告警合并为单个通知,比如网络通知、主机通知、服务通知
静默(silences):是一种简单的特定时间静音的机制,例如:服务器要升级维护可以先设置这个时间段告警静默
抑制(inhibition):当告警发出后,停止重复发送由此告警引发的其他告警;即合并由一个故障引起的多个告警事件,可以消除冗余告警
- 安装alertmanager
# 下载
wget https://github.com/prometheus/alertmanager/releases/download/v0.23.0/alertmanager-0.23.0.linux-amd64.tar.gz
# 解压
tar xvf alertmanager-0.23.0.linux-amd64.tar.gz
# 创建软链接
ln -sv /apps/alertmanager-0.23.0.linux-amd64 /apps/alertmanager
- 创建alertmanager.service文件
cat > /etc/systemd/system/alertmanager.service <<EOF
[Unit]
Description=Prometheus alertmanager
After=network.target
[Service]
ExecStart=/apps/alertmanager/alertmamager --config.file="/apps/alertmanager/alertmanager.yml"
[Install]
WantedBy=multi-user.target
EOF
- 启动alertmanager
systemctl start alertmanager.service
默认监听端口9093,9094
监控配置官方网址:https://prometheus.io/docs/alerting/latest/configuration/
- 验证alertmanager状态
3.2 邮件
官方网址:https://prometheus.io/docs/alerting/latest/configuration/#email_config
- 配置文件介绍
alertmanager.yml配置文件
global:
resolve_timeout: 5m # alertmanager在持续多久没有收到新告警后标记为resolved
smtp_from: # 发件人邮箱地址
smtp_smarthost: # 邮箱smtp地址
smtp_auth_username: # 发件人的登陆用户名,默认和发件人地址一致
smtp_auth_password: # 发件人的登陆密码,有时候是授权码
smtp_hello:
smtp_require_tls: # 是否需要tls协议。默认是true
route:
group_by: [alertname] # 通过alertname的值对告警进行分类
group_wait: 10s # 一组告警第一次发送之前等待的时延,即产生告警10s将组内新产生的消息合并发送,通常是0s~几分钟(默认是30s)
group_interval: 2m # 一组已发送过初始告警通知的告警,接收到新告警后,下次发送通知前等待时延,通常是5m或更久(默认是5m)
repeat_interval: 5m # 一组已经发送过通知的告警,重复发送告警的间隔,通常设置为3h或者更久(默认是4h)
receiver: 'default-receiver' # 设置告警接收人
receivers:
- name: 'default-receiver'
email_configs:
- to: 'EMAIL@DOMAIN.com'
send_resolved: true # 发送恢复告警通知
inhibit_rules: # 抑制规则
- source_match: # 源匹配级别,当匹配成功发出通知,其他级别产生告警将被抑制
severity: 'critical' # 告警时间级别(告警级别根据规则自定义)
target_match:
severity: 'warning' # 匹配目标成功后,新产生的目标告警为'warning'将被抑制
equal: ['alertname','dev','instance'] # 基于这些标签抑制匹配告警的级别
# 时间示例解析 # group_wait: 10s # 第一次产生告警,等待10s,组内有新增告警,一起发出,没有则单独发出 # group_interval: 2m # 第二次产生告警,先等待2m,2m后没有恢复就进入repeat_interval # repeat_interval: 5m # 在第二次告警时延过后,再等待5m,5m后没有恢复,就发送第二次告警
如上配置,如果告警没有恢复,第二次告警会等待2m+5m,即7分钟后发出
- 配置告警规则
groups:
- name: alertmanager_pod.rules
rules:
- alert: Pod_all_cpu_usage
expr: (sum by(name)(rate(container_cpu_usage_seconds_total{image!=""}[5m]))*100) > 1
for: 2m
labels:
serverity: critical
service: pods
annotations:
description: 容器 {{ $labels.name }} CPU 资源利用率大于 10% , (current value is {{ $value }})
summary: Dev CPU 负载告警
- alert: Pod_all_memory_usage
expr: sort_desc(avg by(name)(irate(node_memory_MemFree_bytes {name!=""}[5m]))) > 2147483648 # 内存大于2G
for: 2m
labels:
severity: critical
annotations:
description: 容器 {{ $labels.name }} Memory 资源利用大于 2G , (current value is {{ $value }})
summary: Dev Memory 负载告警
- alert: Pod_all_network_receive_usage
expr: sum by(name)(irate(container_network_reveive_bytes_total{container_name="POD"}[1m])) > 52428800 # 大于50M
for: 2m
labels:
severity: critical
annotations:
description: 容器 {{ $labels.name }} network_receive 资源利用大于 50M , (current value is {{ $value }})
- alert: node内存可用大小
expr: node_memory_MemFree_bytes < 4294967296 # 内存小于4G
for: 2m
labels:
severity: critical
annotations:
description: node可用内存小于4G
在/apps/prometheus/目录下创建rules目录,创建pods_rule.yaml文件,内容如上
注意缩进格式,如果文件格式有误,重启prometheus的时候,promethues会一直起不来,可以先用promtool检查配置文件格式,因为加载告警配置的时候,引入了这个文件,所以在检查promethues.yml文件的时候也会检查自定义的pods_rule.yaml文件
- promethues加载告警配置
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
- IP:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
- "/apps/prometheus/rules/pods_rule.yaml"
注:如果修改rule_files中的内容,需要先重启prometheus,加载修改后的配置,然后修改alertmanager,不然修改后的告警内容不会生效
- 重启prometheus
systemctl restart prometheus.service
- 验证prometheus状态
在prometheus页面,点击Alerts查看告警状态,当前为PENDING,说明已经检测到告警,还没满足发邮件的时间规则
FIRING证明告警已成功,此时应该已经收到邮件
- 查看alertmanager告警
- 查看告警邮件
点击Source链接,跳转的是主机名加prometheus-server的端口,无法解析就跳转不过去
- 使用amtool查看告警
./amtool alert --alertmanager.url=http://IP:9093
3.3 钉钉
- 钉钉添加机器人
创建机器人官方网址:https://open.dingtalk.com/document/robots/custom-robot-access
- 发送消息脚本
vim /data/scripts/dingding-keywords.sh
MESSAGE=$1
/usr/bin/curl -X POST 'https://oapi.dingtalk.com/robot/send?access_token=TOKEN'\
-H 'Content-Type: application/json' \
-d '{"msgtype": "text",
"text": {
"content": "${MESSAGE}"
}
}'
- 测试发送消息
发送的消息内容中,必须包含自定义的关键字,不然发送消息会失败,发送脚本发送消息成功后,群里会收到
- 部署webhook-dingtalk
# 下载
wget https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v1.4.0/prometheus-webhook-dingtalk-1.4.0.linux-amd64.tar.gz
# 解压
tar xvf prometheus-webhook-dingtalk-1.4.0.linux-amd64.tar.gz
# 创建软链接
ln -sv /apps/prometheus-webhook-dingtalk-1.4.0.linux-amd64 prometheus-webhook-dingtalk
下载的webhook-dingtalk版本最好跟这个保持一直,新版本有些地方不兼容
- 启动webhook-dingtalk
cd /apps/prometheus-webhook-dingtalk
./prometheus-webhook-dingtalk --web.listen-address="0.0.0.0:8060" --ding.profile="KEYWORD=https://oapi.dingtalk.com/robot/send?access_token=TOKEN"
指定监听端口8060
KEYWORD必须是创建机器人时的自定义关键字,不然告警发布出去,会报错
- 配置alertmanager
- name: 'dingding'
webhook_configs:
- url: 'http://IP:8060/dingtalk/alertsen/send'
send_resolved: true
- 重启alertmanager
systemctl restart alertmanager.service
prometheus加载的alertmanager告警规则里边,也必须含有自定义关键字才可以告警出来,不然也会报错"keywords not in content",自定义关键字在key还是value中,都可以
- 验证发送告警信息
- 查看dingtalk日志
返回码为200
- 查看钉钉消息
- 钉钉标签签名python脚本
dingtalk签名脚本官方网址:https://open.dingtalk.com/document/robots/customize-robot-security-settings
#python 3.8
import time
import hmac
import hashlib
import base64
import urllib.parse
timestamp = str(round(time.time() * 1000))
secret = 'this is secret'
secret_enc = secret.encode('utf-8')
string_to_sign = '{}\n{}'.format(timestamp, secret)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
print(timestamp)
print(sign)
注意python版本,按照示例指定版本,执行用"/usr/bin/python3.8 脚本名字"启动
- 钉钉发送消息shell脚本
#!/bin/bash
source /etc/profile
MESSAGE=$1
secret='SECxxxxxx'
getkey=$(/usr/bin/python3.8 SCRIPT)
timestamp=${getkey:0:13}
sign=$(echo "${getkey:13:100}"|tr -d '\n')
DateStamp=$(date -d @${getkey:0:10} "+%F %H:%m%s")
/usr/bin/curl -X POST "https://oapi.dingtalk.com/robot/send?access_token=xxxxxx×tamp=${timestamp}&sign=${sign}" \
-H 'Content-Type: application/json' \
-d '{"msgtype":"text",
"text":{
"content": "'${MESSAGE}'"
}
}'
- alertmanager发送告警
prometheus-webhook-dingtalk配置文件
targets:
webhook1:
url: https://oapi.dingtalk.com/robot/send?access_token=xxxxxx
# secret for signature
secret: SECxxxxxx
指定token和secret
alertmanager配置文件
- name: 'dingding'
webhook_configs:
- url: 'http://IP:8060/dingtalk/webhook1/send' # webhook1对应prometheus-webhook-dingtalk配置文件中的名字
send_resolved: true
- 启动prometheus-webhook-dingtalk
./prometheus-webhook-dingtalk --web.listen-address="0.0.0.0:8060" --config.file=config.yml
启动程序和配置文件同路径下可不指定"--config.file"
prometheus配置不需要改动
- dingtalk日志
- 钉钉
3.4 消息分类发送
根据消息中的属性信息设置规则,将消息分类发送,修改alertmanager配置文件
route:
group_by: [alertname]
group_wait: 10s
group_interval: 10s
repeat_interval: 2m
receiver: 'dingding'
# 添加路由信息
routes:
- receiver: email
group_wait: 10s
match_re:
instance: "IP:PORT" # 匹配成功的信息发邮件出来,其余信息发给钉钉
修改配置文件后,重启alertmanager
- 验证消息发送
钉钉发送两台主机告警信息
邮件发送一台主机告警信息(匹配成功instance,需要包括端口号)
3.5 自定义告警模板
- 告警规则
groups:
- name: 'node running status'
rules:
- alert: 'Instance Down'
expr: 'up == 0'
for: 5s
annotations:
title: 'Instance Down'
description: "{{ $labels.instance }}down"
labels:
robot: 'jcss'
severity: 'warning'
owner: 'xxxxxxxxxxx'
- name: 'node memory usage'
rules:
- alert: 'memory usage'
expr: '((node_memory_MemTotal_bytes - node_memory_MemFree_bytes) / node_memory_MemTotal_bytes * 100)> 85'
for: 5s
annotations:
title: 'Mem'
description: '{{ $labels.instance }} Memusage {{ $value }}'
labels:
robot: 'jcss'
ops: 'true'
severity: 'warning'
owner: "xxxxxxxxxxx"
- 自定义模板(wechat)
{{ define "wechat.default.message" }}
{{ range $i, $alert :=.Alerts }}
=======alertmanager监控告警======
告警状态: {{ .Status }}
告警级别: {{ $alert.Labels.severity }}
告警类型: {{ $alert.Labels.alertname }}
告警应用: {{ $alert.Annotations.summary }}
告警主机: {{ $alert.Labels.instance }}
告警主题: {{ $alert.Annotations.summary }}
告警阀值: {{ $alert.Annotations.value }}
告警详情: {{ $alert.Annotations.description }}
告警时间: {{ $alert.StartsAt.Format "2006-01-02 15:04:05" }}
================end===============
{{ end }}
{{ end }}
- 自定义模板(dingding)
{{ define "__subject" }}
[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}]
{{ end }}
{{ define "__alert_list" }}{{ range . }}
---
{{ if .Labels.owner }}@{{ .Labels.owner }}{{ end }}
**告警名称**: {{ index .Annotations "title" }}
**告警级别**: {{ .Labels.severity }}
**告警主机**: {{ .Labels.instance }}
**告警信息**: {{ index .Annotations "description" }}
**告警时间**: {{ dateInZone "2006.01.02 15:04:05" (.StartsAt) "Asia/Shanghai" }}
{{ end }}{{ end }}
{{ define "__resolved_list" }}{{ range . }}
---
{{ if .Labels.owner }}@{{ .Labels.owner }}{{ end }}
**告警名称**: {{ index .Annotations "title" }}
**告警级别**: {{ .Labels.severity }}
**告警主机**: {{ .Labels.instance }}
**告警信息**: {{ index .Annotations "description" }}
**告警时间**: {{ dateInZone "2006.01.02 15:04:05" (.StartsAt) "Asia/Shanghai" }}
**恢复时间**: {{ dateInZone "2006.01.02 15:04:05" (.EndsAt) "Asia/Shanghai" }}
{{ end }}{{ end }}
{{ define "default.title" }}
{{ template "__subject" . }}
{{ end }}
{{ define "default.content" }}
{{ if gt (len .Alerts.Firing) 0 }}
**====侦测到{{ .Alerts.Firing | len }}个故障====**
{{ template "__alert_list" .Alerts.Firing }}
---
{{ end }}
{{ if gt (len .Alerts.Resolved) 0 }}
**====恢复{{ .Alerts.Resolved | len }}个故障====**
{{ template "__resolved_list" .Alerts.Resolved }}
{{ end }}
{{ end }}
{{ define "ding.link.title" }}{{ template "default.title" . }}{{ end }}
{{ define "ding.link.content" }}{{ template "default.content" . }}{{ end }}
{{ template "default.title" . }}
{{ template "default.content" . }}
default.yml定义在prometheus-webhook-dingtalk目录下
- 引用模板
修改alertmanager配置文件,引用模板
template:
- "/apps/prometheus-webhook-dingtalk/templates/default.templ" # 引用模板
在alertmanager中引用模板,dingtalk的告警时间,alertmanager不识别,加进去"dateInZone"那行alertmanger起不来,去掉才可以
- dingtalk验证
修改prometheus-webhook-dingtalk的config.yml文件,引用模板
templates:
- /apps/prometheus-webhook-dingtalk/templates/default.templ
这里引用模板文件,可以识别告警时间信息
- dingtalk验证
3.6 告警抑制与静默
- 告警抑制
基于告警规则,资源使用率超过80%就不再发60%的告警,即60%的表达式触发的告警被抑制了
- name: alertmanager_node.rules
rules:
- alert: 磁盘容量
expr: 100-(node_filesystem_free_bytes{fstype=~"ext4|xfs"}/node_filesystem_size_bytes {fstype=~"ext4|xfs"}*100) > 80 #磁盘容量利用率大于80%
for: 2s
labels:
severity: critical
annotations:
summary: "{{$labels.mountpoint}} 磁盘分区使用率过高!"
description: "{{$labels.mountpoint }} 磁盘分区使用大于80%(目前使用:{{$value}}%)"
- alert: 磁盘容量
expr: 100-(node_filesystem_free_bytes{fstype=~"ext4|xfs"}/node_filesystem_size_bytes {fstype=~"ext4|xfs"}*100) > 60 #磁盘容量利用率大于60%
for: 2s
labels:
severity: warning
annotations:
summary: "{{$labels.mountpoint}} 磁盘分区使用率过高!"
description: "{{$labels.mountpoint }} 磁盘分区使用大于80%(目前使用:{{$value}}%)"
- 钉钉告警验证
- 钉钉恢复验证
告警的时候只有>80%,恢复的时候是两个,>60%和>80%
- 告警静默
手动静默:先找到要静默的告警事件,然后手动静默指定的事件
查看静默事件
点击Expire,静默事件失效,继续发送告警
3.7 Alertmanager高可用
- 基于负载均衡
alertmanager是http的单次调用,不需要会话保持,所以可以部署多态alertmanager,在前边加上负载均衡器,可以通过vip做成主备或者轮训方式
- 基于Gossip机制
Gossip机制为多个Alertmanager之间提供了信息传递的机制。确保及时在多个Alertmanager分别接收到相同告警信息的情况下,也只有一个告警通知被发送给Receiver
gossip协议: Gossip是分布式系统中被广泛使用的协议,用于实现分布式节点之间的信息交换和状态同步。Gossip协议同步状态类似于流言或者病毒的传播
- 搭建本地集群环境
为了能够让Alertmanager节点之间进行通讯,需要在Alertmanager启动时设置相应的参数。其中主要的参数包括:
--cluster.listen-address string: 当前实例集群服务监听地址
--cluster.peer value: 初始化时关联的其它实例的集群服务地址
3.8 PrometheusAlert
github地址:https://github.com/feiyu563/PrometheusAlert
PrometheusAlert是开源的运维告警中心消息转发系统,支持主流的监控系统Prometheus、Zabbix,日志系统Graylog2,Graylog3、数据可视化系统Grafana、SonarQube。阿里云-云监控,以及所有支持WebHook接口的系统发出的预警消息,支持将收到的这些消息发送到钉钉,微信,email,飞书,腾讯短信,腾讯电话,阿里云短信,阿里云电话,华为短信,百度云短信,容联云电话,七陌短信,七陌语音,TeleGram,百度Hi(如流)等。
四、Pushgateway
4.1 pushgateway简介
github地址:https://github.com/prometheus/pushgateway
pushgateway是采用被动推送的方式,而不是类似于prometheus server主动连接exporter获取监控数据,pushgateway可以单独运行在一个节点,然后需要自定义监控脚本把需要监控的数据主动推送给pushgateway的API接口,然后pushgateway再等待prometheus server抓取数据,即pushgateway本身没有任何抓取监控数据的功能,pushgateway只是被动的等待数据从客户端推送过来
--persistence.file="" # 数据保存的文件,默认只保存在内存中
--persistence.interval=5m # 数据持久化的间隔时间
4.2 部署pushgateway
- 下载并启动
# 下载
wget https://github.com/prometheus/pushgateway/releases/download/v1.4.2/pushgateway-1.4.2.linux-amd64.tar.gz
# 解压
tar xvf pushgateway-1.4.2.linux-amd64.tar.gz
# 创建软链接
ln -sv pushgateway-1.4.2.linux-amd64 pushgateway
# 启动
cd pushgateway
./pushgateway
默认监听端口9091
- 验证pushgateway页面
4.3 prometheus采集数据
- job_name: "pushgateway-monitor"
scrape_interval: 5s
static_configs:
- targets: ["IP:9091"]
honor_labels: true # 保留抓取数据原标签
配置prometheus.yml文件,重启prometheus
honor_labels控制prometheus如何处理已经存在于抓取数据中的标签与prometheus将附加的服务器端的标签之间的冲突("job"和"instance"标签,手动配置的目标标签以及服务发现生成的标签);如果honor_labels设置为"true",则通过保留已抓取数据的标签值并忽略冲突的服务器端标签,如果设置为"false",则通过将已抓取数据中的冲突标签重命名为"exported_<original-label>"(例如"exporterd_instance","exported_job"),然后附加服务器端标签
- 验证prometheus页面
4.4 推送数据
- 推送单条数据
要push数据到pushgateway中,可以通过API标准接口来添加,默认URL为:
http://ip:9091/metrics/job/JOBNAME{/LABEL_NAME/LABEL_VALUE}
其中JOBNAME是必填项,为job标签值,后边可以跟任意数量的标签对,一般我们会添加一个instance/INSTANCE_NAME实例名称标签,来方便区分各个指标
# 推送job名称为test_job,key为metrics,值为111
echo "test_job 111" | curl --data-binary @- http://PUSHGATEWAY_IP:9091/metrics/job/test_job
# 推送job名称为test_job,key为metrics,值为111,instance为UPLOAD_IP
echo "test_job 111" | curl --data-binary @- http://PUSHGATEWAY_IP:9091/metrics/job/test_job/instance/UPLOAD_IP
往相同的metrics中push数据,之前的key会被新的key覆盖掉
- pushgateway数据验证
- 推送多条数据
cat << EOF | curl --data-binary @- http://PUSHGATEWAY_IP:9091/metrics/job/test_job/instance/UPLOAD_IP
#TYPE node_memory_usage gauge
node_memory_usage 4311744512
# TYPE memory_total gauge
node_memory_total 103481868288
EOF
- pushgateway数据验证
- prometheus验证
4.5 自定义收集数据
- 自定义脚本
#!/bin/bash
total_memory=$(free | awk '/Mem/{print $2}')
used_memory=$(free | awk '/Mem/{print $3}')
job_name="custom_memory_monitor"
instance_name=`ifconfig ens33 | grep -w inet | awk '{print $2}'`
pushgateway_server="http://PUSHGATEWAY_IP:9091/metrics/job"
cat <<EOF | curl --data-binary @- ${pushgateway_server}/${job_name}/instance/${instance_name}
#TYPE node_memory_usage gauge 4G
node_memory_usage 4311744512
# TYPE memory_total gauge 96G
node_memory_total 103481868288
EOF
内存监控脚本,mem_monitor.sh 分别在不通的主机执行脚本,验证指标收集和推送
- pushgateway验证
4.6 删除数据
先对一个组写入多个instance数据
- pushgateway验证多条数据
- 通过api删除指定组内指定实例的数据
curl -X DELETE http://PUSHGATEWAY_IP:9091/metrics/job/custom_memory_monitor/instance/UPLOAD_IP
- pushgateway验证删除组内实例
- 通过web界面删除
五、联邦集群
一台server,两台联邦,两台node,配置prometheus和node_exporter
- 分别添加target
- job_name: "prometheus-node1"
static_configs:
- targets: ["PROMETHEUS1:9100"]
promethues联邦二配置同理
- prometheus验证数据
另一个数据同理
- 配置采集数据prometheus-server
- job_name: "prometheus-federate-1"
scrape_interval: 10s
honor_labels: true
metrics_path: '/federate'
params:
'match[]':
- '{job="prometheus"}'
- '{__name__=~"job:.*"}'
- '{__name__=~"node.*"}'
static_configs:
- targets: ["PROMETHEUS1:9090"]
- job_name: "prometheus-federate-2"
scrape_interval: 10s
honor_labels: true
metrics_path: '/federate'
params:
'match[]':
- '{job="prometheus"}'
- '{__name__=~"job:.*"}'
- '{__name__=~"node.*"}'
static_configs:
- targets: ["PROMETHEUS2:9090"]
- prometheus-server验证
- prometheus-server查询数据验证
prometheus-node1和prometheus-node2的job被联邦节点收集数据后,又被prometheus-server端收集数据
- grafana导入模板
模板ID:8919
六、Prometheus存储
6.1 本地存储
Prometheus有着非常高效的时间序列数据存储方法,每个采样数据仅仅占用3.5byte左右空间,上百万条时间序列,30s间隔,保留60天,大概200多G空间(引用官方内容)
- block简介
每个block为一个data目录中以01开头的存储目录
# ll data
drwxr-xr-x 3 root root 4096 Mar 31 12:39 01FZFZSNX1SJFCKQYZAAN2J6AG/ # block
drwxr-xr-x 2 root root 4096 Mar 31 12:39 wal/ # write ahead log
默认情况下,prometheus将采集到的数据存储到本地的TSDB数据库中,路径默认为prometheus安装目录的data目录,数据写入过程为先把数据写入wal日志并放在内存,然后2小时后将内存数据保存至一个新的block块,同时再把新采集的数据写入内存,然后在2小时后再保存到一个新的block块,以此类推
- block特性
block会压缩、合并历史数据库,以及删除过期的块,随着压缩、合并,block的数量会减少,在压缩过程中会发生三件事:定制执行压缩、合并小的block到大的block、清理过期的块
tree 01FZFZSNX1SJFCKQYZAAN2J6AG/
01FZFZSNX1SJFCKQYZAAN2J6AG/
├── chunks
│ └── 000001 # 数据目录,每个大小为512M,超过会被切成多个
├── index # 索引文件,记录存储的数据索引信息,通过文件内的几个表来查找时序数据
├── meta.json # block元数据信息,包括了样本数、采集数据的起始时间、压缩历史
└── tombstones # 逻辑数据,主要记载删除记录和标记要删除的内容,删除标记,在查询块时排除样本
- 本地存储配置参数
--config.file="prometheus.yml" # 指定配置文件
--web.listen-address="0.0.0.0:9090" # 指定监听地址
--storage.tsdb.path="data/" # 指定数据存储目录
--storage.tsdb.retention.time=y, w, d, h, m, s, ms # 数据保存时长,默认是15天
--storage.tsdb.retention.size=B, KB, MB, GB, TB, PB, EB. # 指定chunk大小,默认 "512MB"
--query.timeout=2m # 默认最大查询超时时间
--query.max-concurrency=20 #默认最大查询并发数
--web.read-timeout=5m # 默认最大空闲超时时间
--web.max-connections=512 # 默认最大并发链接数
--web.enable-lifecycle # 启用或关闭API动态加载配置功能
6.2 远端存储Victoriametrics
github网址:https://github.com/VictoriaMetrics/VictoriaMetrics
官方文档网址:https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html
- 单机部署
# 下载
wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.71.0/victoria-metrics-amd64-v1.71.0.tar.gz
# 解压
tar xvf victoria-metrics-amd64-v1.71.0.tar.gz
启动参数
-httpListenAddr=0.0.0.0:8428 # 默认监听地址及端口
-storageDataPath # 数据存放目录,默认在启动目录下创建victoria-metrics-data
-retentionPeriod # h (hour), d (day), w (week), y (year),默认单位是月,保留一个月
启动
mv victoria-metrics-prod /usr/local/bin/
# 创建service文件
cat >> /etc/systemd/system/victoria-metrics-prod.service <<EOF
[Unit]
Description=victoria-metrics-prod
Documentation=https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html
After=network.target
[Service]
Restart=on-failure
ExecStart=/usr/local/bin/victoria-metrics-prod -storageDataPath=/data/victoria -retentionPeriod=3
[Install]
WantedBy=multi-user.target
EOF
# 加载配置文件
systemctl daemon-reload
# 启动
systemctl start victoria-metrics-prod.service
验证victoria页面
vitoria ui页面
prometheus配置
remote_write:
- url: http://192.168.96.161:8428/api/v1/write
配置完成后重启prometheus
victoria ui数据展示
若一直没有数据,需要开启导航栏的Auto-refresh按钮,然后时间选最近5分钟
查询的数据是vitoria存储目录的数据,而不是prometheus本地的data数据目录的数据
grafana配置
添加数据源:类型为prometheus,地址及端口为vitoriametrics服务器的ip和端口
模板ID:8919
- docker-compose
github网址:https://github.com/VictoriaMetrics/VictoriaMetrics/tree/cluster/deployment/docker
安装docker-compose,克隆代码,进入目录,docker-compose up -d
是单机版启动
- 集群部署
组件介绍
vminsert:写入组件(写),负责接收数据写入并根据对度量名称及其所有标签的一直hash结果将数据分散写入不同的后端vmstorage节点,vmstorage负责持久化数据,vminsert默认端口8400
vmstorage:查询原始数据并返回给指定时间范围内给定标签过滤器的查询数据,默认端口8482
vmselect:查询组件(读),连接vmstorage,默认端口8401
其他可选组件
vmagnet:是一个很小但功能强大的代理,它可以从node_exporter各种来源收集度量数据,并将他们存储在victoriametrics或任何其他支持远程写入协议的与prometheus兼容的存储系统中
vmalert:替换prometheus server,以vitoriametrics为数据源,基于兼容prometheus的告警规则,判断数据是否异常,并将产生的通知发送给alertmanager
vmgateway:读写victoriametrics数据的代理网关,可实现限速和访问控制等功能,目前企业版组件
vmctl:victoriametrics的命令行工具,目前主要用于将prometheus、opentsdb等数据源的数据迁移,迁移到victoriametrics
下载
# 下载
wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.71.0/victoria-metrics-amd64-v1.71.0-cluster.tar.gz
# 解压
tar xvf victoria-metrics-amd64-v1.71.0-cluster.tar.gz
mv vm* /usr/local/bin/
选择三台主机,每台主机都需要下载安装
主要参数
-httpListenAddr string # vmselect
Address to listen for http connections (default ":8481")
-vminsertAddr string # vmstorage
TCP address to accept connections from vminsert services (default ":8400")
-vmselectAddr string # vmstorage
TCP address to accept connections from vmselect services (default ":8401")
部署vmstorage-prod组件
vmstorage负责数据的持久化,监听端口:API 8482,数据写入端口8400,数据读取端口:8401
# 创建service文件
cat >> /etc/systemd/system/vmstorage.service <<EOF
[Unit]
Description=Vmstorage Server
After=network.target
[Service]
Restart=on-failure
WorkingDirectory=/tmp
ExecStart=/usr/local/bin/vmstorage-prod --loggerTimezone Asia/Shanghai -storageDataPath /data/victoriametrics-cluster/vmstorage -httpListenAddr :8482 -vminsertAddr :8400 -vmselectAddr :8401
[Install]
WantedBy=multi-user.target
EOF
# 启动
systemctl daemon-reload
systemctl start vmstorage.service
注意操作系统不同,可能配置文件路径不一样
vmstorage在cluster模式下,有三个端口,8482端口是API端口,8400是端口给vminsert写数据的,8401端口是给vmselect查询数据的
部署vminsert-prod组件
# 创建service文件
cat >> /etc/systemd/system/vminsert.service <<EOF
[Unit]
Description=Vminsert Server
After=network.target
[Service]
Restart=on-failure
WorkingDirectory=/tmp
ExecStart=/usr/local/bin/vminsert-prod -httpListenAddr :8480 -storageNode=IP1:8400,IP2:8400,IP3:8400
[Install]
WantedBy=multi-user.target
EOF
# 启动
systemctl daemon-reload
systemctl start vminsert.service
注意组件名字后边的-prod,不要忘了写
vminsert监听端口8480
部署vmselect-prod组件
# 创建service文件
cat >> /etc/systemd/system/vmselect.service <<EOF
[Unit]
Description=Vmselect Server
After=network.target
[Service]
Restart=on-failure
WorkingDirectory=/tmp
ExecStart=/usr/local/bin/vmselect-prod -httpListenAddr :8481 -storageNode=IP1:8401,IP2:8401,IP3:8401
[Install]
WantedBy=multi-user.target
EOF
# 启动
systemctl daemon-reload
systemctl start vmselect.service
vmselect 监听端口8481
验证集群服务端口
curl http://IP:8480/metrics # vminsert
curl http://IP:8481/metrics # vmselect
curl http://IP:8482/metrics # vmstorage
三个服务器都需要验证
验证vmselect监听端口页面
prometheus配置
remote_write:
- url: http://IP1:8480/insert/0/prometheus # 配置的端口是vminsert的监听端口
- url: http://IP2:8480/insert/0/prometheus
- url: http://IP3:8480/insert/0/prometheus
配置的端口是vminsert的监听端口
配置grafana,添加数据源
http://IP1:8481/select/0/prometheus
grafana只能配置一个地址,可以搭建负载均衡器,写负载均衡的ip,读取数据的路径需要跟prometheus的配置文件中保持一致,insert是写,select是读,后边两段uri需要一致,不然读不到数据
grafana模板
8919、13824
- 开启数据复制
官方网址:https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#replication-and-data-safety
默认情况下,数据被vminsert的组件基于hash算法分别将数据持久化到不同的vmstorage节点
开启数据复制是启用vminsert组件支持的-replicationFactor=n(n代表几份)复制功能,将数据分别在各节点保存一份完整的副本以实现数据的高可用