Skip to content

Prometheus Operator

Prometheus Operator 把 Prometheus、Alertmanager、抓取配置和告警规则变成 Kubernetes 资源。传统部署里要直接改 prometheus.yml;在 K8s 里,抓取目标会跟着 Pod、Service、namespace 变化,手工维护配置很容易乱。Operator 的作用就是把这些动态关系交给控制器处理。

这里的 PrometheusServiceMonitorPodMonitorPrometheusRule 都是 CRD 创建出来的自定义资源。CRD 和控制器的通用机制见 CRD 与控制器,Operator 的安装、升级和排错思路见 Operator 运维

一、核心对象

对象作用
Prometheus定义 Prometheus 实例、副本数、存储、选择哪些抓取配置
Alertmanager定义 Alertmanager 实例、存储、集群和访问方式
ServiceMonitor通过 Service 发现 /metrics 目标
PodMonitor直接通过 Pod 发现 /metrics 目标
PrometheusRule告警规则和记录规则
AlertmanagerConfig告警路由、接收器、静默和抑制相关配置

Operator 不是替代 Prometheus,它是管理 Prometheus 的控制器。Prometheus 进程仍然负责抓取指标、存储 TSDB、执行 PromQL 和计算规则。

二、ServiceMonitor

ServiceMonitor 匹配的是 Service 标签。Service 后面再通过 selector 找到 Pod,所以排查时要分两层看:ServiceMonitor 是否匹配 Service,Service 是否有 Endpoints。

yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: demo-app
  namespace: monitoring
  labels:
    release: kps
spec:
  namespaceSelector:
    matchNames:
      - demo
  selector:
    matchLabels:
      app: demo-app
  endpoints:
    - port: metrics
      path: /metrics
      interval: 30s

对应 Service:

yaml
apiVersion: v1
kind: Service
metadata:
  name: demo-app
  namespace: demo
  labels:
    app: demo-app
spec:
  selector:
    app: demo-app
  ports:
    - name: metrics
      port: 9100
      targetPort: metrics

endpoints.port 写的是 Service 里的端口名,不是数字端口。ServiceMonitor 没有生效时,常见原因是 Service label 不匹配、namespaceSelector 没包含业务 namespace、端口名写错、Prometheus 实例没有选择这条 ServiceMonitor。

三、PodMonitor

PodMonitor 直接匹配 Pod,不依赖 Service。它适合没有稳定 Service 的组件,或者确实需要按 Pod 抓取的场景。

yaml
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: demo-pods
  namespace: monitoring
  labels:
    release: kps
spec:
  namespaceSelector:
    matchNames:
      - demo
  selector:
    matchLabels:
      app: demo-app
  podMetricsEndpoints:
    - port: metrics
      path: /metrics
      interval: 30s

普通业务服务通常先用 ServiceMonitor。PodMonitor 更直接,但短生命周期 Pod 会让 target 变化更频繁。

四、PrometheusRule

PrometheusRule 负责声明告警规则和记录规则:

yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: pod-alerts
  namespace: monitoring
  labels:
    release: kps
spec:
  groups:
    - name: pod.rules
      rules:
        - alert: PodRestartingTooOften
          expr: increase(kube_pod_container_status_restarts_total[15m]) > 3
          for: 5m
          labels:
            severity: warning
          annotations:
            summary: "Pod 重启频繁"
            description: "namespace={{ $labels.namespace }} pod={{ $labels.pod }}"

这条规则依赖 kube-state-metrics 暴露的 Pod 重启指标。告警里保留 namespacepodcontainernode 这类标签,收到通知后才能定位对象。

五、selector 关系

kube-prometheus-stack 里,Prometheus 实例会通过 selector 选择 ServiceMonitor、PodMonitor 和 PrometheusRule。安装时如果设置:

yaml
prometheus:
  prometheusSpec:
    serviceMonitorSelectorNilUsesHelmValues: false
    podMonitorSelectorNilUsesHelmValues: false
    ruleSelectorNilUsesHelmValues: false

Prometheus 会更容易选择集群里新增的监控对象。小环境里这样比较省心;生产环境通常会按 label、namespace 和团队边界收口,避免任何 namespace 都能随便把 target 塞进 Prometheus。

六、排查入口

bash
# CRD 是否存在
kubectl get crd | grep monitoring.coreos.com

# Prometheus 实例
kubectl -n monitoring get prometheus

# ServiceMonitor 和 PodMonitor
kubectl get servicemonitor -A
kubectl get podmonitor -A

# 规则是否被加载
kubectl get prometheusrule -A

Prometheus 页面里的 Status -> Targets(中文:状态 -> 目标)是最终验证入口。K8s 资源创建成功,只说明声明写进了 apiserver;target 变成 UP,才说明发现链路、网络、端口、权限和 /metrics 都打通了。