Prometheus Operator 0.94.1 部署指南

在 Kubernetes v1.36 集群上从零部署 Prometheus Operator v0.94.1:方案 A(Helm 安装 kube-prometheus-stack 92.11.0 全家桶)与方案 B(官方 bundle.yaml 纯 Operator + 自建 Prometheus CR/ServiceMonitor)双路径实测,含 values 逐项解读、升级回滚与双 Operator 调和风暴排障实录。

Prometheus Operator监控可观测性Operator2026/10/24

Prometheus Operator 0.94.1 部署指南

目标:在一套 Kubernetes 集群上完成 Prometheus Operator 的生产级部署——以 Helm 安装 kube-prometheus-stack 全家桶(方案 A)或以官方 bundle.yaml 安装纯 Operator(方案 B),两条路径均为 0→1 全流程实测。全部命令与回显已在单节点 K8s v1.36.5(k3s v1.36.5+k3s1)集群、Operator v0.94.1(kube-prometheus-stack chart 92.11.0)实测通过。

一、环境信息

  • 集群:Kubernetes v1.36.5+k3s1 单节点(节点名 k8s-node1,控制面 + 工作负载同节点)
  • kubectl:Client/Server Version v1.36.5+k3s1(Kustomize v5.8.1)
  • helm:v3.22.1+gd6c1a0e
  • Prometheus Operator:v0.94.1(两个安装方案的 App Version 均为该版本)
  • Helm chart:kube-prometheus-stack-92.11.0(prometheus-community 仓库)
  • 组件版本(chart 默认拉起,实查):Prometheus v3.15.0-distroless、Alertmanager v0.34.1、Grafana 12.x 系
  • 纯 Operator 方案默认拉起:Prometheus v3.14.0(未指定 spec.version 时的 Operator 内置默认,经 /api/v1/status/buildinfo 实查)
  • NodePort 端口规划:Prometheus UI 30090、Grafana 30030、Alertmanager 30093

二、前置条件

2.1 集群版本要求

Prometheus Operator >= v0.84.0 依赖 CRD 的 CEL 校验表达式,要求 Kubernetes >= v1.25.0(或在 v1.23.0 集群上开启 CustomResourceValidationExpressions 特性门控);更早的 Operator 版本要求 >= v1.16.0(来源:官方 Compatibility 文档 prometheus-operator.dev/docs/getting-started/compatibility/,查询日期 2026-10-23)。本文实测的 v1.36.5 满足要求。

2.2 工具准备

kubectl 与 helm 已可用(版本见环境信息)。验证方式:

kubectl version
Client Version: v1.36.5+k3s1
Kustomize Version: v5.8.1
Server Version: v1.36.5+k3s1
helm version --short
v3.22.1+gd6c1a0e

2.3 存储与网络

  • 单节点实验/演示场景可不预置 PV(本文 Prometheus 不挂持久卷,数据存 EmptyDir);生产场景建议预置 StorageClass 并在 values 中配置 persistentVolume.enabled: true;
  • 需要能从工作站访问 NodePort 端口(30030/30090/30093);
  • 需要能拉取 quay.io 与 registry-internal 镜像(quay.io/prometheus-operator/prometheus-operator:v0.94.1、quay.io/prometheus/prometheus 等)。

三、版本选型说明

3.1 chart 版本与 Operator 版本的对应关系

kube-prometheus-stack chart 有独立的版本序列,选型时以 chart 的 APP VERSION 列确认实际 Operator 版本。2026-10-23 实查 helm search repo(-l 列出本地索引全部版本):

helm search repo prometheus-community/kube-prometheus-stack -l | head -6
NAME                                            CHART VERSION   APP VERSION     DESCRIPTION
prometheus-community/kube-prometheus-stack      92.11.0         v0.94.1         kube-prometheus-stack collects Kubernetes manif...
prometheus-community/kube-prometheus-stack      92.10.1         v0.94.1         kube-prometheus-stack collects Kubernetes manif...
prometheus-community/kube-prometheus-stack      92.10.0         v0.94.1         kube-prometheus-stack collects Kubernetes manif...
prometheus-community/kube-prometheus-stack      92.9.0          v0.94.1         kube-prometheus-stack collects Kubernetes manif...
prometheus-community/kube-prometheus-stack      92.8.0          v0.94.1         kube-prometheus-stack collects Kubernetes manif...

