Prometheus 监控 Kube-state-metrics 终极实战:Kubernetes 对象状态可观测性全解析
在 Kubernetes 集群中,cAdvisor 告诉我们容器用了多少 CPU/内存,而kube-state-metrics则回答“当前有多少个 Pod 处于 Running?多少 Deployment 不可用?节点是否就绪?Job 是否成功?”这类面向 Kubernetes 对象状态的问题。它监听 API Server,将 Deployment、Pod、Node、DaemonSet、StatefulSet、Job、CronJob、PVC 等资源的期望与当前状态转化为 Prometheus 指标,是构建 K8s 集群可观测性不可或缺的一环。本文将带你从部署、指标解读到生产告警,彻底掌握基于 kube-state-metrics 的 K8s 状态监控。
1. 为什么是 kube-state-metrics?它与 cAdvisor 有何不同?
| 工具 | 关注点 | 指标示例 |
|---|---|---|
| cAdvisor | 容器资源使用(CPU、内存、磁盘、网络) | container_cpu_usage_seconds_total |
| kube-state-metrics | K8s 对象的状态和元数据 | kube_deployment_status_replicas_available |
两者完全互补:cAdvisor 负责“用多少”,kube-state-metrics 负责“有没有、对不对”。
2. 部署 kube-state-metrics
推荐使用官方 Helm Chart 或直接 YAML 部署。
2.1 使用 Helm 部署(最简单)
helm repoaddprometheus-community https://prometheus-community.github.io/helm-charts helminstallkube-state-metrics prometheus-community/kube-state-metrics\--namespacekube-system2.2 使用 Kubernetes Deployment + Service(生产常见)
可直接从官方仓库获取最新 manifest:
kubectl apply-fhttps://github.com/kubernetes/kube-state-metrics/releases/latest/download/kube-state-metrics.yaml这会创建 Deployment、ServiceAccount、ClusterRole(需要读取集群资源)、Service(暴露端口 8080)。默认监听在:8080/metrics端点。
验证:
kubectl port-forward svc/kube-state-metrics8080:8080-nkube-systemcurlhttp://localhost:8080/metrics应看到大量以kube_开头的指标。
3. 配置 Prometheus 抓取
如果使用 Prometheus Operator,通常会通过ServiceMonitor或PodMonitor自动发现。确保 Service 带有正确的标签,例如 Helm 安装时自动配置。
手动添加静态抓取配置:
scrape_configs:-job_name:'kube-state-metrics'scrape_interval:30sstatic_configs:-targets:['kube-state-metrics.kube-system.svc.cluster.local:8080']labels:cluster:'prod-cluster'如果 Prometheus 在集群外,需通过 NodePort 或 LoadBalancer 暴露并配置 TLS 与认证。
4. 核心监控指标与 PromQL
kube-state-metrics 指标以kube_为前缀,按资源类型分组,标签包含namespace、deployment、node、pod等。
4.1 Deployment 与 StatefulSet
| 指标 | 含义 |
|---|---|
kube_deployment_status_replicas_available | 可用的副本数 |
kube_deployment_status_replicas_desired | 期望副本数 |
kube_deployment_status_replicas_updated | 已更新的副本数 |
kube_statefulset_status_replicas_ready | StatefulSet 就绪副本 |
PromQL 示例:
- Deployment 不可用(可用副本小于期望):
kube_deployment_status_replicas_available < kube_deployment_spec_replicas - 滚动更新停滞(已更新副本不等于期望,且可用副本不等于期望):
kube_deployment_status_replicas_updated != kube_deployment_spec_replicas and kube_deployment_status_replicas_available != kube_deployment_spec_replicas
4.2 Pod 状态
| 指标 | 含义 |
|---|---|
kube_pod_status_phase | Pod 当前阶段:Pending=0, Running=1, Succeeded=2, Failed=3, Unknown=4 |
kube_pod_status_ready | Pod 是否就绪(1=Ready,0=Not Ready) |
kube_pod_container_status_restarts_total | 容器重启次数 |
PromQL:
- 处于 CrashLoopBackOff 的 Pod 数量(通过重启次数和状态组合):
increase(kube_pod_container_status_restarts_total[5m]) > 0 - 非 Running 且非 Succeeded 的 Pod:
kube_pod_status_phase{phase!~"Running|Succeeded"} > 0 - 长时间未就绪的 Pod:
kube_pod_status_ready == 0 and kube_pod_status_phase == 1
4.3 Node 状态
| 指标 | 含义 |
|---|---|
kube_node_status_condition | 节点条件,condition=Ready,status=true/false/unknown |
kube_node_spec_unschedulable | 节点是否已被 cordon(不可调度) |
kube_node_status_allocatable | 可分配资源(CPU、内存) |
PromQL:
- 节点 NotReady:
kube_node_status_condition{condition="Ready",status="true"} != 1 - 节点被 cordon:
kube_node_spec_unschedulable == 1
4.4 Job 与 CronJob
| 指标 | 含义 |
|---|---|
kube_job_status_failed | Job 失败数(1=失败) |
kube_job_status_succeeded | Job 成功数 |
kube_cronjob_spec_suspend | CronJob 是否被挂起 |
告警:Job 失败
kube_job_status_failed{job_name=~".*"} > 04.5 PVC 与存储
| 指标 | 含义 |
|---|---|
kube_persistentvolumeclaim_status_phase | PVC 状态(Bound=0, Pending=1, Lost=2) |
kube_persistentvolume_status_phase | PV 状态 |
告警:未绑定的 PVC
kube_persistentvolumeclaim_status_phase{phase="Pending"} > 04.6 资源配额
| 指标 | 含义 |
|---|---|
kube_resourcequota | ResourceQuota 已用/硬限制 |
可用于容量规划。
5. Grafana 仪表盘推荐
- Kubernetes Cluster (Prometheus):Dashboard ID13332,结合 kube-state-metrics 与 cAdvisor,提供 Deployment、Pod、Node、资源配额的全面视图。
- K8s Object States:ID13824,更侧重对象状态。
- Kubernetes kube-state-metrics:ID10856,经典独立仪表板。
导入后选择数据源,并将cluster变量与集群标签绑定。
6. 告警规则实战
groups:-name:kubernetes_state_alertsrules:-alert:K8sNodeNotReadyexpr:kube_node_status_condition{condition="Ready",status="true"}!=1for:5mlabels:severity:criticalannotations:summary:"节点 {{ $labels.node }} 处于 NotReady 状态超过 5 分钟"-alert:K8sDeploymentUnavailableexpr:kube_deployment_status_replicas_available < kube_deployment_spec_replicasfor:5mlabels:severity:criticalannotations:summary:"Deployment {{ $labels.namespace }}/{{ $labels.deployment }} 可用副本不足"-alert:K8sPodCrashLoopBackOffexpr:increase(kube_pod_container_status_restarts_total[10m])>3labels:severity:warningannotations:summary:"Pod {{ $labels.namespace }}/{{ $labels.pod }} 中容器频繁重启"-alert:K8sPodNotReadyexpr:kube_pod_status_ready == 0 and kube_pod_status_phase == 1for:10mlabels:severity:warningannotations:summary:"Pod {{ $labels.namespace }}/{{ $labels.pod }} 处于 Running 但未就绪"-alert:K8sJobFailedexpr:kube_job_status_failed>0labels:severity:criticalannotations:summary:"Job {{ $labels.namespace }}/{{ $labels.job_name }} 执行失败"-alert:K8sPersistentVolumeClaimPendingexpr:kube_persistentvolumeclaim_status_phase{phase="Pending"}>0for:30mlabels:severity:warningannotations:summary:"PVC {{ $labels.namespace }}/{{ $labels.persistentvolumeclaim }} 长期处于 Pending"-alert:K8sCronJobSuspendedexpr:kube_cronjob_spec_suspend == 1labels:severity:infoannotations:summary:"CronJob {{ $labels.namespace }}/{{ $labels.cronjob }} 已被挂起"7. 进阶:多集群、安全与性能
7.1 多集群监控
每个集群内部署 kube-state-metrics,Prometheus 使用联邦模式或 Thanos/Cortex 进行聚合,通过在抓取时注入cluster标签区分集群。
7.2 指标基数控制
kube-state-metrics 会为每个 Pod、每个容器暴露指标,在大规模集群(>10k Pods)中指标数量可能爆炸。可以通过以下方式缓解:
- 使用
--metric-allowlist或--metric-denylist限制暴露的指标。 - 在 Prometheus 抓取侧使用
metric_relabel_configs丢弃不需要的标签或指标。 - 部署多个 kube-state-metrics 实例,每个负责特定资源(如单独部署一个只收集节点指标的实例)。
7.3 RBAC 与安全
kube-state-metrics 需要读取集群范围内的资源,务必使用只读的 ClusterRole,切勿授予写权限。在私有环境中,Service 端口通过内网访问即可,避免暴露到公网。
8. 总结
Kube-state-metrics 是 Kubernetes 可观测性三大基石之一(另外两个是 cAdvisor 和 kube-event)。它让集群中每一个 Deployment 的副本、每一个 Node 的健康、每一个 Job 的成败都成为可查询、可告警的时序指标。结合 Prometheus 和 Alertmanager,你可以在集群状态偏离预期时第一时间收到通知,真正做到 “GitOps 期望 vs 集群实际” 的持续校验。部署它,让你的 K8s 集群不再是黑盒,而是一张透明的资源地图。