3、K8s核心指标采集:kube-state-metrics、node-exporter、cadvisor指标详解与部署
在Kubernetes可观测性体系中,指标采集是构建监控数据管道的第一环。本章聚焦三个最核心的指标源:kube-state-metrics(集群状态)、node-exporter(节点资源)和cadvisor(容器资源)。理解它们各自的数据范围、采集原理和部署方式,是后续进行延迟水位分析和异常事件检测的基础。
3.1 三大指标源的分工与数据范围
这三个组件分别从不同维度暴露Kubernetes集群的指标数据,彼此互补,共同构成完整的监控数据视图。
| 组件 | 数据来源 | 核心指标类型 | 暴露端口 | 指标前缀 |
|---|---|---|---|---|
| kube-state-metrics | Kubernetes API Server(监听资源对象) | Pod/Deployment/Node/Namespace等资源状态、副本数、标签、注解 | 8080 | kube_* |
| node-exporter | 宿主机操作系统(/proc、/sys) | CPU使用率、内存使用率、磁盘I/O、网络流量、文件系统 | 9100 | node_* |
| cadvisor | 容器运行时(cgroups、/var/lib/docker) | 容器CPU/内存/网络/文件系统使用量、容器启动时间 | 4194(kubelet内嵌) | container_* |
关键理解: kube-state-metrics 不采集任何资源使用率数据,它只反映“集群中有什么”以及“这些资源处于什么状态”。node-exporter 和 cadvisor 才负责采集“资源用了多少”。三者结合,才能回答“某个 Deployment 的 Pod 是否因为节点内存不足而被驱逐”这类问题。
3.2 kube-state-metrics:集群状态指标详解
kube-state-metrics 通过 Watch 机制监听 Kubernetes API Server 中的资源对象,将其状态转换为 Prometheus 指标。它不存储数据,只做实时转换。
3.2.1 核心指标清单
- Pod 相关:
kube_pod_status_phase(Pending/Running/Succeeded/Failed/Unknown)、kube_pod_info(节点归属)、kube_pod_container_status_restarts_total(重启次数) - Deployment 相关:
kube_deployment_status_replicas_available(可用副本数)、kube_deployment_status_replicas_unavailable(不可用副本数) - Node 相关:
kube_node_status_condition(Ready/DiskPressure/MemoryPressure)、kube_node_spec_unschedulable(是否可调度) - Namespace 相关:
kube_namespace_status_phase(Active/Terminating)
3.2.2 部署方式(Helm)
# 添加 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 \
--set image.tag=v2.10.0 \
--set collectors.namespaces=true \
--set collectors.nodes=true \
--set collectors.pods=true \
--set collectors.deployments=true
性能注意: 在大型集群(超过1000个Pod)中,kube-state-metrics 的指标基数会急剧膨胀。建议启用
--metric-limit 和 --metric-blacklist 参数过滤不必要的指标,或使用 kube-state-metrics 的 custom-resource-state 功能只采集关键资源。
3.3 node-exporter:节点资源指标详解
node-exporter 运行在每个 Kubernetes 节点上(DaemonSet),直接读取宿主机的 /proc 和 /sys 文件系统,暴露节点级别的硬件和操作系统指标。
3.3.1 核心指标清单
- CPU:
node_cpu_seconds_total(按 mode 区分 user/system/idle/iowait) - 内存:
node_memory_MemTotal_bytes、node_memory_MemAvailable_bytes、node_memory_MemFree_bytes - 磁盘:
node_disk_io_time_seconds_total(I/O 时间)、node_disk_read_bytes_total、node_disk_written_bytes_total - 网络:
node_network_receive_bytes_total、node_network_transmit_bytes_total - 文件系统:
node_filesystem_size_bytes、node_filesystem_avail_bytes、node_filesystem_files_free
3.3.2 部署方式(DaemonSet + 主机网络)
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: monitoring
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
hostNetwork: true # 使用主机网络,采集宿主机指标
hostPID: true # 访问宿主机进程信息
containers:
- name: node-exporter
image: prom/node-exporter:v1.6.0
args:
- --path.procfs=/host/proc
- --path.sysfs=/host/sys
- --collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($|/)
ports:
- containerPort: 9100
hostPort: 9100
volumeMounts:
- name: proc
mountPath: /host/proc
readOnly: true
- name: sys
mountPath: /host/sys
readOnly: true
volumes:
- name: proc
hostPath:
path: /proc
- name: sys
hostPath:
path: /sys
采集优化: 默认情况下 node-exporter 会采集大量指标(约1000+)。建议通过
--collector.disable-defaults 配合 --collector.enable 只启用需要的采集器,例如:--collector.enable=cpu,meminfo,diskstats,netdev,filesystem,减少 Prometheus 存储压力。
3.4 cadvisor:容器资源指标详解
cadvisor 已经内嵌在 kubelet 中,通过 kubelet 的 /metrics/cadvisor 端点暴露容器级别的资源使用指标。无需单独部署,但需要正确配置 kubelet 的启动参数。
3.4.1 核心指标清单
- 容器 CPU:
container_cpu_usage_seconds_total(累计CPU时间)、container_cpu_cfs_periods_total(CFS调度周期) - 容器内存:
container_memory_usage_bytes(当前使用量)、container_memory_working_set_bytes(工作集内存,更准确) - 容器网络:
container_network_receive_bytes_total、container_network_transmit_bytes_total - 容器文件系统:
container_fs_usage_bytes、container_fs_limit_bytes
3.4.2 启用与采集配置
cadvisor 指标默认在 kubelet 的 10250 端口(HTTPS)上暴露。Prometheus 采集时需要使用 ServiceAccount 进行身份认证。
# Prometheus 采集配置示例(scrape_configs 片段)
- job_name: 'kubelet-cadvisor'
scheme: https
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
insecure_skip_verify: true
bearer__file: /var/run/secrets/kubernetes.io/serviceaccount/
kubernetes_sd_configs:
- role: node
relabel_configs:
- target_label: __address__
replacement: kubernetes.default.svc:443
- source_labels: [__meta_kubernetes_node_name]
regex: (.+)
target_label: __metrics_path__
replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor
指标选择建议: 在计算容器内存使用率时,优先使用
container_memory_working_set_bytes 而非 container_memory_usage_bytes,因为 working_set 剔除了缓存和缓冲区,更接近实际内存压力。CPU 使用率则通过 rate(container_cpu_usage_seconds_total[5m]) 计算。
3.5 三大指标源架构关系
下图展示了 kube-state-metrics、node-exporter 和 cadvisor 在 Kubernetes 集群中的部署位置与数据流向。
3.6 指标采集对比与选型建议
在实际运维中,需要根据监控目标选择合适的指标源。下表总结了三个组件在关键场景下的适用性。
| 监控场景 | 推荐指标源 | 关键指标示例 | 说明 |
|---|---|---|---|
| 检测Pod是否被驱逐 | kube-state-metrics | kube_pod_status_reason |
直接反映Pod被驱逐的原因(Evicted) |
| 节点CPU/内存水位 | node-exporter | node_cpu_seconds_total、node_memory_MemAvailable_bytes |
反映宿主机整体资源压力 |
| 单个容器CPU/内存使用 | cadvisor | container_cpu_usage_seconds_total、container_memory_working_set_bytes |
精确到容器级别,用于Pod资源限制分析 |
| Deployment副本数异常 | kube-state-metrics | kube_deployment_status_replicas_unavailable |
快速发现服务降级 |
| 节点磁盘I/O瓶颈 | node-exporter | node_disk_io_time_seconds_total |
结合 rate() 计算I/O延迟 |
| 容器网络流量异常 | cadvisor | container_network_receive_bytes_total |
可用于检测容器级别的网络风暴 |
3.7 部署验证与常见问题
3.7.1 验证指标是否正常采集
部署完成后,可以通过以下命令快速验证指标端点是否正常响应。
# 验证 kube-state-metrics
kubectl port-forward -n monitoring svc/kube-state-metrics 8080:8080 &
curl -s http://localhost:8080/metrics | head -20
# 验证 node-exporter(需在节点上执行)
curl -s http://localhost:9100/metrics | grep node_cpu_seconds_total | head -5
# 验证 cadvisor(通过 kubelet 代理)
kubectl get --raw /api/v1/nodes/<node-name>/proxy/metrics/cadvisor | grep container_cpu_usage_seconds_total | head -5
3.7.2 常见问题与排查
- kube-state-metrics 指标缺失: 检查 ServiceAccount 权限,确保有
list和watch对应资源的权限。 - node-exporter 采集不到磁盘指标: 确认
--path.procfs和--path.sysfs挂载正确,且容器有hostPID: true权限。 - cadvisor 指标返回 403: 检查 Prometheus 的 bearer_ 是否有效,以及 kubelet 的
--authentication--webhook是否启用。 - 指标基数过大导致 Prometheus OOM: 在 kube-state-metrics 中使用
--metric-whitelist或--metric-blacklist过滤指标;在 node-exporter 中禁用不必要的采集器。
最佳实践: 建议在 Prometheus 的 scrape_config 中为每个指标源设置独立的
scrape_interval:kube-state-metrics 可以设为 30s(状态变化不频繁),node-exporter 和 cadvisor 设为 15s(资源使用变化较快)。同时为每个 job 添加 metrics_path 和 job_name 标签,便于后续查询时区分数据来源。