本文来源公众号“马哥Linux运维”,仅用于学术分享,侵权删,干货满满。
原文链接:https://mp.weixin.qq.com/s/X4ADdHOXtQw5Hy5iQSal8A
文章略长,分为(一)、(二)、(三)和(四)两部分,一起学习吧!
马哥Linux运维 | Prometheus 告警规则生产级配置:50+ 核心指标与最佳实践(一)-优快云博客
马哥Linux运维 | Prometheus 告警规则生产级配置:50+ 核心指标与最佳实践(二)-优快云博客
马哥Linux运维 | Prometheus 告警规则生产级配置:50+ 核心指标与最佳实践(三)-优快云博客
1️⃣2️⃣ FAQ(常见问题)
Q1: Prometheus 和 Zabbix/Nagios 的区别?
A:
-
• Prometheus:拉模式(Pull)、时间序列数据库、强大的 PromQL、云原生生态
-
• Zabbix:推模式(Push/Pull)、关系型数据库、传统 IT 基础设施、SNMP/IPMI 支持完善
-
• Nagios:推模式(Push)、插件式架构、轻量级、告警能力强但查询能力弱
适用场景对比:
-
• Prometheus:微服务、Kubernetes、云原生应用、需要复杂查询与聚合
-
• Zabbix:传统 IDC、网络设备、需要自动发现、GUI 配置为主
-
• Nagios:小规模环境、已有大量自定义脚本、简单健康检查
Q2: 为什么推荐使用 Recording Rules?
A:
-
1. 性能优化:预计算复杂查询,告警评估速度提升 10-100 倍
-
2. 降低 CPU 负载:避免重复计算相同的聚合查询
-
3. 简化告警规则:告警规则更简洁,易于维护
-
4. 联邦集群必需:边缘 Prometheus 预计算,中心 Prometheus 仅聚合结果
示例对比:
# ❌ 无 Recording Rules:每次评估都计算(耗时 500ms)
-alert:HighAPIErrorRate
expr:|
sum(rate(http_requests_total{status=~"5.."}[5m])) by (job)
/ sum(rate(http_requests_total[5m])) by (job) > 0.05
# ✅ 有 Recording Rules:直接查询预计算结果(耗时 5ms)
-record:job:http_requests:error_rate
expr:|
sum(rate(http_requests_total{status=~"5.."}[5m])) by (job)
/ sum(rate(http_requests_total[5m])) by (job)
-alert:HighAPIErrorRate
expr:job:http_requests:error_rate>0.05
Q3: 如何处理告警疲劳(Alert Fatigue)?
A: 告警疲劳是指告警过多导致团队忽视告警,解决方法:
-
1. 提高告警阈值:确保告警都是需要人工介入的问题
-
2. 增加 for 持续时间:避免瞬时抖动触发告警
-
3. 配置告警分组:同类告警合并为一条通知
-
4. 使用告警抑制:节点宕机时抑制该节点其他告警
-
5. 定期审查告警:每季度检查误报率,调整或删除无效告警
-
6. 区分优先级:P0(立即响应)、P1(1小时内)、P2(工作日处理)
告警优先级定义:
# P0: 服务完全不可用,需立即响应(5分钟内)
severity:critical
# P1: 服务部分受影响,1小时内响应
severity:warning
# P2: 非紧急问题,工作日处理
severity:info
Q4: Prometheus 数据保留多久合适?
A: 取决于使用场景和存储成本:
| 场景 | 推荐保留时间 | 理由 |
|---|---|---|
| 实时监控 | 7-15 天 | 满足短期故障排查,降低存储成本 |
| 容量规划 | 30-90 天 | 需要观察长期趋势 |
| 合规要求 | 1-3 年 | 需集成远程存储(Thanos/VictoriaMetrics) |
配置示例:
# prometheus.yml
storage:
tsdb:
retention.time:15d# 保留 15 天
retention.size:50GB# 或保留最多 50GB(优先)
wal_compression:true# 启用 WAL 压缩
长期存储方案:
-
• Thanos:对象存储(S3/GCS),支持全局查询、去重、降采样
-
• VictoriaMetrics:高性能时间序列数据库,压缩比 7:1
-
• Cortex:多租户架构,适合 SaaS 场景
Q5: 如何监控 Kubernetes 集群?
A: Kubernetes 监控需要多个 Exporter 配合:
# prometheus.yml
scrape_configs:
# 1. Kubernetes API Server(集群级指标)
-job_name:'kubernetes-apiservers'
kubernetes_sd_configs:
-role:endpoints
relabel_configs:
-source_labels: [__meta_kubernetes_service_name]
action:keep
regex:kubernetes
# 2. Node Exporter(节点级指标)
-job_name:'kubernetes-nodes'
kubernetes_sd_configs:
-role:node
relabel_configs:
-action:labelmap
regex:__meta_kubernetes_node_label_(.+)
# 3. cAdvisor(容器级指标)
-job_name:'kubernetes-cadvisor'
kubernetes_sd_configs:
-role:node
relabel_configs:
-target_label:__address__
replacement:kubernetes.default.svc:443
-source_labels: [__meta_kubernetes_node_name]
target_label:__metrics_path__
replacement:/api/v1/nodes/${1}/proxy/metrics/cadvisor
# 4. kube-state-metrics(K8s 对象状态)
-job_name:'kube-state-metrics'
static_configs:
-targets: ['kube-state-metrics.kube-system.svc:8080']
关键告警规则:
# Pod 重启频繁
-alert:PodRestartingTooOften
expr:rate(kube_pod_container_status_restarts_total[15m])>0.1
for:5m
# Pod Pending 超过 10 分钟
-alert:PodPendingTooLong
expr:kube_pod_status_phase{phase="Pending"}==1
for:10m
# Node NotReady
-alert:KubernetesNodeNotReady
expr:kube_node_status_condition{condition="Ready",status="true"}==0
for:5m
Q6: PromQL 查询为什么会超时?
A: 常见原因与解决方法:
| 原因 | 诊断方法 | 解决方案 |
|---|---|---|
| 查询范围过大 | 检查时间范围( | 缩小范围到 |
| 高基数聚合 | 检查标签基数 | 删除高基数标签,使用 recording rules |
| 无索引标签查询 | 使用 | 添加具体的指标名称或 job 标签 |
| 正则表达式复杂 | 使用 | 简化正则,使用多个简单查询 |
查询优化示例:
# ❌ 慢查询:无索引标签,查询所有时间序列
{__name__=~".*request.*"}
# ✅ 快查询:指定 job 标签
{job="api_server", __name__=~".*request.*"}
# ❌ 慢查询:高基数聚合
sum(rate(http_requests_total[5m])) by (url) # url 有 10000+ 个值
# ✅ 快查询:低基数聚合
sum(rate(http_requests_total[5m])) by (method, status) # 仅 20 个组合
Q7: 如何避免 Prometheus 单点故障?
A: 高可用方案:
方案 1: 主备模式(简单)
# 部署两台完全相同配置的 Prometheus
# 优点:简单可靠
# 缺点:数据冗余,成本高
# Alertmanager 配置去重
alerting:
alertmanagers:
-static_configs:
-targets:
-'alertmanager-01:9093'
-'alertmanager-02:9093'
方案 2: 联邦集群(推荐)
# 边缘 Prometheus 负责采集
# 中心 Prometheus 聚合数据
# 优点:分布式、可扩展
# 缺点:架构复杂
方案 3: Thanos/Cortex(企业级)
-
• 长期存储到对象存储(S3/GCS)
-
• 多副本保证高可用
-
• 全局查询视图
1️⃣3️⃣ 附录:关键脚本
一键部署脚本(RHEL/CentOS 8+)
#!/bin/bash
# 文件名:deploy_prometheus_stack.sh
# 用途:自动化部署 Prometheus + Alertmanager + Node Exporter
set -e # 遇到错误立即退出
# ============ 配置变量 ============
PROMETHEUS_VERSION="2.48.0"
ALERTMANAGER_VERSION="0.26.0"
NODE_EXPORTER_VERSION="1.6.1"
PROMETHEUS_USER="prometheus"
INSTALL_DIR="/opt/prometheus"
DATA_DIR="/var/lib/prometheus"
CONFIG_DIR="/etc/prometheus"
# ============ 前置检查 ============
echo"[1/8] 系统环境检查..."
if ! grep -qE 'CentOS|Red Hat' /etc/os-release; then
echo"错误:仅支持 RHEL/CentOS 系统"
exit 1
fi
if [[ $EUID -ne 0 ]]; then
echo"错误:必须以 root 用户运行此脚本"
exit 1
fi
# ============ 创建用户 ============
echo"[2/8] 创建 prometheus 用户..."
id -u $PROMETHEUS_USER &>/dev/null || useradd --no-create-home --shell /bin/false $PROMETHEUS_USER
# ============ 下载并安装 Prometheus ============
echo"[3/8] 下载 Prometheus ${PROMETHEUS_VERSION}..."
cd /tmp
wget -q https://github.com/prometheus/prometheus/releases/download/v${PROMETHEUS_VERSION}/prometheus-${PROMETHEUS_VERSION}.linux-amd64.tar.gz
tar xzf prometheus-${PROMETHEUS_VERSION}.linux-amd64.tar.gz
echo"安装 Prometheus..."
mkdir -p $INSTALL_DIR$DATA_DIR$CONFIG_DIR/rules
cp prometheus-${PROMETHEUS_VERSION}.linux-amd64/prometheus $INSTALL_DIR/
cp prometheus-${PROMETHEUS_VERSION}.linux-amd64/promtool $INSTALL_DIR/
cp -r prometheus-${PROMETHEUS_VERSION}.linux-amd64/consoles $CONFIG_DIR/
cp -r prometheus-${PROMETHEUS_VERSION}.linux-amd64/console_libraries $CONFIG_DIR/
chown -R $PROMETHEUS_USER:$PROMETHEUS_USER$INSTALL_DIR$DATA_DIR$CONFIG_DIR
# ============ 创建 Prometheus 配置 ============
echo"[4/8] 创建 Prometheus 配置文件..."
cat > $CONFIG_DIR/prometheus.yml <<'EOF'
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- '/etc/prometheus/rules/*.yml'
alerting:
alertmanagers:
- static_configs:
- targets:
- 'localhost:9093'
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node_exporter'
static_configs:
- targets: ['localhost:9100']
EOF
chown$PROMETHEUS_USER:$PROMETHEUS_USER$CONFIG_DIR/prometheus.yml
# ============ 创建 systemd 服务 ============
echo"[5/8] 创建 Prometheus systemd 服务..."
cat > /etc/systemd/system/prometheus.service <<EOF
[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target
[Service]
User=$PROMETHEUS_USER
Group=$PROMETHEUS_USER
Type=simple
ExecStart=$INSTALL_DIR/prometheus \\
--config.file=$CONFIG_DIR/prometheus.yml \\
--storage.tsdb.path=$DATA_DIR \\
--storage.tsdb.retention.time=15d \\
--storage.tsdb.wal-compression \\
--web.console.templates=$CONFIG_DIR/consoles \\
--web.console.libraries=$CONFIG_DIR/console_libraries \\
--web.enable-lifecycle \\
--web.enable-admin-api
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
# ============ 下载并安装 Alertmanager ============
echo"[6/8] 下载 Alertmanager ${ALERTMANAGER_VERSION}..."
cd /tmp
wget -q https://github.com/prometheus/alertmanager/releases/download/v${ALERTMANAGER_VERSION}/alertmanager-${ALERTMANAGER_VERSION}.linux-amd64.tar.gz
tar xzf alertmanager-${ALERTMANAGER_VERSION}.linux-amd64.tar.gz
echo"安装 Alertmanager..."
mkdir -p /etc/alertmanager /var/lib/alertmanager
cp alertmanager-${ALERTMANAGER_VERSION}.linux-amd64/alertmanager $INSTALL_DIR/
cp alertmanager-${ALERTMANAGER_VERSION}.linux-amd64/amtool $INSTALL_DIR/
# 创建 Alertmanager 配置
cat > /etc/alertmanager/alertmanager.yml <<'EOF'
global:
resolve_timeout: 5m
route:
receiver: 'default-email'
group_by: ['alertname', 'cluster']
group_wait: 10s
group_interval: 10s
repeat_interval: 12h
receivers:
- name: 'default-email'
email_configs:
- to: 'ops-team@example.com'
from: 'alerts@example.com'
smarthost: 'smtp.example.com:587'
auth_username: 'alerts@example.com'
auth_password: 'your_password'
EOF
chown -R $PROMETHEUS_USER:$PROMETHEUS_USER /etc/alertmanager /var/lib/alertmanager
# 创建 Alertmanager systemd 服务
cat > /etc/systemd/system/alertmanager.service <<EOF
[Unit]
Description=Alertmanager
Wants=network-online.target
After=network-online.target
[Service]
User=$PROMETHEUS_USER
Group=$PROMETHEUS_USER
Type=simple
ExecStart=$INSTALL_DIR/alertmanager \\
--config.file=/etc/alertmanager/alertmanager.yml \\
--storage.path=/var/lib/alertmanager \\
--web.listen-address=:9093
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
# ============ 下载并安装 Node Exporter ============
echo"[7/8] 下载 Node Exporter ${NODE_EXPORTER_VERSION}..."
cd /tmp
wget -q https://github.com/prometheus/node_exporter/releases/download/v${NODE_EXPORTER_VERSION}/node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz
tar xzf node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz
echo"安装 Node Exporter..."
cp node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64/node_exporter $INSTALL_DIR/
# 创建 Node Exporter systemd 服务
cat > /etc/systemd/system/node_exporter.service <<EOF
[Unit]
Description=Node Exporter
After=network.target
[Service]
User=$PROMETHEUS_USER
Group=$PROMETHEUS_USER
Type=simple
ExecStart=$INSTALL_DIR/node_exporter \\
--collector.systemd \\
--collector.processes \\
--collector.tcpstat
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
# ============ 启动所有服务 ============
echo"[8/8] 启动服务..."
systemctl daemon-reload
systemctl enable --now prometheus alertmanager node_exporter
# 等待服务启动
sleep 5
# ============ 验证安装 ============
echo""
echo"============ 安装完成 ============"
echo"Prometheus: http://$(hostname -I | awk '{print $1}'):9090"
echo"Alertmanager: http://$(hostname -I | awk '{print $1}'):9093"
echo"Node Exporter: http://$(hostname -I | awk '{print $1}'):9100"
echo""
echo"验证服务状态:"
systemctl is-active prometheus && echo"✓ Prometheus 运行中" || echo"✗ Prometheus 启动失败"
systemctl is-active alertmanager && echo"✓ Alertmanager 运行中" || echo"✗ Alertmanager 启动失败"
systemctl is-active node_exporter && echo"✓ Node Exporter 运行中" || echo"✗ Node Exporter 启动失败"
echo""
echo"下一步:"
echo"1. 编辑 /etc/prometheus/rules/ 下的告警规则"
echo"2. 编辑 /etc/alertmanager/alertmanager.yml 配置通知渠道"
echo"3. 执行 'curl -X POST http://localhost:9090/-/reload' 热加载配置"
使用方法:
# 下载脚本
curl -O https://your-repo.com/deploy_prometheus_stack.sh
chmod +x deploy_prometheus_stack.sh
# 执行安装
sudo ./deploy_prometheus_stack.sh
健康检查脚本
#!/bin/bash
# 文件名:check_prometheus_health.sh
# 用途:全面检查 Prometheus 栈健康状态
set -e
PROMETHEUS_URL="http://localhost:9090"
ALERTMANAGER_URL="http://localhost:9093"
echo"============ Prometheus 健康检查 ============"
# 1. 检查服务状态
echo"[1/7] 检查服务状态..."
systemctl is-active prometheus && echo"✓ Prometheus 运行中" || echo"✗ Prometheus 未运行"
systemctl is-active alertmanager && echo"✓ Alertmanager 运行中" || echo"✗ Alertmanager 未运行"
systemctl is-active node_exporter && echo"✓ Node Exporter 运行中" || echo"✗ Node Exporter 未运行"
# 2. 检查端口监听
echo""
echo"[2/7] 检查端口监听..."
ss -tulnp | grep :9090 && echo"✓ Prometheus 端口 9090 监听中" || echo"✗ Prometheus 端口 9090 未监听"
ss -tulnp | grep :9093 && echo"✓ Alertmanager 端口 9093 监听中" || echo"✗ Alertmanager 端口 9093 未监听"
ss -tulnp | grep :9100 && echo"✓ Node Exporter 端口 9100 监听中" || echo"✗ Node Exporter 端口 9100 未监听"
# 3. 检查目标健康状态
echo""
echo"[3/7] 检查监控目标..."
DOWN_TARGETS=$(curl -s $PROMETHEUS_URL/api/v1/targets | jq -r '.data.activeTargets[] | select(.health != "up") | "\(.job)/\(.instance)"')
if [ -z "$DOWN_TARGETS" ]; then
echo"✓ 所有监控目标正常"
else
echo"✗ 以下目标不可达:"
echo"$DOWN_TARGETS"
fi
# 4. 检查告警规则错误
echo""
echo"[4/7] 检查告警规则..."
RULE_ERRORS=$(curl -s $PROMETHEUS_URL/api/v1/rules | jq -r '.data.groups[].rules[] | select(.lastError != null) | "\(.name): \(.lastError)"')
if [ -z "$RULE_ERRORS" ]; then
echo"✓ 所有告警规则正常"
else
echo"✗ 以下规则有错误:"
echo"$RULE_ERRORS"
fi
# 5. 检查存储空间
echo""
echo"[5/7] 检查存储空间..."
STORAGE_USAGE=$(df -h /var/lib/prometheus | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $STORAGE_USAGE -lt 80 ]; then
echo"✓ 存储空间充足(已使用 ${STORAGE_USAGE}%)"
else
echo"⚠ 存储空间不足(已使用 ${STORAGE_USAGE}%)"
fi
# 6. 检查 TSDB 状态
echo""
echo"[6/7] 检查 TSDB 状态..."
NUM_SERIES=$(curl -s $PROMETHEUS_URL/api/v1/status/tsdb | jq -r '.data.numSeries')
echo"活跃时间序列数: $NUM_SERIES"
if [ $NUM_SERIES -lt 100000 ]; then
echo"✓ 时间序列数量正常"
else
echo"⚠ 时间序列数量过多,可能存在高基数标签"
fi
# 7. 检查当前告警
echo""
echo"[7/7] 检查当前告警..."
ACTIVE_ALERTS=$(curl -s $ALERTMANAGER_URL/api/v2/alerts | jq -r '.[] | select(.status.state == "active") | "\(.labels.alertname)"')
if [ -z "$ACTIVE_ALERTS" ]; then
echo"✓ 无活跃告警"
else
echo"⚠ 当前活跃告警:"
echo"$ACTIVE_ALERTS"
fi
echo""
echo"============ 检查完成 ============"
高基数标签检测脚本
#!/bin/bash
# 文件名:detect_high_cardinality.sh
# 用途:检测高基数标签
PROMETHEUS_URL="http://localhost:9090"
THRESHOLD=1000 # 时间序列数超过 1000 的指标视为高基数
echo"============ 高基数标签检测 ============"
echo"阈值: $THRESHOLD 时间序列"
echo""
# 获取所有指标名称
METRICS=$(curl -s $PROMETHEUS_URL/api/v1/label/__name__/values | jq -r '.data[]')
# 检查每个指标的时间序列数量
for metric in$METRICS; do
COUNT=$(curl -s "$PROMETHEUS_URL/api/v1/series?match[]=$metric" | jq '.data | length')
if [ $COUNT -gt $THRESHOLD ]; then
echo"⚠ 高基数指标: $metric ($COUNT 个时间序列)"
# 分析标签基数
echo" 标签基数分布:"
curl -s "$PROMETHEUS_URL/api/v1/series?match[]=$metric" | jq -r '.data[].{} | keys[]' | sort | uniq -c | sort -rn | head -n 5 | whileread count label; do
echo" $label: $count 个不同值"
done
echo""
fi
done
1️⃣4️⃣ 扩展阅读
官方文档:
-
• Prometheus 官方文档:https://prometheus.io/docs/introduction/overview/
-
• Alertmanager 官方文档:https://prometheus.io/docs/alerting/latest/alertmanager/
-
• PromQL 查询语言:https://prometheus.io/docs/prometheus/latest/querying/basics/
深入技术博客:
-
• Prometheus 架构设计:https://prometheus.io/docs/introduction/architecture/
-
• 高可用 Prometheus 部署:https://prometheus.io/docs/prometheus/latest/federation/
-
• Thanos 长期存储方案:https://thanos.io/
社区资源:
-
• Prometheus GitHub:https://github.com/prometheus/prometheus
-
• Awesome Prometheus:https://github.com/roaldnefs/awesome-prometheus
-
• Prometheus 中文文档:https://prometheus.io/docs/introduction/overview/ (社区翻译)
最佳实践指南:
-
• Google SRE Workbook - Alerting on SLOs:https://sre.google/workbook/alerting-on-slos/
-
• Robust Perception Blog:https://www.robustperception.io/blog
THE END !
文章结束,感谢阅读。您的点赞,收藏,评论是我继续更新的动力。大家有推荐的公众号可以评论区留言,共同学习,一起进步。

1234

被折叠的 条评论
为什么被折叠?



