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 集群中的部署位置与数据流向。

K8s核心指标采集架构图 K8s核心指标采集架构 Kubernetes 集群 API Server kube-state-metrics Watch 监听 Node 1 node-exporter cadvisor (kubelet) Node 2 node-exporter cadvisor (kubelet) Prometheus Server :8080/metrics :9100/metrics :9100/metrics :10250/metrics/cadvisor :10250/metrics/cadvisor kube-state-metrics node-exporter cadvisor Prometheus

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 标签,便于后续查询时区分数据来源。