kube-prometheus-stack —— 一条 Helm 命令拉起 Kubernetes 全栈监控(Operator + CRD + 全家桶)

运维监控软件手册 06-容器与云原生监控 23.4 KB 原文

kube-prometheus-stack —— 一条 Helm 命令拉起 Kubernetes 全栈监控(Operator + CRD + 全家桶)

分类:06 容器与云原生监控 适用:Kubernetes 集群(自建 / 托管 ACK、TKE、CCE、EKS),单集群到数百节点,指标 + 告警 + Dashboard 一体化 一句话:以 Prometheus Operator 为核心、用 CRD 声明式管理抓取与告警规则的 Kubernetes 监控发行版 官方:https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack 授权:Apache-2.0(Chart / Operator / Prometheus / Alertmanager / Grafana 核心均为宽松开源协议);免费,成本为自承载算力与存储

1. 它解决什么问题

原生 Prometheus 靠静态 prometheus.yml 配 scrape_configs,K8s 里每上线服务都要改配置、reload,告警规则与路由散落难以 GitOps 化。本方案解决集群监控的声明式交付:

  • 一条命令装好 Operator + Prometheus + Alertmanager + Grafana + node-exporter + kube-state-metrics + 预置 Dashboard/规则,开箱覆盖节点、kubelet、API Server、etcd、CoreDNS 等控制面。
  • 用 CRD 代替配置文件:ServiceMonitor 声明"抓谁"、PrometheusRule 声明"何时告警"、AlertmanagerConfig 声明"发给谁",Operator 翻译并热加载;业务方只在自己命名空间提交带标签的 CRD 即可接入;自带 kubernetes-mixin 成熟规则(如 KubePodCrashLooping)。不适合非 K8s 环境、极轻量单机采集、拒绝 CRD/Operator 的场景。

2. 核心概念与架构

2.1 术语表

术语 含义
Prometheus Operator Watch CRD 变化、生成并管理 Prometheus StatefulSet 与配置的控制器(单副本控制面)
CRD monitoring.coreos.com API 组下的自定义资源,用户唯一需编写的接口
Prometheus / Alertmanager 声明实例:副本、存储、保留期、各类 selector
ServiceMonitor 按 Service + label selector 发现后端 Pod 生成 scrape job(最常用)
PodMonitor / Probe / ScrapeConfig 直接按 Pod / blackbox 探测 / 任意外部目标抓取
PrometheusRule / AlertmanagerConfig 告警与 recording 规则 / 命名空间级路由树与 receiver(v1alpha1)
kube-state-metrics / node-exporter K8s 对象状态指标 / 每节点主机指标(DaemonSet)
release 标签 / 高基数 Chart 默认给 CRD 打 release: <HELM_RELEASE>;pod、uid 类标签会致 series 爆炸

2.2 组件与数据流

 提交CRD: ServiceMonitor / PodMonitor / PrometheusRule / AlertmanagerConfig
      │ watch(monitoring.coreos.com)          │
      ▼                                      ▼
 ┌───────────────────┐ 生成配置+reload ┌──────────────────────┐ alarms ┌────────────┐
 │Prometheus Operator│────────────────▶│Prometheus(StatefulSet)│───────▶│Alertmanager│──▶邮件/企微/钉钉/Slack/Webhook
 └───────────────────┘                │按selector汇集CRD/评估Rule│      │分组/抑制/静默│
 pull /metrics(HTTP) ┌──────────────┐  │K8s SD发现Endpoint/TSDB │      └────────────┘
 │node-exp(9100)│kube-state-met(8080)│业务Pod/metrics│◀└──────────────────────┘  PromQL ─▶ Grafana(3000)

CRD → 自动发现 → 告警 链路:① 提交 ServiceMonitor → ② Prometheus.spec.serviceMonitorSelector(默认只认 release: <名字>)选中它,未选中即静默失效(头号故障)→ ③ Operator 渲染为 scrape_configs(kubernetes_sd_configs + relabel)写入 Secret 并 reload → ④ Prometheus 经 K8s API 发现 Endpoints,按 port/path/interval 拉取 → ⑤ PrometheusRule 被 ruleSelector 选中后求值,告警推给 Alertmanager → ⑥ Alertmanager 按 alertmanagerConfigSelector 合并各命名空间 AlertmanagerConfig,沿 route 树匹配 receiver 发通知。

