4. Prometheus 指标采集配置:ServiceMonitor、PodMonitor 与自定义指标

在 Kubernetes 环境中,Prometheus Operator 通过 ServiceMonitor 和 PodMonitor 两种 CRD(Custom Resource Definition)来声明式地管理指标采集目标。本章将深入讲解这两种资源的配置方法,并演示如何通过 Prometheus 配置文件重载 与 Relabeling 机制实现自定义指标的灵活采集,为蓝绿发布中的流量切换与回滚决策提供实时、精准的数据源。

4.1 ServiceMonitor:基于 Service 的自动发现

ServiceMonitor 通过匹配 Kubernetes Service 的标签,自动发现其后端 Endpoints,并生成 Prometheus 的抓取配置。这是生产环境中最常用的采集方式,适用于大多数无状态应用。

核心原理: Prometheus Operator 监听 ServiceMonitor 资源,将其转换为 Prometheus 的 scrape_config,通过 Kubernetes 服务发现自动获取目标 Pod 的 IP 和端口。

4.1.1 ServiceMonitor 配置示例

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: my-app-monitor
  namespace: monitoring
  labels:
    release: prometheus  # 必须与 Prometheus CR 的 serviceMonitorSelector 匹配
spec:
  selector:
    matchLabels:
      app: my-app        # 匹配目标 Service 的标签
  endpoints:
  - port: http           # 对应 Service 中定义的端口名称
    interval: 15s        # 抓取间隔
    path: /metrics       # 指标路径
    scheme: http
  namespaceSelector:
    any: true            # 允许跨命名空间发现
  targetLabels:
  - app                  # 将 Service 的 app 标签传递到指标标签中

4.1.2 关键字段说明

字段 说明 典型值
selector.matchLabels 用于匹配目标 Service 的标签 app: my-app
endpoints[].port 指定 Service 上暴露的端口名称或端口号 http 或 8080
endpoints[].interval Prometheus 抓取该目标的频率 15s、30s
namespaceSelector 控制 ServiceMonitor 生效的命名空间范围 any: true 或 matchNames: [prod]
targetLabels 将 Service 的标签传递到抓取目标的标签中 [app, version]
最佳实践: 在蓝绿发布场景中,建议在 Service 上添加 version: blue 或 version: green 标签,并通过 targetLabels 将其传递到指标中,便于在 Grafana 中区分流量版本。

4.2 PodMonitor:直接发现 Pod 实例

当应用不通过 Service 暴露,或者需要直接采集每个 Pod 的独立指标(如 Sidecar 容器、Job 类任务)时,PodMonitor 是更合适的选择。它直接匹配 Pod 的标签,无需依赖 Service 层。

4.2.1 PodMonitor 配置示例

apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: my-app-pod-monitor
  namespace: monitoring
  labels:
    release: prometheus
spec:
  selector:
    matchLabels:
      app: my-app
      component: sidecar   # 精确匹配 Pod 标签
  podMetricsEndpoints:
  - port: metrics          # 对应 Pod 中 containerPort 的名称
    interval: 10s
    path: /custom-metrics
    relabelings:
    - sourceLabels: [__meta_kubernetes_pod_label_version]
      targetLabel: version
      action: replace
  namespaceSelector:
    matchNames:
    - production

4.2.2 ServiceMonitor 与 PodMonitor 对比

对比维度 ServiceMonitor PodMonitor
发现对象 Service 的后端 Endpoints 直接匹配 Pod
适用场景 有 Service 代理的无状态应用 Sidecar、Job、DaemonSet 等
标签传递 通过 targetLabels 从 Service 继承 通过 relabelings 从 Pod 元数据提取
端口定义 引用 Service 的端口名称 引用 Pod 的 containerPort 名称
蓝绿发布优势 自动跟随 Service 后端切换 可精确采集特定版本 Pod
注意: 使用 PodMonitor 时,如果 Pod 被滚动更新或删除重建,Prometheus 会自动更新目标列表,但指标连续性会短暂中断。对于蓝绿发布中的实时对比,建议同时使用 ServiceMonitor 采集聚合指标,PodMonitor 采集单个 Pod 的详细指标。

4.3 自定义指标采集与 Relabeling 机制

Prometheus 的 Relabeling 是自定义指标采集的核心能力。它允许你在抓取前或抓取后对标签进行增、删、改、保留等操作,从而实现精细化的指标路由和过滤。

