You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenShift多Pod部署下Prometheus指标被覆盖问题求助

问题与解决方案:多Pod下Prometheus指标不被覆盖的配置方法

场景与问题

我在OpenShift上部署了名为host status monitor app的Golang应用,同时部署了Prometheus实例及Operator。应用执行操作后会向Prometheus上报指标,已创建Service和Route,可通过该Route查看所有Prometheus指标并作为Grafana数据源。

当前问题:将应用Pod数量增至2个时,第二个Pod会覆盖第一个Pod上报的所有指标。

需求:配置多Pod部署,所有Pod的指标通过同一Route展示且互不影响。

应用上报指标的核心函数:

func PublishMetrics(hostName, originalState, swarch, server, provtype string) {
    states := []string{STATE_ACTIVE, STATE_UNRESPONSIVE, STATE_INACTIVE, STATE_DECOMISSIONED, STATE_REMOVED}

    for _, state := range states {
        HostStateGauge.With(prometheus.Labels{
            "host":     hostName,
            "state":    state,
            "swarch":   swarch,
            "server":   server,
            "provtype": provtype,
        }).Set(0)
    }
    HostStateGauge.With(prometheus.Labels{
        "host":     hostName,
        "state":    STATE_UNKNOWN,
        "swarch":   "",
        "server":   "",
        "provtype": "",
    }).Set(0)
    HostStateGauge.With(prometheus.Labels{
        "host":     hostName,
        "state":    originalState,
        "swarch":   swarch,
        "server":   server,
        "provtype": provtype,
    }).Set(1)
}

核心原因

Prometheus采集多Pod指标时,若指标的标签集合完全一致,后续Pod的指标会覆盖之前的记录。当前场景中,所有Pod上报的HostStateGauge指标没有区分Pod实例的标签,导致Prometheus无法识别不同Pod的指标,从而产生覆盖问题。


解决步骤

1. 为指标添加Pod实例标识标签

在Golang代码中,给HostStateGauge添加唯一标识Pod的标签(如pod_name),每个Pod启动时获取自身的Pod名称作为标签值:

首先添加获取Pod名称的逻辑(OpenShift会自动为Pod注入POD_NAME环境变量,本地调试可设置默认值):

import "os"

func getPodName() string {
    podName := os.Getenv("POD_NAME")
    if podName == "" {
        return "local-dev-pod"
    }
    return podName
}

修改PublishMetrics函数,新增pod标签:

func PublishMetrics(hostName, originalState, swarch, server, provtype string) {
    podName := getPodName()
    states := []string{STATE_ACTIVE, STATE_UNRESPONSIVE, STATE_INACTIVE, STATE_DECOMISSIONED, STATE_REMOVED}

    for _, state := range states {
        HostStateGauge.With(prometheus.Labels{
            "host":     hostName,
            "state":    state,
            "swarch":   swarch,
            "server":   server,
            "provtype": provtype,
            "pod":      podName, // 添加Pod标识标签
        }).Set(0)
    }
    HostStateGauge.With(prometheus.Labels{
        "host":     hostName,
        "state":    STATE_UNKNOWN,
        "swarch":   "",
        "server":   "",
        "provtype": "",
        "pod":      podName, // 添加Pod标识标签
    }).Set(0)
    HostStateGauge.With(prometheus.Labels{
        "host":     hostName,
        "state":    originalState,
        "swarch":   swarch,
        "server":   server,
        "provtype": provtype,
        "pod":      podName, // 添加Pod标识标签
    }).Set(1)
}

2. 确保Deployment注入POD_NAME环境变量

如果OpenShift未自动注入该变量,可在Deployment模板中手动配置:

spec:
  template:
    spec:
      containers:
      - name: host-status-monitor
        image: your-image:tag
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name

3. 配置Prometheus ServiceMonitor

通过Prometheus Operator创建ServiceMonitor,让Prometheus自动发现所有Pod的指标端点:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: host-status-monitor-servicemonitor
  labels:
    release: prometheus-operator # 匹配你的Prometheus实例release标签
spec:
  selector:
    matchLabels:
      app: host-status-monitor # 匹配应用Service的标签
  endpoints:
  - port: metrics # 应用Service暴露的指标端口名称
    interval: 30s

4. 验证指标展示

部署修改后的应用与配置后,通过Route访问Prometheus,查询HostStateGauge指标,会看到带有不同pod标签的多条记录,不会再出现覆盖。在Grafana中,可通过pod标签区分不同Pod的指标,或使用sum、avg等聚合函数汇总数据。


内容的提问来源于stack exchange,提问作者SRM KTR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 23:50:28