k8s部署prometheus架构规则

常用命令

bash 复制代码
# 查看所有 ServiceMonitor,查看所有被监控采集数据的服务
kubectl get servicemonitor -n monitoring

# 查看所有 PrometheusRule规则
kubectl get prometheusrule -n monitoring

#查看 Prometheus 实例的 ruleSelector 告警配置
kubectl get prometheus -n monitoring -o jsonpath='{.items[0].spec.ruleSelector}'

# 查看 Alertmanager 通知配置
kubectl get secret alertmanager-main -n monitoring -o jsonpath='{.data.alertmanager\.yaml}' | base64 -d

一、prometheus operator架构

Prometheus Operator 架构中的四个核心资源对象,它们之间是**"采集 → 规则 → 告警 → 通知"**的完整链路关系。下面为你详解每个资源的逻辑包含关系、作用及示例。

1. 采集:ServiceMonitor:定义"监控谁"

bash 复制代码
kubectl get servicemonitor -n monitoring
  • 作用:告诉 Prometheus "我要监控哪些服务"。它通过标签选择器(selector)自动发现 Kubernetes 中的 Service,并生成对应的抓取配置(scrape config)。
  • 逻辑位置:数据采集层。没有它,Prometheus 就不知道去哪里拉取指标。
  • 示例

假设有一个业务应用,部署在 default 命名空间,Service 名字叫 my-app,暴露了 /metrics 接口,端口是 8080

yaml 复制代码
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: my-app-monitor
  namespace: monitoring          # ServiceMonitor 必须和 Prometheus 在同一个命名空间
  labels:
    release: prometheus           # 这个标签必须匹配你的 Prometheus 实例的 serviceMonitorSelector
spec:
  namespaceSelector:
    matchNames:
      - default                   # 你的业务 Service 所在的命名空间
  selector:
    matchLabels:
      app: my-app                 # 匹配你业务 Service 的标签
  endpoints:
    - port: http                  # 匹配 Service 中定义的端口名称(不是端口号)
      path: /metrics              # 指标暴露路径
      interval: 30s               # 抓取间隔
      scrapeTimeout: 10s          # 抓取超时

三个必须匹配的地方

匹配关系 ServiceMonitor 里的字段 需要匹配的对象
谁发现它 metadata.labels.release Prometheus 实例的 serviceMonitorSelector
找哪个 Service spec.selector.matchLabels 你业务 Service 的 metadata.labels
抓哪个端口 spec.endpoints[].port 你业务 Service 的 ports[].name

第一步:确认 Prometheus 的 selector

复制代码
kubectl get prometheus -n monitoring -o yaml | grep -A 5 serviceMonitorSelector

你会看到类似这样的输出:

yaml 复制代码
serviceMonitorSelector:
  matchLabels:
    release: prometheus

记住这个 release: prometheus,你的 ServiceMonitor 的 metadata.labels 里必须带上它。

第二步:确认你的业务 Service 有正确的标签和端口名

bash 复制代码
kubectl get svc my-app -n default -o yaml

确认有类似这样的内容:

yaml 复制代码
metadata:
  labels:
    app: my-app          # ← ServiceMonitor 的 selector 要匹配这个
spec:
  ports:
    - name: http          # ← ServiceMonitor 的 endpoints.port 要匹配这个
      port: 8080
      targetPort: 8080

如果你的 Service 的端口没有 name 字段,必须加上,否则 ServiceMonitor 无法引用。

第三步:部署 ServiceMonitor

bash 复制代码
kubectl apply -f servicemonitor.yaml

第四步:验证

bash 复制代码
# 1. 确认 ServiceMonitor 已创建
kubectl get servicemonitor my-app-monitor -n monitoring

# 2. 进入 Prometheus Pod,检查 targets 是否出现
kubectl exec -it prometheus-k8s-0 -n monitoring -- wget -qO- http://localhost:9090/api/v1/targets | grep my-app