⚠️ Operator 不支持 prometheus.io/scrape 注解发现,必须用 ServiceMonitor/PodMonitor(官方 README 明确)。

3. 安装与部署

3.1 环境准备

项 要求
Kubernetes README 标注 1.19+;较新 Chart 的 kubeVersion 可能要求更高(如 1.25+)——以官方最新稳定版为准
Helm / 权限 3+(Helm 2 不支持 OCI 与 CRD 语义);可创建 CRD、ClusterRole/Binding、Namespace 的集群管理员
资源 / 存储 最低 2C4G 可跑通;生产建议 Prometheus 2C4G + SSD PV;默认 emptyDir 重启丢数据
网络 Pod 互通、目标端口可达;托管集群常不暴露 etcd/API Server 指标,需确认
kubectl version --short; helm version --short
kubectl auth can-i create customresourcedefinitions.apiextensions.k8s.io
kubectl get storageclass

3.2 多种安装方式

A. Helm 官方仓库(推荐)/ B. OCI Artifact / C. 原生 manifests / D. GitOps

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts && helm repo update
helm install kps prometheus-community/kube-prometheus-stack -n monitoring --create-namespace -f values.yaml --wait --timeout 10m
# OCI:helm install kps oci://ghcr.io/prometheus-community/charts/kube-prometheus-stack -n monitoring --create-namespace
helm show values prometheus-community/kube-prometheus-stack > values-default.yaml
# manifests:git clone https://github.com/prometheus-operator/kube-prometheus && cd kube-prometheus
#   kubectl apply --server-side -f manifests/setup && kubectl wait --for condition=Established --timeout=120s crd/prometheuses.monitoring.coreos.com && kubectl apply -f manifests/

D. GitOps:Argo CD Application.source 指向 Helm 仓库 chart: kube-prometheus-stack、targetRevision: <CHART_VERSION>(以官方最新稳定版为准)、syncOptions: [ServerSideApply=true];Flux 用 HelmRelease 等效。默认依赖子 chart:kube-state-metrics、prometheus-node-exporter、grafana,可 --set <name>.enabled=false 关闭。

3.3 首次启动与验证

kubectl get crd | grep monitoring.coreos.com                        # 应见 10 个 CRD
kubectl -n monitoring get pods,statefulset,prometheus,alertmanager
kubectl -n monitoring logs deploy/kps-kube-prometheus-operator --tail=100
kubectl -n monitoring port-forward svc/kps-kube-prometheus-prometheus 9090:9090 &
kubectl -n monitoring port-forward svc/kps-grafana 3000:80 &
curl -s http://127.0.0.1:9090/-/healthy ; curl -s http://127.0.0.1:9090/api/v1/targets | jq '.data.activeTargets|length'

Grafana 默认账号 admin,密码由 grafana.adminPassword 决定(Chart 默认 prom-operator,⚠️ 首次登录必改):kubectl -n monitoring get secret kps-grafana -o jsonpath='{.data.admin-password}' | base64 -d。

4. 配置文件详解

4.1 values.yaml / 告警规则关键项

配置路径 作用 建议
prometheus.prometheusSpec.retention / retentionSize TSDB 保留时长 / 容量上限 15d / 40GB
prometheus.prometheusSpec.storageSpec.volumeClaimTemplate 持久化 PV 生产必配
prometheus.prometheusSpec.replicas / shards / walCompression HA 副本 / 分片 / WAL 压缩 2 / 按需 / true
...serviceMonitorSelectorNilUsesHelmValues 为 false 才允许无 release 标签的 SM 被选中 false
...ruleSelectorNilUsesHelmValues / podMonitorSelectorNilUsesHelmValues 同上,作用于 Rule / PodMonitor false
prometheus.prometheusSpec.serviceMonitorSelector / ruleSelector 显式选择器,{} 匹配全部 {}
alertmanager.alertmanagerSpec.replicas / alertmanagerConfigSelector 副本 / 路由选择器 3 / {}
alertmanager.config / grafana.adminPassword 全局路由(§6) / 管理员密码 按需 / 强密码

4.2 完整可运行最小 values.yaml