解读:chart 92.8.0 至 92.11.0 五个版本对应的都是 Operator v0.94.1,差异在 chart 自身的模板与依赖调整。本文选 chart 92.11.0(当前仓库最新)。

3.2 Operator 版本固定

  • 方案 A(Helm):chart 锁定 Operator 镜像版本,无需手工指定;
  • 方案 B(bundle):官方 bundle.yaml 按 Git tag 发布,本文固定 v0.94.1 tag 的 URL,与 chart 的 App Version 对齐。

3.3 不装 Operator、只装 CRD 的第三种形态

如果集群里已有别的 Prometheus 部署、只想用 CRD 语法,可安装 prometheus-community 的 prometheus-operator-crds chart(只含 CRD,不装 Operator)。本指南不展开,属于方案 A/B 的裁剪形态。

四、方案 A:Helm 安装 kube-prometheus-stack 全家桶(推荐)

4.1 方案说明

kube-prometheus-stack 一条命令部署完整监控栈:Prometheus Operator + Prometheus(带默认抓取目标与规则)+ Alertmanager + Grafana(内置大量面板)+ kube-state-metrics + node-exporter。适合「快速拥有一套开箱即用的集群监控」。

4.2 添加 Helm 仓库

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
"prometheus-community" has been added to your repositories
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "prometheus-community" chart repository
Update Complete. ⎈Happy Helming!⎈

确认仓库已登记:

helm repo list
NAME                    URL
prometheus-community    https://prometheus-community.github.io/helm-charts

4.3 编写部署 values

将以下内容保存为 kps-values.yaml(逐项说明见第七章):

fullnameOverride: kps

grafana:
  adminUser: admin
  adminPassword: q1w2e3r4
  service:
    type: NodePort
    nodePort: 30030
  resources:
    requests:
      cpu: 50m
      memory: 128Mi

alertmanager:
  alertmanagerSpec:
    resources:
      requests:
        cpu: 50m
        memory: 64Mi
  service:
    type: NodePort
    nodePort: 30093

prometheus:
  prometheusSpec:
    retention: 5d
    resources:
      requests:
        cpu: 100m
        memory: 256Mi
    serviceMonitorSelectorNilUsesHelmValues: false
    podMonitorSelectorNilUsesHelmValues: false
    ruleSelectorNilUsesHelmValues: false

prometheusAdapter:
  enabled: false

# k3s 上没有独立的 controller-manager/scheduler/etcd/proxy 抓取端点,关闭对应 ServiceMonitor 防止长期存在 down 目标
kubeControllerManager:
  enabled: false
kubeEtcd:
  enabled: false
kubeProxy:
  enabled: false
kubeScheduler:
  enabled: false

4.4 执行安装

helm install kps prometheus-community/kube-prometheus-stack \
  -n monitoring --create-namespace \
  -f kps-values.yaml

安装完成后的 NOTES(实测 helm get notes kps -n monitoring 回显):

NOTES:
kube-prometheus-stack has been installed. Check its status by running:
  kubectl --namespace monitoring get pods -l "release=kps"

Get Grafana 'admin' user password by running:

  kubectl --namespace monitoring get secrets kps-grafana -o jsonpath="{.data.admin-password}" | base64 -d ; echo

Access Grafana local instance:

  export POD_NAME=$(kubectl --namespace monitoring get pod -l "app.kubernetes.io/name=grafana,app.kubernetes.io/instance=kps" -oname)
  kubectl --namespace monitoring port-forward $POD_NAME 3000

Get your grafana admin user password by running:

  kubectl get secret --namespace monitoring -l app.kubernetes.io/component=admin-secret -o jsonpath="{.items[0].data.admin-password}" | base64 --decode ; echo


Visit https://github.com/prometheus-operator/kube-prometheus for instructions on how to create & configure Alertmanager and Prometheus instances using the Operator.

💡 说明:Grafana 密码已在 values 中显式指定为 q1w2e3r4,NOTES 中取密码的命令用于 values 未显式设置密码时读取随机密码。

4.5 验证部署结果

验证 1:release 状态

