title: K8s 系列 | 第 22 天:监控体系搭建:Prometheus + Grafana + Kube-state-metrics
date: 2026-07-08 08:00:00
tags:
– Kubernetes
– K8s系列
– DevOps
– 监控
– Prometheus
– Grafana
– 可观测性
第 22/30 天
引言
生产环境中的 Kubernetes 集群就像一座精密的”城市”——成千上万的 Pod 在其中穿梭运行,Control Plane 负责调度决策,etcd 保存着集群的每一笔”账目”。没有监控体系,运维人员就像在黑暗中驾驶飞机。本文将带你从零搭建一套完整的 K8s 监控栈:Prometheus(指标采集与存储)+ Grafana(可视化面板)+ kube-state-metrics(集群状态指标),并分享生产环境中的最佳实践与踩坑经验。
核心概念
Prometheus 架构
Prometheus 采用拉(Pull)模式采集指标,核心组件包括:
| 组件 | 作用 |
|---|---|
| Prometheus Server | 核心服务,负责指标抓取、存储与查询 |
| Exporters | 暴露指标的代理层(如 node_exporter, kube-state-metrics) |
| Alertmanager | 告警路由与通知分发 |
| Pushgateway | 批处理任务的指标推送入口(Pull 模式的补充) |
Grafana 的角色
Grafana 是可视化层,从 Prometheus 等数据源读取指标,渲染为仪表盘(Dashboard)。它不存储数据,只查询和展示。
kube-state-metrics 的特殊地位
kube-state-metrics(KSM)监听 Kubernetes API Server,生成集群对象(Deployment、Pod、Node、Service 等)的状态指标。与 node_exporter 收集的节点级指标不同,KSM 回答的是”Desired State vs Actual State”的问题——比如「预期的副本数是 3,实际运行的是 2」。
实战步骤
1. 部署 Prometheus Stack
推荐使用 Prometheus Operator 或 kube-prometheus-stack Helm Chart 进行部署,它们提供了完整的一站式解决方案。
# 添加 Prometheus 社区 Helm 仓库
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
# 创建 monitoring 命名空间
kubectl create namespace monitoring
# 安装 kube-prometheus-stack(包含 Prometheus、Grafana、Alertmanager)
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack
--namespace monitoring
--set grafana.service.type=NodePort
--set grafana.adminPassword=admin123
--set prometheus.prometheusSpec.replicas=2
--set prometheus.prometheusSpec.retention=15d
2. 验证组件运行状态
# 查看所有部署的资源
kubectl get pods -n monitoring
kubectl get svc -n monitoring
# 访问 Prometheus Web UI(端口转发)
kubectl port-forward -n monitoring svc/kube-prometheus-stack-prometheus 9090:9090 &
# 访问 Grafana(端口转发)
kubectl port-forward -n monitoring svc/kube-prometheus-stack-grafana 8080:80 &
打开浏览器访问 http://localhost:9090 进入 Prometheus,执行 up{} 查询,返回值为 1 表示目标存活。
3. 部署 kube-state-metrics
kube-prometheus-stack 默认已包含 KSM,但我们可以独立部署以深入理解其机制:
# kube-state-metrics-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: kube-state-metrics
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
app: kube-state-metrics
template:
metadata:
labels:
app: kube-state-metrics
spec:
serviceAccountName: kube-state-metrics
containers:
- name: kube-state-metrics
image: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.12.0
ports:
- containerPort: 8080
name: http-metrics
args:
- --resources=deployments,pods,nodes,services,namespaces,persistentvolumes,persistentvolumeclaims
- --metric-labels-allowlist=pods=[*],deployments=[*]
---
apiVersion: v1
kind: Service
metadata:
labels:
app: kube-state-metrics
name: kube-state-metrics
namespace: monitoring
spec:
selector:
app: kube-state-metrics
ports:
- name: http-metrics
port: 8080
targetPort: 8080
# 应用 KSM 配置
kubectl apply -f kube-state-metrics-deployment.yaml
4. 配置 Prometheus 抓取 KSM 指标
kube-prometheus-stack 通过 ServiceMonitor 自动发现目标。检查默认的 ServiceMonitor 是否已包含 KSM:
kubectl get servicemonitor -n monitoring
kubectl describe servicemonitor -n monitoring kube-prometheus-stack-kube-state-metrics
如果自定义部署了独立的 KSM,需要手动创建 ServiceMonitor:
# ksm-servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: kube-state-metrics-monitor
namespace: monitoring
labels:
release: kube-prometheus-stack
spec:
selector:
matchLabels:
app: kube-state-metrics
endpoints:
- port: http-metrics
interval: 30s
namespaceSelector:
matchNames:
- monitoring
kubectl apply -f ksm-servicemonitor.yaml
5. 配置 Grafana 仪表盘
Grafana 提供了丰富的社区仪表盘,可以直接导入使用:
| 仪表盘名称 | ID | 描述 |
|---|---|---|
| Kubernetes Cluster Monitoring | 315 | 集群总览:节点、Pod、资源使用率 |
| Kubernetes Pod Resources | 6411 | Pod 级别的 CPU/内存监控 |
| Kube State Metrics | 13332 | KSM 指标可视化面板 |
| Node Exporter Full | 1860 | 节点级系统指标 |
# 通过 Grafana API 导入仪表盘(315 - 集群监控)
curl -X POST
-H "Authorization: Bearer $(curl -s -X POST
-H "Content-Type: application/json"
-d '{"user":"admin","password":"admin123"}'
http://localhost:8080/api/login | jq -r '.accessToken')"
-H "Content-Type: application/json"
-d '{"dashboard":{"id":null,"uid":null,"title":"Kubernetes Cluster Monitoring"},"overwrite":true,"inputs":[{"name":"DS_PROMETHEUS","type":"datasource","pluginId":"prometheus","value":"Prometheus"}]}'
http://localhost:8080/api/dashboards/import
6. 核心 PromQL 查询示例
# 1. 集群中所有节点的 CPU 使用率
(1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])))
# 2. 命名空间中运行的 Pod 数量(按状态分组)
count(kube_pod_status_phase{phase="Running"}) by (namespace)
# 3. Deployment 期望副本 vs 可用副本
kube_deployment_spec_replicas{}
- on (namespace, deployment) kube_deployment_status_replicas_available{}
# 4. 节点内存使用率
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
# 5. 集群中异常 Pod(非 Running/Ready 状态)
kube_pod_status_phase{phase!="Running"}
常见问题
Q1:Prometheus 磁盘空间暴涨怎么办?
原因:metrics 留存时间过长或高基数指标(如 Pod 标签过多)导致。
解决:
# 在 Helm values 中调整存储配置
prometheus:
prometheusSpec:
retention: 7d # 缩短留存时间
retentionSize: 50GB # 设置存储上限,超限自动清理
storageSpec:
volumeClaimTemplate:
spec:
storageClassName: fast-storage
resources:
requests:
storage: 100Gi
Q2:Grafana 仪表盘显示 No data
排查步骤:
1. 确认 Prometheus Target 状态:http://prometheus:9090/targets
2. 检查 ServiceMonitor 标签选择器与 Prometheus serviceMonitorSelector 是否匹配
3. 手动在 Prometheus 执行 up{job="kube-state-metrics"} 验证数据是否存在
4. 确认 Grafana 数据源连接正确
Q3:kube-state-metrics 导致 API Server 负载过高
原因:KSM 频繁请求 API Server 获取集群状态。
优化方案:
# 限制 KSM 监控的资源类型,避免不必要的 API 请求
--resources=deployments,pods,nodes # 只监控需要的资源
# 降低采集频率
# 在 ServiceMonitor 中设置 interval: 60s 而非默认 30s
总结
本文搭建了一套完整的 K8s 监控体系:
- Prometheus 作为指标存储与查询引擎
- kube-state-metrics 提供集群对象状态指标
- Grafana 实现可视化仪表盘
- PromQL 提供灵活的指标查询能力
生产环境中,建议额外补充:
– node_exporter:节点级系统指标(CPU、内存、磁盘、网络)
– Alertmanager:配置告警规则(Pod CrashLoopBackOff、Node NotReady、磁盘使用率 > 85%)
– Thanos / VictoriaMetrics:多集群统一存储与长期归档
📋 系列目录
| 阶段 | 天数 | 状态 |
|---|---|---|
| 第 1 周:K8s 基础入门 | 第 1-7 天 | ✅ 已发布 |
| 第 2 周:K8s 存储与网络 | 第 8-14 天 | ✅ 已发布 |
| 第 3 周:K8s 进阶调度与资源管理 | 第 15-21 天 | ✅ 已发布 |
| 第 4 周:K8s 生产环境运维 | 第 22 天 | 🔵 今日发布 |
| 第 5 周:生产环境进阶 | 第 29-30 天 | 🔜 待发布 |
🔮 下期预告
第 23 天:日志收集实战:EFK/ELK 栈在 K8s 中部署
监控解决了”出了什么问题”,日志回答了”为什么出问题”。下篇将带你搭建 Elasticsearch + Fluentd + Kibana 日志收集流水线,实现对 Pod 日志的实时采集、解析与全文检索。
本文为 K8s 系列第 22/30 篇,欢迎收藏、转发,一起系统掌握 Kubernetes!















暂无评论内容