# values.yaml —— 生产最小基线
prometheus:
  prometheusSpec:
    replicas: 2
    retention: 15d
    retentionSize: 40GB
    walCompression: true
    serviceMonitorSelectorNilUsesHelmValues: false   # 关键:放行无 release 标签的 CRD
    podMonitorSelectorNilUsesHelmValues: false
    ruleSelectorNilUsesHelmValues: false
    probeSelectorNilUsesHelmValues: false
    scrapeConfigSelectorNilUsesHelmValues: false
    serviceMonitorSelector: {}          # 空选择器 = 所有命名空间全部 ServiceMonitor
    ruleSelector: {}
    resources: {requests: {cpu: 500m, memory: 2Gi}, limits: {cpu: "2", memory: 6Gi}}
    storageSpec:
      volumeClaimTemplate:
        spec: {storageClassName: <STORAGE_CLASS>, accessModes: ["ReadWriteOnce"],
               resources: {requests: {storage: 100Gi}}}
alertmanager:
  alertmanagerSpec: {replicas: 3, alertmanagerConfigSelectorNilUsesHelmValues: false, alertmanagerConfigSelector: {}}
grafana:
  adminPassword: <STRONG_PASSWORD>      # ⚠️ 禁止沿用默认 prom-operator
  sidecar: {dashboards: {enabled: true, label: grafana_dashboard, labelValue: "1"}}
defaultRules: {create: true}
helm upgrade --install kps prometheus-community/kube-prometheus-stack -n monitoring --create-namespace -f values.yaml --wait

4.3 告警规则配置(PrometheusRule 完整 YAML)

# alert-rules.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: app-rules
  namespace: <APP_NAMESPACE>
  labels: {release: kps}               # 若 ruleSelector 非 {} 则必带
spec:
  groups:
    - name: app.rules
      interval: 30s
      rules:
        - record: app:request_rate5m
          expr: sum by (service) (rate(http_requests_total[5m]))
        - alert: AppHighErrorRate
          expr: sum by(service)(rate(http_requests_total{status=~"5.."}[5m])) / sum by(service)(rate(http_requests_total[5m])) > 0.05
          for: 10m
          labels: {severity: critical, team: <TEAM>}
          annotations: {summary: "{{ $labels.service }} 5xx 错误率超过 5%", runbook_url: "https://<INTERNAL_WIKI>/runbook/app-5xx"}

5. 核心使用方法

5.1 helm / kubectl 常用命令(20 条)

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts  # 1
helm repo update                                                                        # 2
helm show values prometheus-community/kube-prometheus-stack > values.yaml                # 3
helm template kps prometheus-community/kube-prometheus-stack -f values.yaml > render.yaml # 4
helm install kps prometheus-community/kube-prometheus-stack -n monitoring -f values.yaml --wait # 5
helm upgrade kps prometheus-community/kube-prometheus-stack -n monitoring -f values.yaml      # 6
helm list -n monitoring ; helm history kps -n monitoring                                 # 7
helm rollback kps <REVISION> -n monitoring                                              # 8
helm uninstall kps -n monitoring                                                        # 9(CRD 不删)
kubectl get crd | grep monitoring.coreos.com                                            # 10
kubectl api-resources --api-group=monitoring.coreos.com                                # 11
kubectl get prometheus,servicemonitor,podmonitor,prometheusrule,alertmanagerconfig -A  # 12
kubectl describe servicemonitor <NAME> -n <NS>                                         # 13
kubectl get prometheus -n monitoring -o jsonpath='{.items[0].spec.serviceMonitorSelector}' # 14
kubectl -n monitoring get secret prometheus-kps -o jsonpath='{.data.prometheus\.yaml.gz}' | base64 -d | gzip -d | grep -A12 'job_name: .*myapp' # 15(导出真实生成配置)
kubectl -n monitoring logs deploy/kps-kube-prometheus-operator --tail=200               # 16
kubectl -n monitoring rollout restart statefulset/prometheus-kps-kube-prometheus-prometheus # 17
kubectl -n monitoring top pod ; kubectl -n monitoring get events --sort-by=.lastTimestamp | tail -20 # 18
kubectl apply -f app-servicemonitor.yaml -f alert-rules.yaml                           # 19
kubectl delete -f app-servicemonitor.yaml                                              # 20(回滚接入)

5.2 接入业务 /metrics 的完整 YAML(ServiceMonitor)

# app-servicemonitor.yaml —— 业务方只需提交这一份
apiVersion: v1
kind: Service
metadata:
  name: myapp
  namespace: <APP_NAMESPACE>
  labels: {app: myapp}
spec:
  selector: {app: myapp}
  ports: [{name: metrics, port: 8080, targetPort: 8080}]   # ⚠️ 端口必须命名
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: myapp
  namespace: <APP_NAMESPACE>
  labels: {release: kps}                 # 与 Prometheus 的 serviceMonitorSelector 对齐
