马哥Linux运维 | Prometheus 告警规则生产级配置:50+ 核心指标与最佳实践(四)

本文来源公众号“马哥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. 1. 性能优化:预计算复杂查询,告警评估速度提升 10-100 倍

  2. 2. 降低 CPU 负载:避免重复计算相同的聚合查询

  3. 3. 简化告警规则:告警规则更简洁,易于维护

  4. 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. 1. 提高告警阈值:确保告警都是需要人工介入的问题

  2. 2. 增加 for 持续时间:避免瞬时抖动触发告警

  3. 3. 配置告警分组:同类告警合并为一条通知

  4. 4. 使用告警抑制:节点宕机时抑制该节点其他告警

  5. 5. 定期审查告警:每季度检查误报率,调整或删除无效告警

  6. 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: 常见原因与解决方法:

原因

诊断方法

解决方案

查询范围过大

检查时间范围([30d]

缩小范围到 [5m] - [1h]

高基数聚合

检查标签基数

删除高基数标签,使用 recording rules

无索引标签查询

使用 {__name__=~".*"}

添加具体的指标名称或 job 标签

正则表达式复杂

使用 {label=~".*complex.*"}

简化正则,使用多个简单查询

查询优化示例:

# ❌ 慢查询:无索引标签,查询所有时间序列
{__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 !

文章结束,感谢阅读。您的点赞,收藏,评论是我继续更新的动力。大家有推荐的公众号可以评论区留言,共同学习,一起进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值