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 URL :https://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_token 和 secret 为你在钉钉群创建机器人时获得的值。

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_bytes 和 node_memory_MemAvailable_bytes 有数据。如果没有,说明 node-exporter 的 ServiceMonitor 有问题。
  • 告警恢复通知没收到 :确认 Alertmanager 的 webhook_configs 中 send_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 实例通过 serviceMonitorSelector 或 ruleSelector 中的标签选择器来发现并加载这些规则。
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,确认规则存在且无语法错误
相关推荐
像风一样自由20205 小时前
52.Docker部署大模型应用从本地开发到服务化运行
运维·人工智能·docker·容器·大模型·智能体
sxgzzn6 小时前
如何利用电缆故障定位在线监测系统提升供电安全?
运维·重构·无人机·开关柜局放在线监测·gis局放在线监测
曦夜日长6 小时前
Git系统篇,Git本地使用(一):从“究极进化版“到三个区域的底层原理
大数据·linux·git·elasticsearch
mengchanmian6 小时前
VSFTP 服务器搭建(Centos)
运维·服务器·centos
shimly1234566 小时前
给断网无 sudo ubuntu22.04 机器安装 nodejs
linux
别动我齐刘海8 小时前
Linux 系统调试学习1
linux·运维·服务器·c++·学习·机器学习·机器人
Lsetea8 小时前
OpenSSL报certificate chain too long:error 22与verify_depth深度排查
linux·https·ssl证书·openssl·证书链
陈陈CHENCHEN9 小时前
【Kubernetes】纯 IPv6 K8s 用 socat 打通 IPv4 服务
云原生·容器·kubernetes
不像程序员的程序媛9 小时前
linux常见文本操作命令
linux·运维·服务器
wangbing11259 小时前
开发指南149-IotDB-常用命令
linux·运维·iotdb