4.3.1 Relabeling 动作类型

动作 说明 常用场景
replace 将 sourceLabels 的值写入 targetLabel 将 Pod 标签映射为指标标签
keep 仅保留匹配 regex 的目标 只采集特定版本的 Pod
drop 丢弃匹配 regex 的目标 排除健康检查端点
labelmap 将源标签名映射到目标标签名 将 Kubernetes 元数据标签重命名
labeldrop 删除匹配的标签 清理不必要的标签以减少基数

4.3.2 自定义指标采集实战:蓝绿版本区分

以下示例展示如何在 ServiceMonitor 中通过 Relabeling 将 Pod 的 version 标签注入到抓取目标中,实现蓝绿版本的指标隔离。

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: app-version-monitor
  labels:
    release: prometheus
spec:
  selector:
    matchLabels:
      app: my-app
  endpoints:
  - port: http
    interval: 15s
    path: /metrics
    relabelings:
    # 将 Pod 的 version 标签映射为指标标签
    - sourceLabels: [__meta_kubernetes_pod_label_version]
      targetLabel: deploy_version
      action: replace
    # 保留 version 为 blue 或 green 的 Pod
    - sourceLabels: [deploy_version]
      regex: "(blue|green)"
      action: keep
    # 添加一个静态标签标识采集来源
    - targetLabel: monitor_source
      replacement: "service-monitor"
      action: replace
效果: 经过上述 Relabeling 后,Prometheus 抓取到的每个指标都会携带 deploy_version="blue" 或 deploy_version="green" 标签,以及 monitor_source="service-monitor" 标签。在蓝绿发布期间,你可以直接通过 deploy_version 标签查询不同版本的指标。

4.4 指标采集架构总览

下图展示了 Prometheus Operator 环境下,ServiceMonitor 与 PodMonitor 如何协同工作,以及 Relabeling 在数据流中的位置。

Prometheus 指标采集架构图 Prometheus 指标采集架构:ServiceMonitor / PodMonitor / Relabeling Kubernetes 集群 Service app: my-app Pod (Blue) version: blue Pod (Green) version: green Prometheus Operator CRD 资源 ServiceMonitor 匹配 Service 标签 PodMonitor 直接匹配 Pod 标签 Prometheus 采集与 Relabeling Relabeling (抓取前) keep/drop/replace 指标抓取 /metrics TSDB 存储 带版本标签 说明:ServiceMonitor 通过 Service 发现 Pod;PodMonitor 直接发现 Pod;Relabeling 在抓取前完成标签转换与过滤

4.5 配置验证与调试

完成配置后,可以通过以下步骤验证指标采集是否生效:

  1. 检查 Prometheus Target 状态: 访问 Prometheus UI → Status → Targets,确认 ServiceMonitor 或 PodMonitor 对应的目标处于 UP 状态。
  2. 查看抓取日志: 使用 kubectl logs -n monitoring prometheus-prometheus-0 查看 Prometheus 日志,排查连接错误或 Relabeling 问题。
  3. 验证指标标签: 在 Prometheus UI 的 Graph 页面执行 {deploy_version="blue"} 查询,确认标签是否正确注入。
  4. 使用 Promtool 检查配置: promtool check config prometheus.yaml 验证配置文件语法。
快速调试技巧: 在 ServiceMonitor 或 PodMonitor 中添加 relabelings 时,可以先使用 action: replace 并设置 targetLabel: debug_label,然后在 Prometheus UI 的 Target 页面查看该标签的值是否符合预期。

4.6 蓝绿发布中的采集策略建议

场景 推荐采集方式 关键配置
蓝绿版本流量对比 ServiceMonitor + Relabeling 通过 __meta_kubernetes_pod_label_version 注入版本标签
单个 Pod 粒度调试 PodMonitor 直接匹配 Pod 标签,避免 Service 负载均衡干扰
Sidecar 指标采集 PodMonitor 指定 Sidecar 容器的端口名称
跨命名空间监控 ServiceMonitor + namespaceSelector.any: true 确保 Prometheus 有对应命名空间的访问权限
指标基数控制 Relabeling 的 labeldrop 或 keep 删除不必要的 Pod 标签,避免高基数问题

通过合理组合 ServiceMonitor、PodMonitor 和 Relabeling,你可以在蓝绿发布过程中获得精确到版本、Pod 粒度的指标数据,为后续的流量切换决策和回滚判断提供坚实的数据基础。