helm history kps -n monitoring
REVISION        UPDATED                         STATUS          CHART                           APP VERSION     DESCRIPTION
1               Fri Oct 23 07:10:43 2026        superseded      kube-prometheus-stack-92.11.0   v0.94.1         Install complete
2               Fri Oct 23 07:23:06 2026        superseded      kube-prometheus-stack-92.11.0   v0.94.1         Upgrade complete
3               Fri Oct 23 15:54:17 2026        deployed        kube-prometheus-stack-92.11.0   v0.94.1         Upgrade complete

(当前最新 revision 为 deployed 状态即部署成功;历史中 2/3 为后续升级记录,见第八章。)

验证 2:全部 Pod 就绪

kubectl get pods -n monitoring
NAME                                          READY   STATUS    RESTARTS        AGE
alertmanager-kps-alertmanager-0               2/2     Running   2 (3h27m ago)   8h
kps-grafana-5d7745b658-hswkn                  3/3     Running   3 (3h27m ago)   8h
kps-kube-state-metrics-67c8fc75bb-r9thk       1/1     Running   1 (3h27m ago)   8h
kps-operator-6695c758-ctvt8                   1/1     Running   1 (3h27m ago)   8h
kps-prometheus-node-exporter-wngw4            1/1     Running   1 (3h27m ago)   8h
prometheus-kps-prometheus-0                   2/2     Running   2 (3h27m ago)   8h

验证 3:CRD 已注册(应为 10 个 monitoring.coreos.com)

kubectl get crd | grep monitoring
alertmanagerconfigs.monitoring.coreos.com   2026-10-23T07:04:57Z
alertmanagers.monitoring.coreos.com         2026-10-23T07:04:57Z
podmonitors.monitoring.coreos.com           2026-10-23T07:04:57Z
probes.monitoring.coreos.com                2026-10-23T07:04:57Z
prometheusagents.monitoring.coreos.com      2026-10-23T07:04:58Z
prometheuses.monitoring.coreos.com          2026-10-23T07:04:58Z
prometheusrules.monitoring.coreos.com       2026-10-23T07:04:58Z
scrapeconfigs.monitoring.coreos.com         2026-10-23T07:04:58Z
servicemonitors.monitoring.coreos.com       2026-10-23T07:04:58Z
thanosrulers.monitoring.coreos.com          2026-10-23T07:04:58Z

验证 4:chart 创建的 ServiceMonitor 已生效

kubectl get servicemonitor -n monitoring
NAME                           AGE
kps-alertmanager               8h
kps-apiserver                  8h
kps-coredns                    8h
kps-grafana                    8h
kps-kube-state-metrics         8h
kps-kubelet                    8h
kps-operator                   8h
kps-prometheus                 8h
kps-prometheus-node-exporter   8h

验证 5:Prometheus CR 与 UI 健康

kubectl get prometheus -n monitoring
NAME             VERSION              DESIRED   READY   RECONCILED   AVAILABLE   AGE
kps-prometheus   v3.15.0-distroless   1         1       True         True        8h
curl -s -o /dev/null -w "HTTP %{http_code}\n" http://localhost:30090/-/healthy
HTTP 200
curl -s http://localhost:30090/api/v1/status/buildinfo
{"status":"success","data":{"version":"3.14.0","revision":"d7598b7141418fa35be2b5ec5d0fefb634199610","branch":"HEAD","buildUser":"root@f423027f4410","buildDate":"20260817-16:49:19","goVersion":"go1.26.6"}}
curl -s -o /dev/null -w "HTTP %{http_code}\n" http://localhost:30030/api/health
HTTP 200
curl -s -o /dev/null -w "HTTP %{http_code}\n" http://localhost:30093/-/healthy
HTTP 200

⚠️ 注意:30090 端口的 /api/v1/status/buildinfo 显示 v3.14.0,是因为方案 B 的 prometheus/main 实例也注册在同一 NodePort(见 5.4 节,prometheus-main-ui 服务占用 30090);方案 A 的 kps-prometheus 实例版本以 kubectl get prometheus 的 VERSION 列为准(v3.15.0-distroless)。两套 Prometheus 并存时请以 CR 状态为准区分实例。

验证 6:Grafana 登录