spec:
  namespaceSelector: {matchNames: ["<APP_NAMESPACE>"]}
  selector: {matchLabels: {app: myapp}} # 匹配的是 Service 标签,不是 Pod 标签
  endpoints:
    - port: metrics
      path: /metrics
      interval: 30s
      scrapeTimeout: 10s
      relabelings: [{sourceLabels: [__meta_kubernetes_namespace], targetLabel: namespace}]
kubectl apply -f app-servicemonitor.yaml
curl -s --data-urlencode 'query=up{job="myapp"}' http://127.0.0.1:9090/api/v1/query | jq '.data.result'

5.3 AlertmanagerConfig 完整 YAML

# app-alertmanagerconfig.yaml
apiVersion: monitoring.coreos.com/v1alpha1
kind: AlertmanagerConfig
metadata:
  name: app-routing
  namespace: <APP_NAMESPACE>
  labels: {alertmanagerConfig: kps}      # 需与 alertmanagerConfigSelector 对齐
spec:
  route:
    receiver: default
    groupBy: [alertname, namespace]
    groupWait: 30s
    repeatInterval: 4h
    routes: [{matchers: [{name: severity, value: critical}], receiver: oncall-webhook}]
  receivers:
    - name: default
      slackConfigs: [{apiURL: "https://hooks.slack.com/services/<SLACK_WEBHOOK>", channel: "#monitor", sendResolved: true}]
    - name: oncall-webhook
      webhookConfigs: [{url: "https://<WEBHOOK_HOST>/alert", sendResolved: true}]
  inhibitRules:
    - {sourceMatchers: [{name: severity, value: critical}], targetMatchers: [{name: severity, value: warning}], equal: [alertname, namespace]}

AlertmanagerConfig 为 v1alpha1,字段随 Operator 版本变化,以官方最新稳定版 API 文档为准。

5.4 PromQL / HTTP API

P=http://127.0.0.1:9090/api/v1
curl -s --data-urlencode 'query=100-(avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m]))*100)' $P/query | jq
curl -s --data-urlencode 'query=count by(namespace)(kube_pod_status_phase{phase!="Running"}==1)' $P/query | jq
curl -s --data-urlencode 'query=up == 0' $P/query | jq ; curl -s $P/alerts | jq '.data.alerts[].labels.alertname'
curl -s $P/status/tsdb | jq '.data' ; curl -X POST http://127.0.0.1:9090/-/reload

6. 告警与通知

规则层用 PrometheusRule(expr + for 抑制抖动);路由层用 alertmanager.config(全局)或 AlertmanagerConfig(分命名空间)。官方 receiver 支持 email_configs、wechat_configs(企业微信)、webhook_configs(钉钉/Serverless 回调)、slack_configs、pagerduty_configs 等。

# values.yaml → alertmanager.config 片段
alertmanager:
  config:
    global: {resolve_timeout: 5m}
    route:
      group_by: [alertname, namespace]
      group_wait: 30s
      repeat_interval: 12h
      receiver: default
      routes: [{matchers: [severity = "critical"], receiver: oncall}]
    receivers:
      - name: default
        email_configs: [{to: <MAIL_TO>, from: <MAIL_FROM>, smarthost: "<SMTP_HOST>:587",
                         auth_username: <SMTP_USER>, auth_password: <SMTP_PASS>, send_resolved: true}]
        wechat_configs: [{corp_id: <CORP_ID>, api_secret: <WECHAT_SECRET>, to_user: "<USER>", agent_id: <AGENT_ID>}]
      - name: oncall
        slack_configs: [{api_url: "https://hooks.slack.com/services/<SLACK_WEBHOOK>", channel: "#oncall"}]
        webhook_configs: [{url: "https://oapi.dingtalk.com/robot/send?access_token=<DING_TOKEN>", send_resolved: true}]

降噪/升级:for 持续期、group_by 聚合、repeat_interval 控重复、inhibit_rules 高等级抑制低等级、按 severity 分级路由;升级用多条 route 配不同 receiver 与 repeat_interval,或 Webhook 接 On-call/函数回调。

curl -s -X POST http://127.0.0.1:9093/api/v2/silences -H 'Content-Type: application/json' \
  -d '{"matchers":[{"name":"alertname","value":"KubePodCrashLooping","isRegex":false}],"startsAt":"<RFC3339_START>","endsAt":"<RFC3339_END>","createdBy":"ops","comment":"发布窗口"}' | jq