# 3. 或者直接打开 Prometheus UI
# 浏览器访问 Prometheus -> Status -> Targets,搜索你的服务名

2. 规则:PrometheusRule:定义"什么算异常"

bash 复制代码
kubectl get prometheusrule -n monitoring
  • 作用:定义告警规则。当某个指标满足特定条件(如 CPU > 90% 持续 5 分钟),就会触发一个 Alert。
  • 逻辑位置:规则判断层。它不直接发送告警,而是将"触发的告警事件"发送给 Alertmanager。
  • 示例
yaml 复制代码
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: high-cpu-alert
  namespace: monitoring
spec:
  groups:
    - name: cpu-alerts
      rules:
        - alert: HighCPUUsage
          expr: avg(rate(node_cpu_seconds_total{mode!="idle"}[5m])) > 0.9
          for: 5m
          labels:
            severity: critical

3. 告警:Prometheus:定义"谁来执行"

bash 复制代码
#查看 Prometheus 实例的 ruleSelector 告警配置
kubectl get prometheus -n monitoring -o jsonpath='{.items[0].spec.ruleSelector}'
  • 作用 :这是 Prometheus Server 本身的 CRD 对象,定义了 Prometheus 实例的配置,包括:
    • ruleSelector:决定加载哪些 PrometheusRule。
    • serviceMonitorSelector:决定加载哪些 ServiceMonitor。
    • alerting:指定告警发送到哪个 Alertmanager。
  • 逻辑位置:核心引擎层。它是整个监控系统的"大脑",负责采集数据、评估规则、发送告警。
  • 关键点 :你之前查到的 ruleSelector: {} 表示它会加载所有命名空间下的规则(只要规则本身有正确标签)。

4. 通知:Alertmanager:定义"怎么通知人"

bash 复制代码
kubectl get alertmanagers -A

# 查看 Alertmanager 通知配置
kubectl get secret alertmanager-main -n monitoring -o jsonpath='{.data.alertmanager\.yaml}' | base64 -d
  • 作用:接收来自 Prometheus 的告警事件,进行去重、分组、静默处理,然后通过邮件、钉钉、企业微信等渠道发送通知。
  • 逻辑位置:通知分发层。它不关心"为什么告警",只关心"怎么把告警发出去"。
  • 查看方式 :你用的命令 kubectl get secret alertmanager-main -n monitoring -o jsonpath='{.data.alertmanager\.yaml}' | base64 -d 是正确的,因为 Alertmanager 的配置通常存储在 Secret 中。

5.其他相关资源

除了以上四个,还有几个重要的资源你可能需要关注:

  • PodMonitor:与 ServiceMonitor 类似,但直接监控 Pod,而不是通过 Service。适用于没有 Service 暴露的场景。
  • Probe:用于黑盒监控,比如定期访问一个 URL 检查服务是否存活。
  • ThanosRuler:如果你使用了 Thanos 做长期存储和全局查询,ThanosRuler 会替代 PrometheusRule 的作用。
  • ConfigMap:有时 Prometheus 的额外配置(如 recording rules)会通过 ConfigMap 挂载,而不是用 PrometheusRule。

6.总结

这四个命令覆盖了从"数据采集"到"告警通知"的全流程。理解它们的逻辑关系,就能快速定位监控系统中任何一环的问题。

二、配置示例

1.规则-告警-整体架构

从告警规则到钉钉通知的完整配置流程,一共分三步:创建告警规则 → 部署钉钉 Webhook 中间件 → 配置 Alertmanager 路由

bash 复制代码
PrometheusRule(内存>80%触发告警)
       ↓
Prometheus(评估规则,产生告警事件)
       ↓
Alertmanager(接收告警,按路由分发)
       ↓
prometheus-webhook-dingtalk(格式转换中间件)
       ↓
钉钉群机器人(发送通知到群)

1.部署 prometheus-webhook-dingtalk 中间件