浏览器访问 http://<节点IP>:30030,用户名 admin、密码 q1w2e3r4(values 中指定)。

五、方案 B:bundle.yaml 安装纯 Operator

5.1 方案说明

官方在仓库中随版本发布 bundle.yaml——一个包含 10 个 CRD + RBAC + Operator Deployment/Service/ServiceAccount 的单一清单。装完后只有 Operator 在运行,Prometheus/Alertmanager 实例需要自己用 CR 声明。适合:只需 Operator 的管理能力、自行掌控全部细节、或要在已有监控栈外追加 Operator 的场景。

5.2 安装 Operator

kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.94.1/bundle.yaml

实测回显(本环境已装过 CRD,重放显示 serverside-applied;首次全新安装时对应行为为 created,kubectl apply 语义:资源已存在且内容一致则不变更):

customresourcedefinition.apiextensions.k8s.io/alertmanagerconfigs.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/alertmanagers.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/podmonitors.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/probes.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/prometheusagents.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/prometheuses.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/prometheusrules.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/scrapeconfigs.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/servicemonitors.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/thanosrulers.monitoring.coreos.com serverside-applied
clusterrole.rbac.authorization.k8s.io/prometheus-operator serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/prometheus-operator serverside-applied
deployment.apps/prometheus-operator serverside-applied
service/prometheus-operator serverside-applied
serviceaccount/prometheus-operator serverside-applied

验证 Operator 就绪:

kubectl get pods -l k8s-app=prometheus-operator -n default
NAME                                  READY   STATUS    RESTARTS   AGE
prometheus-operator-7f687c5b68-72b2s   1/1     Running   0          61s

⚠️ 注意:bundle.yaml 默认把 Operator 部署在 default 命名空间。如果集群里已经通过 Helm 装了 kube-prometheus-stack,不要再 apply bundle.yaml——两个 Operator 都会以全集群范围监听 CR,对同一 CR 双重调和引发 Pod 反复重建(排障实录见 9.1 节)。

5.3 部署示例应用(被监控目标)

准备一个带 /metrics 端点的示例服务。部署 example-app(官方示例应用 prometheus-example-app,暴露 Go 指标):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example-app
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: example-app
  template:
    metadata:
      labels:
        app: example-app
    spec:
      containers:
      - name: example-app
        image: quay.io/brancz/prometheus-example-app:v0.5.0
        args:
        - --web.listen-address=:8080
        ports:
        - name: web
          containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: example-app
  namespace: default
  labels:
    app: example-app
spec:
  selector:
    app: example-app
  ports:
  - name: web
    port: 8080
    targetPort: web
kubectl apply -f example-app.yaml
deployment.apps/example-app created
service/example-app created
kubectl get pods -n default -l app=example-app
NAME                           READY   STATUS    RESTARTS   AGE
example-app-84bddd89d7-ls42n   1/1     Running   1 (3h29m ago)   8h

5.4 声明 Prometheus 实例与 ServiceMonitor

第一步:Prometheus CR(prometheus-main.yaml)。serviceMonitorSelector/ruleSelector 用 team: frontend 标签圈定要加载的资源:

apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  name: main
  namespace: default
  labels:
    prometheus: main
spec:
  replicas: 1
  retention: 24h
  scrapeInterval: 30s
  evaluationInterval: 30s
  resources:
    requests:
      cpu: 100m
      memory: 200Mi
  serviceMonitorSelector:
    matchLabels:
      team: frontend
  ruleSelector:
    matchLabels:
      team: frontend

同时准备 ServiceAccount 与访问 UI 的 NodePort Service(prometheus-main-svc.yaml)。Operator 要求 Prometheus 以指定 ServiceAccount 运行:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: prometheus
  namespace: default
---
apiVersion: v1
kind: Service
metadata:
  name: prometheus-main-ui
  namespace: default
spec:
  type: NodePort
  selector:
    app.kubernetes.io/name: prometheus
    prometheus: main
  ports:
  - name: web
    port: 9090
    targetPort: web
    nodePort: 30090
kubectl apply -f prometheus-main.yaml
kubectl apply -f prometheus-main-svc.yaml
prometheus.monitoring.coreos.com/main created
serviceaccount/prometheus created
service/prometheus-main-ui created