curl -s http://127.0.0.1:9093/api/v2/silences | jq '.[]|{id,status,comment}'
curl -s -X DELETE http://127.0.0.1:9093/api/v2/silence/<SILENCE_ID>   # ⚠️ 提前解除静默

7. 实战场景

场景 A:给新部署的业务暴露 /metrics 并接入

目标:命名空间 <APP_NAMESPACE> 的 myapp 被自动抓取并出图告警。

kubectl -n <APP_NAMESPACE> create deployment myapp --image=<APP_IMAGE>
kubectl -n <APP_NAMESPACE> expose deployment myapp --port=8080 --name=myapp
kubectl -n <APP_NAMESPACE> patch svc myapp -p '{"spec":{"ports":[{"name":"metrics","port":8080,"targetPort":8080}]}}'
kubectl -n <APP_NAMESPACE> port-forward deploy/myapp 8080:8080 &     # 先自证 /metrics 可用
curl -s http://127.0.0.1:8080/metrics | head -20
kubectl apply -f app-servicemonitor.yaml -f alert-rules.yaml           # §5.2 / §4.3

验证:curl -s --data-urlencode 'query=up{job="myapp"}' http://127.0.0.1:9090/api/v1/query | jq;Targets 页 UP;Grafana Explore 查 app:request_rate5m。回滚:kubectl delete -f app-servicemonitor.yaml -f alert-rules.yaml,目标自动移除,无需重启。

场景 B:ServiceMonitor 不生效排障

目标:恢复 myapp 抓取。按 §8.2 排查链逐层执行:

kubectl -n <APP_NS> get servicemonitor myapp -o yaml | yq '.spec'
kubectl -n <APP_NS> get svc -l app=myapp -o wide ; kubectl -n <APP_NS> get endpoints myapp
kubectl -n monitoring get prometheus -o jsonpath='{.items[0].spec.serviceMonitorSelector}{"\n"}{.items[0].spec.serviceMonitorNamespaceSelector}'
kubectl -n monitoring get secret prometheus-kps -o jsonpath='{.data.prometheus\.yaml.gz}' | base64 -d | gzip -d | grep -A12 'job_name: .*myapp'
kubectl -n monitoring logs deploy/kps-kube-prometheus-operator | grep -iE 'error|failed to select'

验证:生成配置出现 job 且 Targets 页 UP。回滚:kubectl delete -f app-servicemonitor.yaml 回到未接入状态。

场景 C:扩容 + 持久化 + Thanos 长期存储

目标:保留 15d/100Gi、双副本 HA,并接 Thanos 上传对象存储。配置:在 §4.2 values.yaml 追加 prometheus.prometheusSpec.externalLabels.cluster=<CLUSTER_NAME> 与 thanos.objectStorageConfig: {key: thanos.yaml, name: thanos-objstore-config}、thanos.image(版本以官方最新稳定版为准),Secret 内存对象存储凭据。

kubectl -n monitoring create secret generic thanos-objstore-config --from-file=thanos.yaml=./thanos.yaml
helm upgrade kps prometheus-community/kube-prometheus-stack -n monitoring -f values.yaml --wait
kubectl -n monitoring get pvc -l app.kubernetes.io/name=prometheus
curl -s http://127.0.0.1:9090/api/v1/status/tsdb | jq '.data'

验证:PVC 绑定、TSDB 状态正常。回滚:helm rollback kps <PREV_REVISION> -n monitoring;⚠️ 去掉 thanos 段后对象存储历史块需由 Thanos Store 单独查询,不要删 PVC。

8. 日常运维与故障排查

8.1 服务管理、日志与健康检查

kubectl -n monitoring get pods -o wide
kubectl -n monitoring logs deploy/kps-kube-prometheus-operator --tail=200 -f
kubectl -n monitoring logs statefulset/prometheus-kps-kube-prometheus-prometheus --tail=200 -f
kubectl -n monitoring logs statefulset/alertmanager-kps-kube-prometheus-alertmanager --tail=200 -f
curl -s http://127.0.0.1:9090/-/ready ; curl -s http://127.0.0.1:9093/-/healthy

日志路径:统一通过 kubectl logs 获取(容器无独立日志文件,Agent 侧无落盘日志);健康端点 /-/healthy、/-/ready;服务管理用 kubectl -n monitoring rollout restart/scale 与 helm upgrade/rollback。

