servicemonitor 是 prometheus operator 提供的 crd,用于动态声明式监控 kubernetes service;它替代静态配置,自动发现 service 的增删与扩缩容,确保 nginx 等动态服务指标持续可采。

ServiceMonitor 是什么,为什么必须用它
ServiceMonitor 不是 Prometheus 原生资源,而是 Prometheus Operator 提供的自定义资源(CRD)。它的作用很明确:告诉 Operator “去监控哪些 Service、走哪个端口、从哪个路径拉取指标”。没有它,Prometheus 就只能靠静态配置抓取固定地址,无法自动感知 Kubernetes 中 Service 的增删或扩缩容。Nginx 作为 Ingress 控制器或独立服务,其 Pod 数量和 IP 经常变化,硬编码 target 地址会立刻失效。
配置前必须确认的三件事
缺一不可,否则 ServiceMonitor 创建后也不会生效:
-
Operator 已运行:执行
kubectl get pods -n monitoring(或你部署 Operator 的命名空间),看到prometheus-operator-xxx处于 Running 状态 -
Nginx Service 存在且带正确标签:比如 Nginx Ingress Controller 的 Service 通常有
app.kubernetes.io/name: ingress-nginx;自己部署的 Nginx 需确保 Service 的metadata.labels包含可被匹配的键值对 -
Nginx 容器已暴露 /metrics 端点:Ingress Controller 默认开启;自建 Nginx 需搭配 nginx-exporter 或启用 stub_status,并通过 Service 的
targetPort正确指向该端口
一份能跑通的 ServiceMonitor YAML 示例
以下配置适用于主流 Nginx Ingress Controller(如 ingress-nginx v1.0+),直接保存为 nginx-sm.yaml 并应用:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: nginx-ingress-controller
namespace: monitoring
labels:
team: infra
spec:
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
namespaceSelector:
matchNames:
- ingress-nginx
endpoints:
- port: metrics
interval: 30s
path: /metrics
scheme: http
说明:
-
selector.matchLabels必须与目标 Service 的 labels 完全一致 -
namespaceSelector.matchNames锁定 Service 所在命名空间,避免跨命名空间误匹配 -
endpoints.port要对应 Service 中定义的 port 名(不是容器端口数字),例如 Service 中写了- name: metrics,这里就填metrics
验证是否真正生效
别只看 ServiceMonitor 是否创建成功,要层层确认数据链路打通:
- 查 ServiceMonitor 状态:
kubectl get servicemonitor -n monitoring nginx-ingress-controller -o wide,观察 AGE 是否更新 - 查 Prometheus targets 页面:进入 Prometheus UI(通常是
http://<prometheus-svc>:9090/targets</prometheus-svc>),搜索关键词ingress-nginx,状态应为 UP,且显示真实 endpoint 地址(如10.244.1.12:10254) - 查指标是否存在:在 Prometheus 表达式框输入
nginx_ingress_controller_requests_total或nginx_ingress_controller_nginx_process_resident_memory_bytes,应有时间序列返回