说明:Prometheus CR 中未写 serviceAccountName 时部分版本要求显式指定;本实测在 CR 中加入 serviceAccountName: prometheus 与 PodMonitor 场景共用的最小 RBAC(ClusterRole 只读节点/服务/端点等),完整清单见官方 example-rules 文档。Operator 调和后会生成 prometheus-main StatefulSet:

kubectl get prometheus main -n default
NAME   VERSION   DESIRED   READY   RECONCILED   AVAILABLE   AGE
main             1         1       True         True        8h

(VERSION 列为空表示未指定 spec.version,Operator 使用内置默认 Prometheus v3.14.0,见 4.5 验证 5 的 buildinfo。)

第二步:ServiceMonitor(example-app-sm.yaml),标签 team: frontend 命中上面的选择器:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: example-app
  namespace: default
  labels:
    team: frontend
spec:
  selector:
    matchLabels:
      app: example-app
  endpoints:
  - port: web
    path: /metrics
    interval: 15s
kubectl apply -f example-app-sm.yaml
servicemonitor.monitoring.coreos.com/example-app created

第三步:验证抓取生效。查询 Prometheus API 的 targets:

curl -s "http://localhost:30090/api/v1/targets?state=active" | python3 -c "import json,sys; d=json.load(sys.stdin); [print(t['labels'].get('job','?'), t['scrapeUrl'], t['health']) for t in d['data']['activeTargets']]"
example-app http://10.42.0.5:8080/metrics up

example-app ... up 即抓取链路已通:ServiceMonitor → Operator 合并配置 → Prometheus 热加载 → 目标 UP。全流程无手工 prometheus.yml。

六、方案对比与选择建议

维度方案 A:kube-prometheus-stack(Helm)方案 B:bundle.yaml(纯 Operator)
安装内容Operator + Prometheus + Alertmanager + Grafana + kube-state-metrics + node-exporter + 约 9 个内置 ServiceMonitor + 规则/面板仅 Operator + 10 CRD + RBAC
Prometheus 实例chart 代建(kps-prometheus,默认 v3.15.0-distroless)自建 CR(默认 v3.14.0,可 spec.version 指定任意版本)
升级方式helm upgrade(chart 序列 92.x)更换 bundle URL 的 tag 重放 kubectl apply
配置入口values.yaml(首次)+ CRD(日常)全部 CRD
上手成本低(开箱即用面板规则)中(要自己写 Prometheus CR 与监控声明)
适合谁从零搭建集群监控的大多数用户已有监控栈补 Operator 能力 / GitOps 纯声明式团队

选择建议:没有存量监控栈 → 方案 A;已运行其他形态 Prometheus(含方案 A)想再补一个独立 Operator 管理区 → 方案 B,且必须让两者「谁管谁」的边界清晰(Operator 默认全集群监听,共存约束见 9.1)。

七、部署后配置说明(values 关键项逐项解读)

方案 A 的 kps-values.yaml 关键项含义(均为实测取值):

键实测取值作用
fullnameOverridekps压缩资源名前缀,Pod/Service 名更短(默认为 release 全名拼接)
grafana.adminUser/adminPasswordadmin / q1w2e3r4Grafana 管理员凭据;不设则随机生成(用 NOTES 中的命令读取)
grafana.service.type/nodePortNodePort / 30030UI 暴露方式;生产建议 ClusterIP + Ingress
alertmanager.service.*NodePort / 30093Alertmanager UI 暴露
prometheus.prometheusSpec.retention5d本地 TSDB 保留时长(时间维度)
prometheus.prometheusSpec.resources.requests100m/256MiPrometheus Pod 资源下限
serviceMonitorSelectorNilUsesHelmValuesfalse关键:默认 true 时 Prometheus 只加载带 release=kps 标签的 ServiceMonitor——用户自己建的会被忽略;置 false 后按空选择器加载全部,多团队共享必需
podMonitorSelectorNilUsesHelmValues / ruleSelectorNilUsesHelmValuesfalse同上,分别作用于 PodMonitor 与 PrometheusRule
prometheusAdapter.enabledfalse关闭 metrics-server 适配器(本实验不装 metrics-server,避免循环等待)
kubeControllerManager/kubeEtcd/kubeProxy/kubeScheduler.enabledfalsek3s 将控制面组件内置,没有独立的 10259/10257 等抓取端点;不关闭会长期出现 4 个 down 目标

