Prometheus - 监控 K8s 集群:kube-state-metrics 集成与全维度监控

👋 大家好,欢迎来到我的技术博客!
📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。
🎯 本文将围绕Prometheus这个话题展开,希望能为你带来一些启发或实用的参考。
🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获!
文章目录
- Prometheus - 监控 K8s 集群:kube-state-metrics 集成与全维度监控
Prometheus - 监控 K8s 集群:kube-state-metrics 集成与全维度监控
在现代云原生架构中,Kubernetes(简称 K8s)已成为容器编排的事实标准。然而,随着集群规模的扩大和微服务数量的激增,如何有效监控整个系统运行状态成为运维团队的核心挑战。Prometheus 作为 CNCF 毕业项目,凭借其强大的多维数据模型、灵活的查询语言 PromQL 以及活跃的生态系统,已成为 Kubernetes 监控领域的首选方案。而 kube-state-metrics 作为连接 Kubernetes API 与 Prometheus 的关键桥梁,提供了对集群资源状态的深度洞察。
本文将深入探讨如何通过集成 kube-state-metrics 构建一个覆盖基础设施、工作负载、应用性能和业务指标的全维度 Kubernetes 监控体系,并结合 Java 应用示例展示端到端的可观测性实践。
为什么需要 kube-state-metrics?
在理解 kube-state-metrics 的作用之前,我们先明确 Kubernetes 监控的两个核心维度:
-
基础设施监控(Infrastructure Metrics)
关注节点(Node)、Pod、容器的资源使用情况,如 CPU、内存、磁盘 I/O、网络流量等。这类指标通常由 cAdvisor(集成在 kubelet 中)或 node-exporter 提供。 -
资源状态监控(Resource State Metrics)
关注 Kubernetes 资源对象的元数据状态,例如:- Deployment 是否处于期望的副本数?
- Pod 是否处于 Pending、CrashLoopBackOff 等异常状态?
- Service 是否有可用的 Endpoints?
- Job 是否成功完成?
这些状态信息无法通过传统的资源使用率指标反映,但对判断系统健康度至关重要。而这正是 kube-state-metrics 的核心价值所在。
📌 kube-state-metrics 是什么?
它是一个简单的服务,监听 Kubernetes API Server,将集群中各种资源对象(如 Pods、Deployments、Services 等)的状态转换为 Prometheus 可抓取的指标格式。它不存储任何数据,仅提供实时快照。
与 cAdvisor / node-exporter 的区别
| 组件 | 数据来源 | 指标类型 | 示例 |
|---|---|---|---|
| cAdvisor | 容器运行时(如 containerd) | 资源使用率 | container_cpu_usage_seconds_total |
| node-exporter | 主机操作系统 | 主机级资源 | node_memory_MemAvailable_bytes |
| kube-state-metrics | Kubernetes API Server | 资源对象状态 | kube_pod_status_phase{phase="Running"} |
三者互补,共同构成完整的监控视图。
部署 kube-state-metrics 到 Kubernetes 集群
kube-state-metrics 通常以 Deployment 形式部署在集群中,并通过 Service 暴露指标端点。以下是推荐的部署方式(基于 Helm):
# 添加 prometheus-community Helm 仓库
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
# 安装 kube-state-metrics
helm install kube-state-metrics prometheus-community/kube-state-metrics \
--namespace monitoring \
--create-namespace
🔗 官方 Helm Chart 文档:https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-state-metrics
安装完成后,验证服务是否正常运行:
kubectl get pods -n monitoring -l app.kubernetes.io/name=kube-state-metrics
# 应看到类似输出:
# NAME READY STATUS RESTARTS AGE
# kube-state-metrics-7d5f9c8b4d-2xk9l 1/1 Running 0 2m
访问指标端点(需端口转发):
kubectl port-forward svc/kube-state-metrics -n monitoring 8080:8080
curl http://localhost:8080/metrics
你将看到大量以 kube_ 开头的指标,例如:
kube_pod_status_phase{namespace="default",pod="my-app-7d5f9c8b4d-abc12",phase="Running"} 1
kube_deployment_status_replicas_available{namespace="monitoring",deployment="kube-state-metrics"} 1
配置 Prometheus 抓取 kube-state-metrics 指标
为了让 Prometheus 发现并抓取 kube-state-metrics 的指标,我们需要配置 ServiceMonitor(如果使用 Prometheus Operator)或直接在 prometheus.yml 中添加 job。
方式一:使用 Prometheus Operator(推荐)
如果你使用 kube-prometheus-stack(包含 Prometheus Operator),只需创建一个 ServiceMonitor:
# kube-state-metrics-servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: kube-state-metrics
namespace: monitoring
labels:
release: prometheus-operator # 与 Prometheus 实例的 serviceMonitorSelector 匹配
spec:
selector:
matchLabels:
app.kubernetes.io/name: kube-state-metrics
namespaceSelector:
matchNames:
- monitoring
endpoints:
- port: http
interval: 30s
应用后,Prometheus 会自动发现该目标。
方式二:直接修改 prometheus.yml
如果你手动部署 Prometheus,编辑其配置文件:
scrape_configs:
- job_name: 'kube-state-metrics'
static_configs:
- targets: ['kube-state-metrics.monitoring.svc.cluster.local:8080']
💡 提示:确保 Prometheus 有权限访问
monitoring命名空间中的服务。
核心 kube-state-metrics 指标详解
kube-state-metrics 暴露了数百个指标,覆盖几乎所有 Kubernetes 资源。以下是几类关键指标及其使用场景:
1. Pod 状态监控
-
kube_pod_status_phase{phase="Pending|Running|Succeeded|Failed|Unknown"}- 用途:检测卡在 Pending 状态的 Pod(可能因资源不足或镜像拉取失败)
- 告警规则示例:
- alert: PodStuckInPending expr: kube_pod_status_phase{phase="Pending"} > 0 for: 5m labels: severity: warning annotations: summary: "Pod stuck in pending state"
-
kube_pod_container_status_restarts_total- 用途:识别频繁重启的容器(可能因 OOM 或应用崩溃)
- PromQL 查询:
# 过去 5 分钟内重启次数 > 3 的容器 rate(kube_pod_container_status_restarts_total[5m]) > 0.01
2. Deployment 健康度
kube_deployment_status_replicas_availablekube_deployment_spec_replicas- 用途:判断 Deployment 是否达到期望副本数
- PromQL 查询:
# 可用副本数 < 期望副本数的 Deployment kube_deployment_status_replicas_available < kube_deployment_spec_replicas
3. 节点状态
kube_node_status_condition{condition="Ready", status="true"}- 用途:监控节点是否就绪
- 告警规则:
- alert: NodeNotReady expr: kube_node_status_condition{condition="Ready", status="true"} == 0 for: 2m labels: severity: critical
4. 资源配额与限制
kube_pod_container_resource_requestskube_pod_container_resource_limits- 用途:分析集群资源分配情况,避免资源碎片
构建全维度监控体系:四层监控模型
一个健壮的 Kubernetes 监控体系应覆盖以下四个层次:
第一层:基础设施监控(Infrastructure)
- 关注点:Node、Pod、容器的 CPU、内存、磁盘、网络
- 数据源:
node_exporter:主机级指标cAdvisor:容器级指标(通过 kubelet/metrics/cadvisor暴露)
- 关键指标:
node_cpu_seconds_totalcontainer_memory_usage_bytesrate(container_network_receive_bytes_total[5m])
第二层:工作负载监控(Workload)
- 关注点:Kubernetes 资源对象的状态与配置
- 数据源:
kube-state-metrics - 关键指标:
kube_pod_status_phasekube_deployment_status_replicas_availablekube_service_info
第三层:应用性能监控(APM)
- 关注点:应用内部的性能指标,如 HTTP 延迟、错误率、JVM 状态
- 数据源:应用自身暴露的指标(通过 Micrometer、Prometheus Client 等)
- 关键指标:
http_server_requests_seconds_countjvm_memory_used_byteslogback_events_total
第四层:业务监控(Business)
- 关注点:与业务直接相关的指标,如订单量、支付成功率
- 数据源:应用埋点
- 关键指标:
order_created_totalpayment_success_rate
接下来,我们将通过一个 Java Spring Boot 应用示例,展示如何实现第三层和第四层监控。
Java 应用集成:Spring Boot + Micrometer + Prometheus
Spring Boot 应用可通过 Micrometer 库轻松暴露 Prometheus 指标。Micrometer 是一个应用指标门面(类似 SLF4J),支持多种监控后端,包括 Prometheus。
步骤 1:添加依赖
在 pom.xml 中添加:
<dependencies>
<!-- Spring Boot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Micrometer Registry for Prometheus -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
</dependencies>
步骤 2:启用 Prometheus 端点
在 application.yml 中配置:
management:
endpoints:
web:
exposure:
include: health,info,prometheus # 暴露 prometheus 端点
metrics:
tags:
application: ${spring.application.name}
启动应用后,访问 http://localhost:8080/actuator/prometheus 即可看到指标。
步骤 3:自定义业务指标
假设我们有一个订单服务,希望监控订单创建数量和支付成功率:
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
private final Counter orderCreatedCounter;
private final Counter paymentSuccessCounter;
private final Counter paymentFailureCounter;
private final Timer orderProcessingTimer;
public OrderService(MeterRegistry meterRegistry) {
// 订单创建计数器
this.orderCreatedCounter = Counter.builder("order_created_total")
.description("Total number of orders created")
.register(meterRegistry);
// 支付成功/失败计数器
this.paymentSuccessCounter = Counter.builder("payment_success_total")
.description("Total successful payments")
.register(meterRegistry);
this.paymentFailureCounter = Counter.builder("payment_failure_total")
.description("Total failed payments")
.register(meterRegistry);
// 订单处理耗时
this.orderProcessingTimer = Timer.builder("order_processing_duration_seconds")
.description("Time taken to process an order")
.register(meterRegistry);
}
public void createOrder(Order order) {
Timer.Sample sample = Timer.start();
try {
// 业务逻辑
doCreateOrder(order);
orderCreatedCounter.increment();
} finally {
sample.stop(orderProcessingTimer);
}
}
public boolean processPayment(Payment payment) {
try {
boolean success = doProcessPayment(payment);
if (success) {
paymentSuccessCounter.increment();
} else {
paymentFailureCounter.increment();
}
return success;
} catch (Exception e) {
paymentFailureCounter.increment();
throw e;
}
}
}
步骤 4:配置 Prometheus 抓取应用指标
在 Prometheus 配置中添加 job:
scrape_configs:
- job_name: 'spring-boot-app'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
action: keep
regex: my-java-app # 你的应用标签
- source_labels: [__address__]
action: replace
target_label: __address__
regex: ([^:]+)(?::\d+)?
replacement: $1:8080 # 应用端口
- source_labels: [__meta_kubernetes_pod_name]
target_label: pod
🔗 Micrometer 官方文档:https://micrometer.io/docs
关键告警规则设计
有效的告警应遵循 SMART 原则(具体、可衡量、可实现、相关、有时限)。以下是针对不同层级的典型告警规则:
1. 节点级别告警
- alert: HighNodeCPU
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90
for: 10m
labels:
severity: warning
annotations:
summary: "High CPU usage on {{ $labels.instance }}"
- alert: NodeDiskSpaceLow
expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) < 0.1
for: 5m
labels:
severity: critical
2. Pod 级别告警
- alert: PodCrashLooping
expr: rate(kube_pod_container_status_restarts_total[5m]) > 0.1
for: 10m
labels:
severity: warning
annotations:
summary: "Pod {{ $labels.pod }} is crash looping"
- alert: PodNotReady
expr: sum by (pod) (kube_pod_status_ready{condition="true"}) == 0
for: 5m
labels:
severity: critical
3. 应用级别告警(Java)
- alert: HighHttpErrorRate
expr: sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m]))
/ sum(rate(http_server_requests_seconds_count[5m])) > 0.05
for: 5m
labels:
severity: warning
annotations:
summary: "HTTP error rate is above 5%"
- alert: JVMHeapUsageHigh
expr: jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"} > 0.85
for: 10m
labels:
severity: warning
4. 业务级别告警
- alert: OrderCreationDropped
expr: rate(order_created_total[10m]) < 1
for: 15m
labels:
severity: critical
annotations:
summary: "Order creation rate dropped below 1 per 10 minutes"
可视化:Grafana 仪表盘构建
Grafana 是 Prometheus 最流行的可视化工具。我们可以创建多层仪表盘:
1. 集群概览仪表盘
- 节点 CPU/内存使用率
- Pod 状态分布(Running/Pending/Failed)
- Deployment 健康度(可用副本 vs 期望副本)
2. 应用性能仪表盘
- HTTP 请求速率、延迟、错误率
- JVM 内存、GC 次数、线程数
- 自定义业务指标(如订单量)
3. 业务指标仪表盘
- 实时订单量趋势
- 支付成功率
- 用户地域分布(需额外埋点)
🔗 Grafana 官方仪表盘库:https://grafana.com/grafana/dashboards/
推荐导入 ID:1860(Kubernetes Cluster Monitoring)、12856(Spring Boot Stats)
高级技巧:指标关联与根因分析
真正的全维度监控不仅在于收集指标,更在于关联分析。例如:
场景:应用响应时间突然升高
- 基础设施层:检查节点 CPU 是否打满 →
node_cpu_seconds_total - 工作负载层:检查 Pod 是否被驱逐或重启 →
kube_pod_status_phase,kube_pod_container_status_restarts_total - 应用层:检查 GC 暂停时间是否过长 →
jvm_gc_pause_seconds_sum - 业务层:检查是否伴随订单量激增 →
order_created_total
通过 PromQL 的 join 操作,我们可以关联不同维度的指标:
# 查看高延迟请求对应的 Pod
http_server_requests_seconds_count{status=~"5.."}
+ on(pod) group_left()
kube_pod_status_phase{phase="Running"}
使用 Recording Rules 优化查询
对于复杂查询,可创建 Recording Rules 预计算结果:
# prometheus-rules.yaml
groups:
- name: app-rules
rules:
- record: job:http_inprogress_requests:sum
expr: sum(http_server_requests_seconds_count) by (job)
- record: cluster:pod_cpu_usage:ratio
expr: sum(rate(container_cpu_usage_seconds_total[5m]))
/ sum(kube_pod_container_resource_requests{resource="cpu"})
故障排查实战:从告警到修复
让我们通过一个真实案例演示全维度监控的价值。
问题现象
收到告警:PodCrashLooping,Pod order-service-7d5f9c8b4d-abc12 每 2 分钟重启一次。
排查步骤
-
查看 Pod 日志
kubectl logs order-service-7d5f9c8b4d-abc12 --previous输出:
java.lang.OutOfMemoryError: Java heap space -
检查 JVM 指标
- 在 Grafana 中查看
jvm_memory_used_bytes,发现堆内存持续增长至上限 jvm_gc_pause_seconds_count显示 Full GC 频繁但无法释放内存
- 在 Grafana 中查看
-
关联业务指标
order_created_total在问题发生前有突增- 推测:大促活动导致订单量激增,应用未做限流
-
检查资源请求
kube_pod_container_resource_requests{resource="memory"}显示内存请求为 512Micontainer_memory_usage_bytes显示实际使用已超 1Gi
解决方案
- 临时扩容:增加 Pod 内存限制
resources: requests: memory: "1Gi" limits: memory: "2Gi" - 长期优化:
- 引入缓存减少数据库压力
- 添加限流机制(如 Resilience4j)
- 优化代码内存使用(如分页查询)
验证修复
- 观察
kube_pod_container_status_restarts_total是否归零 - 监控
jvm_memory_used_bytes是否稳定 - 确认
order_created_total恢复正常
性能优化与最佳实践
1. 控制指标基数(Cardinality)
高基数指标会显著增加 Prometheus 存储和查询压力。避免在标签中使用高变异性字段(如用户 ID、请求 ID)。
✅ 好做法:
// 使用有限枚举值作为标签
Counter.builder("http_requests_total")
.tag("method", request.getMethod()) // GET/POST 等
.tag("status", String.valueOf(response.getStatus())) // 200/404/500
❌ 坏做法:
// 用户 ID 可能有百万级,导致指标爆炸
.tag("user_id", userId)
2. 合理设置抓取间隔
- 基础设施指标:15-30s
- 应用指标:30-60s
- 业务指标:60s+
过短的间隔会增加负载,过长则影响告警时效性。
3. 使用 Relabeling 精简标签
通过 relabel_configs 移除不必要的标签:
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
target_label: app
- action: labeldrop
regex: __meta_kubernetes_pod_label_.*
4. 分离长期存储
对于超过 15 天的历史数据,建议使用 Thanos 或 Cortex 实现长期存储和全局查询。
总结:构建可观测性闭环
通过集成 kube-state-metrics,我们成功将 Kubernetes 集群的“状态”纳入监控体系,与基础设施指标、应用性能指标、业务指标共同构成了完整的可观测性金字塔:
但这仅仅是开始。真正的价值在于:
- 预防性:通过容量规划避免故障(如预测内存耗尽)
- 快速定位:从告警到根因分析的时间从小时级缩短到分钟级
- 业务驱动:将技术指标与业务结果关联,证明 IT 价值
🌟 记住:监控不是目的,而是手段。最终目标是构建一个自愈、自适应、以业务为中心的云原生系统。
随着 Kubernetes 生态的演进,Service Mesh(如 Istio)、eBPF 等新技术将进一步丰富监控维度。但无论技术如何变化,全维度、关联性、自动化始终是监控体系的核心原则。
现在,是时候检查你的集群是否已具备这四层防护了!🚀
🙌 感谢你读到这里!
🔍 技术之路没有捷径,但每一次阅读、思考和实践,都在悄悄拉近你与目标的距离。
💡 如果本文对你有帮助,不妨 👍 点赞、📌 收藏、📤 分享 给更多需要的朋友!
💬 欢迎在评论区留下你的想法、疑问或建议,我会一一回复,我们一起交流、共同成长 🌿
🔔 关注我,不错过下一篇干货!我们下期再见!✨
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)