Alertmanager 不能直接对接钉钉,需要一个"翻译官"把告警格式转成钉钉能识别的格式。

1.1 在钉钉群创建自定义机器人
  1. 打开钉钉群 → 群设置 → 智能群助手 → 添加机器人 → 自定义机器人
  2. 机器人名称填"Prometheus告警"
  3. 安全设置选择加签 ,复制保存以下两个值:
    • Webhook URLhttps://oapi.dingtalk.com/robot/send?access_token=xxxxxxxx
    • 加签密钥SECxxxxxxxxxxxxxxxx
1.2 prometheus-dingtalk-webhook中间件yaml文件
bash 复制代码
vim dingtalk-webhook.yaml
#以下两个yaml二选一,分别是钉钉告警格式:prometheus原生格式详细,钉钉格式简略版
yaml 复制代码
# dingtalk-webhook.yaml
# prometheus原生格式详细
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: dingtalk-webhook-config
  namespace: monitoring
data:
  config.yml: |
    targets:
      webhook1:
        url: https://oapi.dingtalk.com/robot/send?access_token=你的access_token
        secret: 你的加签密钥
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dingtalk-webhook
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dingtalk-webhook
  template:
    metadata:
      labels:
        app: dingtalk-webhook
    spec:
      containers:
        - name: dingtalk-webhook
          image: timonwong/prometheus-webhook-dingtalk:v1.6.4
          args:
            - --web.listen-address=:8060
            - --config.file=/config/config.yml
          ports:
            - containerPort: 8060
          volumeMounts:
            - name: config
              mountPath: /config
          resources:
            limits:
              cpu: 100m
              memory: 64Mi
      volumes:
        - name: config
          configMap:
            name: dingtalk-webhook-config
---
apiVersion: v1
kind: Service
metadata:
  name: dingtalk-webhook
  namespace: monitoring
spec:
  selector:
    app: dingtalk-webhook
  ports:
    - name: http
      port: 8060
      targetPort: 8060
  type: Nodeport
yaml 复制代码
# dingtalk-webhook.yaml
# 钉钉格式简略版
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: dingtalk-webhook-config
  namespace: monitoring