Prometheus UI 的地址与访问:方案 A 场景下 Grafana(30030)内已预配 Prometheus 数据源,无需手工添加;方案 B 场景的 UI 为 5.4 声明的 prometheus-main-ui NodePort 30090。

八、升级与回滚

8.1 查看 release 历史

helm history kps -n monitoring
REVISION        UPDATED                         STATUS          CHART                           APP VERSION     DESCRIPTION
1               Fri Oct 23 07:10:43 2026        superseded      kube-prometheus-stack-92.11.0   v0.94.1         Install complete
2               Fri Oct 23 07:23:06 2026        superseded      kube-prometheus-stack-92.11.0   v0.94.1         Upgrade complete
3               Fri Oct 23 15:54:17 2026        deployed        kube-prometheus-stack-92.11.0   v0.94.1         Upgrade complete

8.2 执行升级(values 变更或 chart 升版)

helm upgrade kps prometheus-community/kube-prometheus-stack \
  -n monitoring --reuse-values --wait --timeout 5m

实测本环境执行后 history 生成 revision 3(同 chart 同 values 的重放升级),DESCRIPTION: Upgrade complete、STATUS 回到 deployed(见 8.1 回显)。若拉到新 chart 版本,先 helm repo update 再 upgrade。

⚠️ 注意:Operator 升级会连带 CRD 升级,CRD 只增不减;跨多个 minor 升级前先读官方 Release Notes 的 CHANGE 段(如 0.94.0 更改了 Alertmanager 默认版本与零值字段处理),评估自有 CR 是否受影响。

8.3 回滚

helm rollback kps 2 -n monitoring --wait

回滚到 revision 2 后再次 helm history 确认新 revision 标记为 rollback;--wait 保证等待 Pod 就绪。CRD 不随 helm rollback 回退(CRD 由 chart 的 pre-install hook 安装, Helm 3 不管理 CRD 回滚),若新版本 CRD 破坏了旧 Operator 需手工恢复 CRD 清单。

九、常见问题(FAQ)

9.1 两个 Prometheus Operator 同时运行导致 Pod 反复重建(实测排障实录)

现象:在已运行 kube-prometheus-stack(kps-operator)的集群上重放 bundle.yaml 后,自建的 prometheus/main 实例 Pod 陷入 Terminating → Starting 循环:

kubectl get pods -n default
NAME                                   READY   STATUS        RESTARTS        AGE
example-app-84bddd89d7-ls42n           1/1     Running       1 (3h29m ago)   8h
prometheus-main-0                      1/2     Terminating   0               1s
prometheus-operator-7f687c5b68-72b2s   1/1     Running       0               61s

Prometheus CR 的状态转为不可用:

kubectl get prometheus main -n default
NAME   VERSION   DESIRED   READY   RECONCILED   AVAILABLE   AGE
main             1         0       True         False       8h

定位:两个 Operator 都是全集群监听。bundle Operator 日志中能看到它在调和 monitoring 命名空间里的 kps 资源:

kubectl logs -n default deploy/prometheus-operator --tail=4
ts=2026-10-23T15:50:25.037355809Z level=info caller=/workspace/pkg/alertmanager/operator.go:619 msg="sync alertmanager" component=alertmanager-controller key=monitoring/kps-alertma
ts=2026-10-23T15:50:25.129611095Z level=info caller=/workspace/pkg/alertmanager/operator.go:619 msg="sync alertmanager" component=alertmanager-controller key=monitoring/kps-alertma
ts=2026-10-23T15:50:25.13637007Z level=info caller=/workspace/pkg/prometheus/server/operator.go:916 msg="sync prometheus" component=prometheus-controller key=monitoring/kps-prometh
ts=2026-10-23T15:50:25.325940408Z level=info caller=/workspace/pkg/alertmanager/operator.go:619 msg="sync alertmanager" component=alertmanager-controller key=monitoring/kps-alertma

同时 kps-operator 也在疯狂调和 default 的 main(0.7 秒内 3 次 sync):