8.2 ServiceMonitor 不生效排查链(重点)

从数据面到控制面逐层排除,不要一上来重启 Operator:① kubectl port-forward + curl /metrics 确认应用自身有数据 → ② kubectl get endpoints <SVC> 判 Service selector 是否匹配 Pod → ③ kubectl get svc -o yaml 确认端口已命名且与 endpoints.port 一致 → ④ SM 的 selector.matchLabels 匹配的是 Service 标签而非 Pod 标签 → ⑤ namespaceSelector 跨命名空间必须显式 matchNames → ⑥ 查 Prometheus.spec.serviceMonitorSelector,默认只选 release: <HELM_RELEASE>,业务 SM 漏打即静默失效(最高频)→ ⑦ 看 Operator 日志是否报 CRD 校验/failed to select → ⑧ 解压 prometheus.yaml.gz grep job_name 确认生成 → ⑨ Targets 页看 DOWN 原因(refused / deadline / 403 RBAC)→ ⑩ 检查 relabelings 的 keep/drop 是否过滤掉目标。修法:补 release: kps 标签,或设 ...NilUsesHelmValues: false + serviceMonitorSelector: {}(§4.2)。

8.3 故障「现象 → 原因 → 处置」表

现象 原因 处置
Targets 无业务 job serviceMonitorSelector 未选中(缺 release) 补标签或放宽选择器,见 §8.2 ⑥
DOWN connection refused 端口名/targetPort 写错或应用未监听 修 endpoints.port 与 Service 端口名
规则不出现在 /api/v1/rules ruleSelector 未选中或语法错 看 Operator 日志,用 promtool check rules 预校验
告警触发但无通知 alertmanagerConfigSelector 未选中 / receiver 错 / 静默生效 kubectl get alertmanagerconfig -A,查 Silence 与 Webhook 连通性
Grafana 无数据 数据源 URL 错或 sidecar 未装载 检查 grafana.datasources 与 sidecar.datasources.enabled
Prometheus 反复 OOMKilled 高基数标签 / 规模超内存 降 cardinality、设 retentionSize、加内存或 shards
helm upgrade 后 CRD 字段报错 Helm v3 不自动升级 CRD 手动 kubectl apply --server-side -f <CRD_URL>

9. 性能、容量与高可用

维度 建议
规模估算 用 prometheus_tsdb_head_series 监控;按活跃 series 数估内存
资源 / PDB resources 必配;为 Prometheus/Alertmanager 设 PodDisruptionBudget
保留 / 降采样 本地 ≤15d;长期用 recording rules 预聚合或 Thanos 降采样
HA / 分片 replicas: 2 双份数据;超大规模用 shards 分片
成本 算力 + PV + 对象存储;主要风险是"无意采高基数指标"致资源与账单双涨;用 metricRelabelings 与增大 scrape_interval 调优
curl -s --data-urlencode 'query=prometheus_tsdb_head_series' http://127.0.0.1:9090/api/v1/query | jq

10. 安全加固、备份与升级

  • RBAC 最小权限:业务方只授本命名空间 servicemonitors/prometheusrules 的 create/update;集群级 CRD 与 ClusterRole 平台团队独占,不放大 Operator 自带权限。
  • 密钥:Grafana 密码、SMTP/Slack/Webhook token 用 Secret 注入,禁止明文进 values.yaml 提交 Git(External Secrets / Sealed Secrets)。
  • TLS / 网络:prometheusOperator.admissionWebhooks.certManager.enabled 由 cert-manager 签发 webhook 证书;NetworkPolicy 限只有 Prometheus 能访问业务 /metrics;Ingress 强制 HTTPS。
  • 配置即代码:values.yaml + 全部 CRD 清单入库,Argo CD/Flux 用 ServerSideApply=true 同步(§3.2 D)。
  • 备份:Git 仓库 + kubectl get ... -o yaml 导出 CRD;TSDB 用 remoteWrite/Thanos 到对象存储,⚠️ 不要把 PV 快照当唯一备份。

