3. 集群指标采集与ServiceMonitor实战
在OpenShift中,Prometheus Operator把“监控谁、怎么抓、抓哪些指标”抽象成了Kubernetes自定义资源(CRD)。运维人员不再手工编辑prometheus.yml,而是声明式地创建ServiceMonitor、PodMonitor和Probe三类对象,由Operator监听这些对象的变化,自动生成并热加载Prometheus的抓取配置。理解这三类资源的适用边界,是让业务自定义指标稳定进入集群监控的第一步。
三类采集资源的分工
ServiceMonitor面向Service,通过Service的标签选择器找到目标Service,再依据Service的端口名或targetPort定位后端Pod的指标端口,适合“一个Service对应一组同构Pod”的常规业务。PodMonitor直接选择Pod,不经过Service,适合没有Service、或者需要按Pod粒度单独抓取的场景,例如Job、DaemonSet或临时调试Pod。Probe则用于黑盒探测,它不抓取/metrics,而是让Prometheus主动访问HTTP、TCP或ICMP端点,判断可用性与响应延迟,常用于外部域名、Ingress入口或第三方依赖的健康检查。
三者的选择可以归纳为一条判断链:需要抓取应用暴露的指标文本,且目标有Service,用ServiceMonitor;有指标但无Service,用PodMonitor;不抓指标、只探测可达性与响应,用Probe。下面这张图展示了三类资源从声明到Prometheus实际抓取配置的转换关系。
为业务应用暴露自定义指标
要让ServiceMonitor真正抓到数据,业务应用必须先暴露符合Prometheus文本格式的指标。以Go应用为例,引入prometheus/client_golang后注册一个计数器和一个直方图:
httpRequests := prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "order_http_requests_total",
Help: "Total number of HTTP requests.",
},
[]string{"method", "path", "status"},
)
prometheus.MustRegister(httpRequests)
httpDuration := prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "order_http_request_duration_seconds",
Help: "HTTP request latency.",
Buckets: []float64{0.05, 0.1, 0.25, 0.5, 1, 2.5},
},
[]string{"method", "path"},
)
prometheus.MustRegister(httpDuration)
http.Handle("/metrics", promhttp.Handler())
指标命名遵循“应用前缀_单位_类型后缀”的约定,例如order_http_requests_total中的_total表示计数器,order_http_request_duration_seconds中的_seconds表示单位。暴露路径通常为/metrics,端口可以是业务端口,也可以单独开一个管理端口。部署后先用curl验证:
oc exec -it deploy/order-api -- curl -s localhost:8080/metrics | grep order_http
# HELP order_http_requests_total Total number of HTTP requests.
# TYPE order_http_requests_total counter
order_http_requests_total{method="GET",path="/orders",status="200"} 128
只有确认指标文本可被访问,后续的ServiceMonitor才有意义。如果这里返回404或空内容,应先排查应用侧,而不是怀疑Operator。
编写ServiceMonitor并接入集群监控
假设order-api的Service带有标签app=order-api,端口名为metrics,指向容器8080端口。ServiceMonitor的编写要点是:selector.matchLabels必须与Service标签一致;namespaceSelector决定在哪些命名空间查找Service;endpoints.port填写Service中定义的端口名,而不是数字端口。
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: order-api-monitor
namespace: app-prod
labels:
release: cluster-monitoring
spec:
namespaceSelector:
matchNames:
- app-prod
selector:
matchLabels:
app: order-api
endpoints:
- port: metrics
path: /metrics
interval: 30s
scrapeTimeout: 10s
honorLabels: true
其中release标签非常关键。OpenShift的Prometheus实例通常配置了serviceMonitorSelector,只选择带有特定标签的ServiceMonitor。如果创建的ServiceMonitor缺少该标签,Prometheus不会加载它,表现为Targets页面看不到目标。可通过以下命令确认Prometheus的选择器:
oc -n openshift-monitoring get prometheus k8s \
-o jsonpath='{.spec.serviceMonitorSelector}{"\n"}'
# 输出示例:{"matchLabels":{"release":"cluster-monitoring"}}
应用资源后,在OpenShift控制台的Observe → Targets中应能看到order-api-monitor对应的Endpoint,状态为UP。若为DOWN,常见原因是端口名不匹配、NetworkPolicy阻断了Prometheus到Pod的流量,或Service的selector没有选中任何Pod。可以先用oc get endpoints确认Service后端是否为空。
PodMonitor与Probe的典型用法
对于没有Service的批处理任务,PodMonitor直接按Pod标签选择。注意PodMonitor使用podMetricsEndpoints字段,且端口既可以是容器端口名,也可以是数字端口:
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: batch-job-monitor
namespace: app-prod
labels:
release: cluster-monitoring
spec:
selector:
matchLabels:
app: batch-job
podMetricsEndpoints:
- port: "9100"
path: /metrics
interval: 60s
Probe用于黑盒探测,需要先在Prometheus中配置blackbox exporter作为prober,再通过Probe资源指定目标。下面示例探测一个Ingress域名,判断HTTP状态码是否为2xx:
apiVersion: monitoring.coreos.com/v1
kind: Probe
metadata:
name: order-ingress-probe
namespace: app-prod
labels:
release: cluster-monitoring
spec:
jobName: order-ingress
interval: 30s
module: http_2xx
prober:
url: blackbox-exporter.monitoring.svc:9115
targets:
staticConfig:
static:
- https://order.example.com/healthz
Probe产生的指标包括probe_success(1表示成功,0表示失败)和probe_duration_seconds(探测耗时)。这两个指标适合配置告警,例如probe_success == 0持续2分钟即触发入口不可用告警。
验证与排障要点
接入完成后,建议按以下顺序验证:第一,用curl确认应用/metrics可访问;第二,用oc get servicemonitor确认资源已创建且标签正确;第三,在Targets页面确认目标状态;第四,在Prometheus查询框输入自定义指标名,确认能查到时间序列。若Targets中完全没有出现该job,优先检查ServiceMonitor的release标签与Prometheus的serviceMonitorSelector是否匹配;若目标出现但状态为DOWN,则检查端口名、路径、NetworkPolicy和证书。把这三类资源的标签选择关系理清,业务自定义指标就能稳定进入集群监控体系。