data:
  config.yml: |
    templates:
      - /config/dingtalk.tmpl
    targets:
      webhook1:
        url: https://oapi.dingtalk.com/robot/send?你的钉钉机器人地址
        secret: 你的认证密钥
        message:
          title: '{{ template "dingtalk.default.message" . }}'
          text: '{{ template "dingtalk.default.message" . }}'
  dingtalk.tmpl: |
    {{ define "dingtalk.default.message" }}
    {{- if gt (len .Alerts.Firing) 0 }}
    {{- range .Alerts.Firing }}
    ### 🚨 [故障告警]

    - **告警名称**: {{ .Labels.alertname }}

    - **故障级别**: {{ .Labels.severity }}

    - **故障实例**: {{ .Labels.instance }}

    - **告警摘要**: {{ .Annotations.summary }}

    - **故障时间**: {{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}

    - **故障详情**: {{ .Annotations.description }}

    ---
    {{- end }}
    {{- end }}

    {{- if gt (len .Alerts.Resolved) 0 }}
    {{- range .Alerts.Resolved }}
    ### ✅ [告警恢复]

    - **告警名称**: {{ .Labels.alertname }}

    - **恢复实例**: {{ .Labels.instance }}

    - **故障时间**: {{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}

    - **恢复时间**: {{ (.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}

    ---
    {{- end }}
    {{- end }}
    {{ end }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dingtalk-webhook
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dingtalk-webhook
  template:
    metadata:
      labels:
        app: dingtalk-webhook
    spec:
      containers:
        - name: dingtalk-webhook
          image: timonwong/prometheus-webhook-dingtalk:v2.1.0
          args:
            - --web.listen-address=:8060
            - --config.file=/config/config.yml
          ports:
            - containerPort: 8060
          volumeMounts:
            - name: config
              mountPath: /config/config.yml
              subPath: config.yml
            - name: config
              mountPath: /config/dingtalk.tmpl
              subPath: dingtalk.tmpl
          resources:
            limits:
              cpu: 100m
              memory: 64Mi
      volumes:
        - name: config
          configMap:
            name: dingtalk-webhook-config
---
apiVersion: v1
kind: Service
metadata:
  name: dingtalk-webhook
  namespace: monitoring
spec:
  selector:
    app: dingtalk-webhook
  ports:
    - name: http
      port: 8060
      targetPort: 8060
  type: NodePort

⚠️ 必须替换 ConfigMap 中的 access_tokensecret 为你在钉钉群创建机器人时获得的值。

1.3 部署中间件
bash 复制代码
kubectl apply -f dingtalk-webhook.yaml
bash 复制代码
#更新配置后滚动重启
kubectl rollout restart deployment dingtalk-webhook -n monitoring

验证 Pod 是否正常运行:

bash 复制代码
kubectl get pods -n monitoring -l app=dingtalk-webhook

验证告警链路是否正常

bash 复制代码
# 先获取 NodePort 端口号
kubectl get svc dingtalk-webhook -n monitoring -o jsonpath='{.spec.ports[0].nodePort}'
bash 复制代码
# 用 curl 模拟 Alertmanager 发送告警(替换 <NodeIP> 和 <NodePort>)
curl -X POST http://10.211.55.7:32033/dingtalk/webhook1/send \
  -H 'Content-Type: application/json' \
  -d '{
    "receiver": "dingtalk",
    "status": "firing",
    "alerts": [
      {
        "status": "firing",
        "labels": {
          "alertname": "TestAlert",
          "severity": "critical",
          "instance": "192.168.1.100:9100"
        },
        "annotations": {
          "summary": "这是一条测试告警",
          "description": "用于验证钉钉告警链路是否通畅"
        },
        "startsAt": "2026-07-30T07:00:00.000Z",
        "endsAt": "0001-01-01T00:00:00Z"
      }
    ],
    "groupLabels": {
      "alertname": "TestAlert"
    },
    "commonLabels": {
      "alertname": "TestAlert",
      "severity": "critical",
      "instance": "192.168.1.100:9100"
    },
    "commonAnnotations": {
      "summary": "这是一条测试告警",
      "description": "用于验证钉钉告警链路是否通畅"
    }
  }'

2.配置 Alertmanager 路由到钉钉

你需要修改 Alertmanager 的配置,添加一个钉钉接收器,并将 severity: critical 的告警路由过去。

2.1 查看当前 Alertmanager 配置
bash 复制代码
# 备份导出当前配置并保存为文件
kubectl get secret alertmanager-main -n monitoring -o jsonpath='{.data.alertmanager\.yaml}' | base64 -d > /data/01_prometheus/alertmanager-backup.yaml

cp /data/01_prometheus/alertmanager-backup.yaml /data/01_prometheus/alertmanager.yaml
2.2 修改 Alertmanager 配置

在现有配置的基础上,添加钉钉相关的路由和接收器。完整示例如下:

bash 复制代码
vim alertmanager.yaml
yaml 复制代码
"global":
  "resolve_timeout": "5m"
"inhibit_rules":
- "equal":
  - "namespace"
  - "alertname"
  "source_matchers":
  - "severity = critical"
  "target_matchers":
  - "severity =~ warning|info"
- "equal":
  - "namespace"
  - "alertname"
  "source_matchers":
  - "severity = warning"
  "target_matchers":
  - "severity = info"
- "equal":
  - "namespace"
  "source_matchers":
  - "alertname = InfoInhibitor"
  "target_matchers":
  - "severity = info"
"receivers":
- "name": "Default"
- "name": "Watchdog"
- "name": "Critical"
- "name": "null"
- "name": "Dingtalk-Critical"
  "webhook_configs":
  - "url": "http://dingtalk-webhook.monitoring.svc:8060/dingtalk/webhook1/send"
    "send_resolved": true
- "name": "Dingtalk-Warning"
  "webhook_configs":
  - "url": "http://dingtalk-webhook.monitoring.svc:8060/dingtalk/webhook1/send"
    "send_resolved": true
- "name": "Dingtalk-Info"
  "webhook_configs":
  - "url": "http://dingtalk-webhook.monitoring.svc:8060/dingtalk/webhook1/send"
    "send_resolved": true
"route":
#按 alertname 和 instance 分组
  "group_by": 
    - alertname
    - instance
#  - "namespace" 
  "group_interval": "5m"
  "group_wait": "30s"
  "receiver": "Default"
  "repeat_interval": "12h"
  "routes":
  # Watchdog (保活探针)
  - "matchers":
    - "alertname = Watchdog"
    "receiver": "Watchdog"
  # InfoInhibitor (抑制器,直接丢弃不发)
  - "matchers":
    - "alertname = InfoInhibitor"
    "receiver": "null"
  # Critical -> 钉钉
  - "matchers":
    - "severity = critical"
    "receiver": "Dingtalk-Critical"
    "continue": true
  # Critical -> Critical
  - "matchers":
    - "severity = critical"
    "receiver": "Critical"
  # warning -> 钉钉
  - "matchers":
    - "severity = warning"
    "receiver": "Dingtalk-Warning"
    "repeat_interval": "4h"
  # Info -> 钉钉
  - "matchers":
    - "severity = info"
    "receiver": "Dingtalk-Info"
    "repeat_interval": "24h"

关键说明:

  • url 中的 dingtalk-webhook.monitoring.svc 是第二步部署的 Service 的集群内 DNS 地址。
  • webhook1 对应 ConfigMap 中 targets 下的 key 名称。
  • send_resolved: true 表示告警恢复后也会发送通知。
  • continue: false 表示匹配到钉钉路由后不再继续匹配其他路由。如果需要同时发邮件,改为 true
2.3 更新 Alertmanager Secret
bash 复制代码
#读取 当前alertmanager.yaml 文件
#自动做 base64 编码
#生成 Secret 并覆盖更新到集群中
kubectl create secret generic alertmanager-main \
  -n monitoring \
  --from-file=alertmanager.yaml=./alertmanager.yaml \
  --dry-run=client -o yaml | kubectl apply -f -
  
# 手工生成 base64 编码(注意 -w 0 表示不换行)
# cat /tmp/alertmanager.yaml | base64 -w 0
2.4验证
bash 复制代码
kubectl get secret alertmanager-main -n monitoring -o jsonpath='{.data.alertmanager\.yaml}' | base64 -d
2.5修改完 Secret 后,重启 Alertmanager Pod 让配置生效
bash 复制代码
kubectl get statefulset -n monitoring | grep alertmanager
#滚动重启最安全、最标准的方式,它会逐个替换 Pod,保证服务不中断
kubectl rollout restart statefulset alertmanager-main -n monitoring
kubectl get pods -n monitoring -w | grep alertmanager 

3.总结:

1.备份
bash 复制代码
kubectl get secret alertmanager-main -n monitoring -o jsonpath='{.data.alertmanager\.yaml}' | base64 -d > /tmp/alertmanager-backup.yaml
2.修改
bash 复制代码
cp /tmp/alertmanager-backup.yaml /tmp/alertmanager-new.yaml
# 然后用编辑器打开 /tmp/alertmanager-new.yaml,在原有基础上追加钉钉配置(保持双引号风格)
vim /tmp/alertmanager-new.yaml
3.应用
bash 复制代码
kubectl create secret generic alertmanager-main \
  --from-file=alertmanager.yaml=/tmp/alertmanager-new.yaml \
  -n monitoring \
  --dry-run=client -o yaml | kubectl apply -f -
4.回滚
bash 复制代码
kubectl create secret generic alertmanager-main \
  --from-file=alertmanager.yaml=./alertmanager-backup.yaml \
  -n monitoring \
  --dry-run=client -o yaml | kubectl apply -f -

4.常见问题

  • 钉钉群没收到消息 :检查中间件 Pod 日志 kubectl logs -n monitoring -l app=dingtalk-webhook,看是否有 token 错误或网络不通的报错。
  • 告警规则不触发 :在 Prometheus UI 手动执行 PromQL 表达式,确认 node_memory_MemTotal_bytesnode_memory_MemAvailable_bytes 有数据。如果没有,说明 node-exporter 的 ServiceMonitor 有问题。
  • 告警恢复通知没收到 :确认 Alertmanager 的 webhook_configssend_resolved: true 已设置。
bash 复制代码
kubectl exec -it alertmanager-main-0 -n monitoring -- sh
# 在 Pod 里执行
wget http://dingtalk-webhook.monitoring.svc:8060/dingtalk/webhook1/send

2.节点内存使用率告警

1.PrometheusRule 告警规则

bash 复制代码
vim node-memory-usage-rule.yaml
yaml 复制代码
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: node-memory-usage-rule
  namespace: monitoring
  labels:
    prometheus: k8s
    role: alert-rules
spec:
  groups:
    - name: node-memory
      rules:
        - alert: NodeMemoryUsageHigh
          expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100 > 80
          for: 3m
          labels:
            severity: critical
          annotations:
            summary: "节点 {{ $labels.instance }} 内存使用率超过 80%"
            description: "节点 {{ $labels.instance }} 当前内存使用率为 {{ $value | printf \"%.1f\" }}%,已超过 80% 阈值,请及时处理。"

说明:

  • expr:用 (总内存 - 可用内存) / 总内存 * 100 计算内存使用率百分比,> 80 即超过 80% 触发。
  • for: 3m:持续 3 分钟超过阈值才触发,避免瞬时波动导致误报。
  • severity: critical:标记为严重级别,后续 Alertmanager 根据这个标签做路由。
bash 复制代码
kubectl apply -f node-memory-usage-rule.yaml

2.验证

bash 复制代码
# 1. 确认 PrometheusRule 已加载
kubectl get prometheusrule node-memory-usage-rule -n monitoring

# 2. 确认钉钉中间件运行正常
kubectl get pods -n monitoring -l app=dingtalk-webhook

# 3. 端口转发 Prometheus,在 UI 中确认规则已加载
kubectl port-forward svc/prometheus-k8s -n monitoring 9090:9090
# 浏览器访问 http://localhost:9090/rules,搜索 NodeMemoryUsageHigh

# 4. 手动触发测试(可选):在 Prometheus UI 的 Graph 页面执行
# (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100 > 80
# 确认有数据返回,说明 node-exporter 采集正常

3.节点重启告警

1.PrometheusRule 告警规则

bash 复制代码
vim node-restart-rule.yaml
bash 复制代码
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: node-restart-rule
  namespace: monitoring
  labels:
    prometheus: k8s
    role: alert-rules
spec:
  groups:
    - name: node-restart
      rules:
        - alert: NodeRecentlyRebooted
          expr: time() - node_boot_time_seconds < 1800
          for: 1m
          labels:
            severity: critical
          annotations:
            summary: "节点 {{ $labels.instance }} 发生过重启"
            description: "节点 {{ $labels.instance }} 当前运行时间不足 30 分钟,疑似刚刚重启。当前运行时长: {{ $value | humanizeDuration }}"
bash 复制代码
# 应用规则
kubectl apply -f node-restart-rule.yaml

2.应用并验证

bash 复制代码
# 验证规则是否加载成功
kubectl get prometheusrule node-restart-rule -n monitoring -o yaml

# 在 Prometheus UI 中确认规则已生效
kubectl port-forward svc/prometheus-k8s -n monitoring 9090:9090
# 访问 http://localhost:9090/rules,搜索 "NodeRecentlyRebooted"

# 2. 确认钉钉中间件运行正常
kubectl get pods -n monitoring -l app=dingtalk-webhook

# 3. 端口转发 Prometheus,在 UI 中确认规则已加载
kubectl port-forward svc/prometheus-k8s -n monitoring 9090:9090
# 浏览器访问 http://localhost:9090/rules,搜索 NodeMemoryUsageHigh

# 4. 手动触发测试(可选):在 Prometheus UI 的 Graph 页面执行
# time() - node_boot_time_seconds < 1800
# 确认有数据返回,说明 node-exporter 采集正常

3.字段详解

字段 含义与作用
apiVersion 指定使用的 API 版本。monitoring.coreos.com/v1 是 Prometheus Operator 提供的自定义资源(CRD)版本。
kind 资源类型。PrometheusRule 是 Prometheus Operator 用来管理告警和记录规则的专用资源。
metadata 资源的元数据,用于标识和管理。
metadata.name 这个规则对象在 Kubernetes 中的名称。
metadata.namespace 规则对象所在的命名空间。通常与 Prometheus 实例在同一命名空间(如 monitoring)。
metadata.labels 标签,至关重要。Prometheus 实例通过 serviceMonitorSelectorruleSelector 中的标签选择器来发现并加载这些规则。
spec.groups 告警规则的分组。一个 PrometheusRule 可以包含多个组,一个组可以包含多条规则。
spec.groups.name 规则组的名称,在 Prometheus UI 中会显示。
spec.groups.rules 规则列表,可以包含告警规则(Alerting Rules)和记录规则(Recording Rules)。
alert 告警名称。当表达式触发时,产生的告警就叫这个名字(如 NodeRecentlyRebooted)。
expr PromQL 表达式。这是告警的核心逻辑。time() - node_boot_time_seconds 计算出节点的运行时长(秒),< 120 表示运行时长小于 120 秒时条件成立。
for 持续时间。表达式 expr 的结果必须持续满足该时长,告警才会从 pending 状态变为 firing(触发)状态。设置为 1m 可以避免因节点刚启动、Exporter 尚未就绪而导致的瞬时误报。
labels 附加标签。可以为触发的告警添加自定义标签,用于告警路由和分类。severity: critical 是最常用的标签,用于区分告警的严重程度。
annotations 附加注解。用于提供更丰富的告警信息,不会用于告警路由,但会显示在通知内容中。
annotations.summary 告警的简要摘要,通常是一句话概括问题。{``{ $labels.instance }} 是 Go 模板语法,用于引用触发告警的实例地址。
annotations.description 告警的详细描述。{``{ $value }} 引用了表达式计算出的原始值,humanizeDuration 是一个模板函数,能将秒数(如 90)自动转换为可读格式(如 1m 30s)。
humanizeDuration 将秒数自动转换为可读格式(如 1m30s

4.业务侧告警

1.prometheusrule规则

bash 复制代码
vim business-rule.yaml
bash 复制代码
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: business-app-rule
  namespace: monitoring  # 建议放在 monitoring 命名空间,或你的业务命名空间
  labels:
    prometheus: k8s
    role: alert-rules
    app: business-monitoring
spec:
  groups:
    # ================= 1. 错误率告警 (Errors) =================
    - name: business_error_rate
      interval: 30s
      rules:
        - alert: HighHTTPErrorRate
          expr: |
            (
              sum(rate(http_requests_total{status=~"5.."}[5m])) by (service, instance)
              /
              sum(rate(http_requests_total[5m])) by (service, instance)
            ) * 100 > 5
          for: 3m
          labels:
            severity: critical
            team: backend
          annotations:
            summary: "🔥 服务 {{ $labels.service }} 5xx 错误率过高"
            description: "实例 {{ $labels.instance }} 过去5分钟 5xx 错误率高达 {{ $value | printf \"%.2f\" }}%,请立即检查日志和依赖服务。"

        - alert: HighHTTP4xxRate
          expr: |
            (
              sum(rate(http_requests_total{status=~"4.."}[5m])) by (service, instance)
              /
              sum(rate(http_requests_total[5m])) by (service, instance)
            ) * 100 > 20
          for: 5m
          labels:
            severity: warning
            team: backend
          annotations:
            summary: "⚠️ 服务 {{ $labels.service }} 4xx 错误率偏高"
            description: "实例 {{ $labels.instance }} 4xx 错误率 {{ $value | printf \"%.2f\" }}%,可能存在客户端调用异常或参数错误。"

    # ================= 2. 延迟告警 (Duration) =================
    - name: business_latency
      interval: 30s
      rules:
        - alert: HighRequestLatency
          expr: |
            histogram_quantile(0.99, 
              sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service, instance)
            ) > 1
          for: 5m
          labels:
            severity: warning
            team: backend
          annotations:
            summary: "🐢 服务 {{ $labels.service }} P99 延迟过高"
            description: "实例 {{ $labels.instance }} P99 延迟已达 {{ $value | printf \"%.2f\" }}s,可能由慢SQL、GC或下游超时引起。"

    # ================= 3. 流量异常告警 (Rate) =================
    - name: business_traffic
      interval: 1m
      rules:
        - alert: TrafficDrop
          expr: |
            sum(rate(http_requests_total[5m])) by (service) 
            < 
            sum(rate(http_requests_total[5m] offset 1d)) by (service) * 0.5
          for: 10m
          labels:
            severity: warning
            team: sre
          annotations:
            summary: "📉 服务 {{ $labels.service }} 流量骤降"
            description: "当前流量相比昨天同时段下降超过 50%,请检查上游网关、DNS 或是否发生了误发布。"

    # ================= 4. 业务逻辑告警 (示例) =================
    - name: business_logic
      interval: 1m
      rules:
        - alert: OrderFailureSpike
          expr: |
            sum(rate(business_orders_total{status="failed"}[5m])) by (service) > 10
          for: 2m
          labels:
            severity: critical
            team: business
          annotations:
            summary: "🛑 订单创建失败激增"
            description: "服务 {{ $labels.service }} 订单失败速率 {{ $value | printf \"%.1f\" }} 次/秒,请检查库存或支付网关。"

2.部署

bash 复制代码
kubectl apply -f business-rule.yaml

3.验证

bash 复制代码
# 检查规则是否被 Prometheus 加载
kubectl get prometheusrule business-app-rule -n monitoring

# 查看 Prometheus UI -> Status -> Rules,确认规则存在且无语法错误
相关推荐
mounter62519 分钟前
从 2026 LSFMM/BPF 峰会看 eBPF 生态演进:技术变革、工具全景与资源泄漏诊断实战
linux·linux kernel·kernel
M78佐菲23 分钟前
Linux学习笔记:网络通信
linux·笔记·学习·算法
AAA代码批发商33 分钟前
Days37 Linux C 网络编程:UDP、TCP 与 HTTP 协议实战详解
linux·c语言·网络
Ningcode_cloud36 分钟前
什么是CICD? GitLab + Jenkins 持续集成实战部署手册
运维·ci/cd·云原生·容器·gitlab·jenkins
好评12442 分钟前
【Linux】传输层协议UDP
linux·运维·udp
Csxyzj1 小时前
基于Linux+Docker NAT的Ollama多实例负载均衡部署
运维·docker·容器
流光D1 小时前
AI时代,搭建 web 站点并配置 nginx 反向代理流程
运维·服务器·前端·人工智能·nginx·ai·ai编程
GreatVicent1 小时前
AI Agent互操作标准化加速:A2A协议正式加入Linux基金会
linux·运维·人工智能·agent·aws·a2a
奇树谦2 小时前
Seaweed中filer.sync原理
linux·服务器·网络