kube-prometheus-stack —— 一条 Helm 命令拉起 Kubernetes 全栈监控(Operator + CRD + 全家桶)
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. 参考链接
- Chart 源码 / README:https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack
- Chart 升级说明:https://github.com/prometheus-community/helm-charts/blob/main/charts/kube-prometheus-stack/UPGRADE.md
- Helm 仓库:https://prometheus-community.github.io/helm-charts
- Prometheus Operator:https://github.com/prometheus-operator/prometheus-operator
- Operator API 参考:https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md
- kube-prometheus(jsonnet manifests):https://github.com/prometheus-operator/kube-prometheus
- Prometheus 官方文档:https://prometheus.io/docs/
- Alertmanager 配置:https://prometheus.io/docs/alerting/latest/configuration/
- Artifact Hub 版本清单:https://artifacthub.io/packages/helm/prometheus-community/kube-prometheus-stack