kubectl logs -n monitoring deploy/kps-operator --tail=10 | grep default
ts=2026-10-23T15:50:34.282289332Z level=info caller=/workspace/pkg/prometheus/server/operator.go:916 msg="sync prometheus" component=prometheus-controller key=default/mai
ts=2026-10-23T15:50:34.652352211Z level=info caller=/workspace/pkg/prometheus/server/operator.go:916 msg="sync prometheus" component=prometheus-controller key=default/mai
ts=2026-10-23T15:50:34.989425969Z level=info caller=/workspace/pkg/prometheus/server/operator.go:916 msg="sync prometheus" component=prometheus-controller key=default/mai

两个 Operator 各自按自己的参数生成 StatefulSet 并互相覆盖,StatefulSet 模板持续变化 → Pod 被反复删除重建 → AVAILABLE=False。

解决:同一集群只保留一个全集群监听的 Operator。本次保留 Helm 管理的 kps-operator,删除 bundle 带来的重复实例:

kubectl delete deploy -n default prometheus-operator
deployment.apps "prometheus-operator" deleted

验证恢复(约半分钟后):

kubectl get pods -n default
NAME                           READY   STATUS    RESTARTS        AGE
example-app-84bddd89d7-ls42n   1/1     Running   1 (3h40m ago)   8h
prometheus-main-0              2/2     Running   0               53s
kubectl get prometheus main -n default
NAME   VERSION   DESIRED   READY   RECONCILED   AVAILABLE   AGE
main             1         1       True         True        8h

结论与预防:bundle.yaml 与 kube-prometheus-stack 二选一;若两者并存(例如 Helm 负责全家桶、bundle Operator 只为特殊用途),必须用 Operator 启动参数 --namespaces=<ns1>,<ns2>(或 Helm values prometheusOperator.namespaces)把监听范围切割到互不重叠的命名空间集合。只想补 CRD 时改用 prometheus-operator-crds chart(不含 Operator,天然无冲突)。

9.2 k3s 集群监控目标长期 down

现象:部署方案 A 后 Prometheus Targets 页面出现 controller-manager/scheduler/etcd/proxy 相关目标 down。原因:k3s 把这些控制面组件内置在单一进程里,没有标准抓取端点。解决:values 中关闭四项抓取(见第七章表格),helm upgrade 后目标消失。

9.3 自建的 ServiceMonitor 不被抓取

现象:新 ServiceMonitor apply 后 Prometheus Targets 无变化。原因:kube-prometheus-stack 默认 *SelectorNilUsesHelmValues: true,Prometheus 实例只加载带 release=<release名> 标签的监控资源。解决:第七章三个 NilUsesHelmValues: false(本次实测已配置);或给自建资源补上 release: kps 标签。CRD 字段详解见同专栏 《Prometheus Operator 0.94.1 配置与 CRD 详解》。

9.4 Operator 启动后 CR 一直 RECONCILED=False

排查顺序:kubectl logs -n <ns> deploy/<operator> 看调和错误 → kubectl get prometheus <name> -o yaml 看 status.conditions 的 message → 常见原因是 ServiceAccount 缺失或 RBAC 不足(Prometheus Pod 需要读节点/端点的权限)。

十、卸载与清理

卸载方案 A(Helm release):

helm uninstall kps -n monitoring
kubectl delete namespace monitoring

卸载方案 B(bundle):

kubectl delete -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.94.1/bundle.yaml
kubectl delete servicemonitor,podmonitor,prometheusrule,probes,scrapeconfigs,alertmanagerconfigs,prometheuses,prometheusagents,alertmanagers,thanosrulers -A --all

⚠️ 注意:bundle.yaml 不含 CRD 删除(防止误删数据),如需彻底清理再执行:

kubectl delete crd alertmanagerconfigs.monitoring.coreos.com alertmanagers.monitoring.coreos.com podmonitors.monitoring.coreos.com probes.monitoring.coreos.com prometheusagents.monitoring.coreos.com prometheuses.monitoring.coreos.com prometheusrules.monitoring.coreos.com scrapeconfigs.monitoring.coreos.com servicemonitors.monitoring.coreos.com thanosrulers.monitoring.coreos.com

验证清理干净:

kubectl get crd | grep monitoring
No resources found

十一、参考链接