监控

ServiceMonitor

·12 分钟阅读·4558 字

ServiceMonitor 的声明式采集配置、选择器、端点和 Prometheus Operator 工作流程

📋 目录

ServiceMonitor

当前已经进入 Prometheus 在 Kubernetes 中最核心的一层了。

前面我们理解了:

Target
  |
  |
Prometheus 去哪里采集

但是 Kubernetes 环境里有一个问题:

Pod IP 会变化,Prometheus 怎么知道应该采集哪些 Pod?

答案就是:

ServiceMonitor。

它是 kube-prometheus-stack 中实现 Kubernetes 自动发现监控目标的核心资源。


一、ServiceMonitor 是什么?

一句话:

ServiceMonitor 是 Prometheus Operator 定义的 Kubernetes CRD,用来告诉 Prometheus:应该监控哪些 Service,以及如何访问它们的 /metrics。

注意几个关键词:

  • Kubernetes CRD

  • Prometheus Operator

  • Service

  • metrics endpoint


没有 ServiceMonitor 的传统 Prometheus

以前:

prometheus.yml:

scrape_configs:
  - job_name: python-app
    static_configs:
      - targets:
        - 10.0.0.10:8000

问题:

如果 Pod 重启:

旧 Pod:

10.42.1.10

新 Pod:

10.42.3.20

Prometheus 配置失效。


二、ServiceMonitor 解决什么问题?

Kubernetes:

Pod
 |
 |
Service
 |
 |
ServiceMonitor
 |
 |
Prometheus

它不关心 Pod IP。

它只关心:

找到符合条件的 Service。


例如:

Python 服务:

python-app Pod

labels:

app=python-app

Service:

python-app-service

port:
8000

ServiceMonitor:

告诉 Prometheus:

找到 label:

app=python-app

然后访问:

metrics端口

/metrics

三、ServiceMonitor 工作流程

完整链路:

                Python程序
                    |
                    |
             prometheus_client
                    |
                    |
              /metrics接口
                    |
                    |
              Kubernetes Service
                    |
                    |
             ServiceMonitor
                    |
                    |
          Prometheus Operator
                    |
                    |
          生成prometheus.yml
                    |
                    |
              Prometheus Target

四、ServiceMonitor 本质是什么?

它也是 Kubernetes 对象。

查看:

kubectl get servicemonitor -n monitoring

你会看到:

NAME

monitoring-kube-state-metrics
monitoring-prometheus-node-exporter

查看:

kubectl get servicemonitor monitoring-kube-state-metrics \
-n monitoring -o yaml

类似:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor

metadata:
  name: kube-state-metrics

spec:

  selector:
    matchLabels:
      app.kubernetes.io/name: kube-state-metrics

  endpoints:

  - port: http
    interval: 30s

拆解:

1. selector

selector:
  matchLabels:
    app: python

意思:

找到:

labels:
  app: python

的 Service。


2. endpoints

endpoints:
- port: metrics

意思:

访问 Service 的:

metrics port

3. interval

interval: 15s

采集周期:

每15秒:

Prometheus
      |
      |
      GET /metrics

五、实践:Python 服务暴露 Metrics

我们写一个简单 FastAPI 服务。

目标:

实现:

Python
 |
 |
/metrics
 |
 |
Prometheus

1. 安装依赖

pip install fastapi uvicorn prometheus_client

2. Python代码

app.py

from fastapi import FastAPI
from prometheus_client import Counter, generate_latest
from starlette.responses import Response

app = FastAPI()

# 定义指标

request_count = Counter(
    "http_requests_total",
    "Total HTTP Requests"
)

@app.get("/")
def hello():

    request_count.inc()

    return {
        "message": "hello"
    }

@app.get("/metrics")
def metrics():

    return Response(
        generate_latest(),
        media_type="text/plain"
    )

启动:

uvicorn app:app --host 0.0.0.0 --port 8000

测试:

访问:

http://localhost:8000/metrics

看到:

# HELP http_requests_total Total HTTP Requests

http_requests_total 5

说明:

Python 已经成为 Metrics Provider。


六、部署到 Kubernetes

Deployment:

python-app.yaml

apiVersion: apps/v1
kind: Deployment

metadata:
  name: python-app

spec:

  replicas: 1

  selector:
    matchLabels:
      app: python-app

  template:

    metadata:
      labels:
        app: python-app

    spec:

      containers:

      - name: app

        image:
          your-python-image

        ports:

        - containerPort: 8000

七、创建 Service

关键:

必须暴露 metrics 端口。

service.yaml

apiVersion: v1
kind: Service

metadata:

  name: python-app

  labels:

    app: python-app

spec:

  selector:

    app: python-app

  ports:

  - name: metrics

    port: 8000

    targetPort: 8000

注意:

这里:

name: metrics

非常重要。

因为 ServiceMonitor 会引用它。


八、写 ServiceMonitor

python-app-servicemonitor.yaml

apiVersion: monitoring.coreos.com/v1

kind: ServiceMonitor

metadata:

  name: python-app-monitor

  namespace: monitoring

spec:

  selector:

    matchLabels:

      app: python-app

  namespaceSelector:

    matchNames:

    - default

  endpoints:

  - port: metrics

    path: /metrics

    interval: 15s

解释:


selector

matchLabels:

 app: python-app

找到:

Service:

metadata:
 labels:
   app: python-app

port

port: metrics

对应 Service:

ports:

- name: metrics

path

path: /metrics

访问:

http://service:8000/metrics

九、应用

部署:

kubectl apply -f python-app.yaml

kubectl apply -f service.yaml

kubectl apply -f python-app-servicemonitor.yaml

查看:

kubectl get servicemonitor -n monitoring

进入 Prometheus:

Status

↓

Targets

应该看到:

python-app-monitor

Endpoint:

python-app.default.svc:8000/metrics

State:

UP

十、查询自己的指标

Prometheus:

输入:

http_requests_total

返回:

http_requests_total 10

说明:

Python 服务已经进入监控体系。


十一、实际企业中的结构

你以后做 AIops Agent,基本就是这个模式:

业务服务

Python / Go / Java

       |
       |
   /metrics

       |
       |
 Service

       |
       |
 ServiceMonitor

       |
       |
 Prometheus

       |
       |
 PromQL

       |
       |
 AI Agent

例如:

AI Agent 查询:

rate(http_requests_total[5m])

发现:

QPS突然下降80%

然后:

调用:

kubectl logs
kubectl describe pod
git diff

自动分析。


十二、当前应该重点掌握的几个概念关系

Exporter
    |
    | 暴露
    ↓

Metrics Endpoint
    |
    | 被发现
    ↓

Target
    |
    | 自动生成
    ↓

ServiceMonitor
    |
    | 管理
    ↓

Prometheus Operator
    |
    |
    ↓

Prometheus

更准确:

ServiceMonitor 不是 Target。

它是:

创建和管理 Target 的声明。


当前学习路线已经从“Kubernetes 使用者”进入到“可观测平台开发者”的方向了。下一步非常建议继续学习:

  1. PromQL(如何查询指标)

  2. Recording Rule(预计算指标)

  3. AlertRule(自动告警)

  4. Prometheus API + Python Agent

这几个就是 AIops Agent 的数据基础。

Yanche Blog

记录云原生、Linux、数据库等技术领域的学习心得,以及日常生活的思考与感悟。

© 2026 Yanche Blog. All rights reserved.

Powered by Astro