升级顺序:① helm get values kps -n monitoring > values-live.yaml 备份 → ② ⚠️ Helm v3 不自动更新 CRD,先手动 kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/<OPERATOR_VERSION>/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml 及其余 CRD(版本取目标 Chart 的 appVersion,以官方最新稳定版为准)→ ③ 阅读 UPGRADE.md breaking changes → ④ helm upgrade ... --wait → ⑤ 失败 helm rollback kps <PREV_REVISION> -n monitoring。⚠️ helm uninstall 不删 CRD,重装前确认旧 CRD 兼容;必要时 kubectl delete crd <...> 会连带删除所有业务 CRD 实例,务必先备份。

11. 常见坑

# 现象 原因 解决
1 自建 SM 完全无 job 默认选择器只认 release: <HELM_RELEASE> 补标签或 ...NilUsesHelmValues: false + selector: {}
2 跨命名空间抓不到 namespaceSelector 缺省只匹配自身 NS 显式 matchNames
3 端口匿名致 job 丢失 endpoints.port 引用端口名 Service port 加 name: metrics
4 用注解 prometheus.io/scrape 无效 Operator 不支持注解发现 改 ServiceMonitor/PodMonitor
5 升级后规则全消失 Helm v3 不更新 CRD 手动 --server-side 升级 CRD
6 卸载重装后规则重复报错 ⚠️ helm uninstall 保留 CRD 与实例 备份后清理残留或保持幂等 GitOps
7 抓 kubelet 401/403 托管集群禁用只读端口 / RBAC 不全 用官方 kubelet ServiceMonitor 配置
8 内存暴涨 OOM pod/container_id/user_id 高基数 metricRelabelings drop + limit
9 Grafana 默认密码暴露公网 ⚠️ 沿用 prom-operator 强制 grafana.adminPassword + Ingress 认证

12. 速查表

项 值 / 命令
官方仓库 https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack
Helm 仓库 https://prometheus-community.github.io/helm-charts
OCI 制品 oci://ghcr.io/prometheus-community/charts/kube-prometheus-stack
Operator / kube-prometheus 仓库 github.com/prometheus-operator/prometheus-operator · /kube-prometheus
API 组 monitoring.coreos.com
核心 CRD prometheuses / alertmanagers / servicemonitors / podmonitors / probes / prometheusrules / alertmanagerconfigs / scrapeconfigs / thanosrulers / prometheusagents
列出 CRD kubectl api-resources --api-group=monitoring.coreos.com
Prometheus 端口 9090(svc/<RELEASE>-kube-prometheus-prometheus)
Alertmanager 端口 9093
Grafana 端口 Service 80 → 容器 3000
node-exporter / kube-state-metrics 9100 / 8080
Grafana 默认账号 admin / grafana.adminPassword(默认 prom-operator,必改)
生成配置 Secret prometheus-<RELEASE> → prometheus.yaml.gz
控制台入口 Prometheus UI / Alertmanager UI / Grafana(port-forward 或 Ingress)
常用 PromQL up、rate(...[5m])、kube_pod_status_phase、node_cpu_seconds_total

13. 选型建议与同类对比

维度 kube-prometheus-stack(自建) 商业 SaaS(如 Datadog) 云托管 Prometheus
部署运维 自管 Operator/CRD/升级/容量 免运维,装 Agent 即可 免管控制面,仍需配采集
数据主权 数据全在自有集群,最可控 ⚠️ 数据出境到 SaaS,需评估合规 数据在云账号内,同地域
成本模型 算力 + 存储 + 人力,大规模边际成本低 按主机/容器/日志量/自定义指标计费,规模大时昂贵 按 series/写入量/存储计费
功能广度 指标 + 告警 + Grafana(日志/APM 另接) 指标/日志/APM/RUM/安全一体 指标 + 云产品监控,深度绑定自家云
定制能力 最高(CRD + PromQL + 任意 exporter) 中(受平台约束) 中(兼容 PromQL 但受托管限制)
信创/国产化 可控,易适配国产 K8s 发行版 需确认境内节点与合规资质 主流云厂商有信创/政务云形态

选它:已有 K8s 平台团队、要求数据不出域、需深度定制与 GitOps、希望长期摊薄成本、多云/混合云统一监控。不选:无 K8s 运维能力的小团队、只需云产品基础告警、日志/APM 为一等需求且不想自建多套系统。常见混用:控制面与应用指标用自建 stack,云产品(RDS/SLB/OSS)指标与账单告警用云监控,告警在统一 Webhook/On-call 平台汇聚。

14. 参考链接

kube-prometheus-stack —— 一条 Helm 命令拉起 Kubernetes 全栈监控(Operator + CRD + 全家桶) - 知识库 - 起航社区