4. cAdvisor 与 kubelet 指标集成:指标路径与标签解析

在 Kubernetes 集群中,容器运行时指标主要通过两条路径暴露:cAdvisor(独立 DaemonSet 或嵌入 kubelet)和 kubelet(内置 cAdvisor 的 /metrics/cadvisor 端点)。理解这两者的集成方式、指标路径差异以及标签解析规则,是设计精准容量预警规则的前提。

4.1 指标暴露架构

cAdvisor 最初作为独立组件运行,从 Kubernetes 1.12 起被直接嵌入 kubelet 中。当前主流集群中,kubelet 的 /metrics/cadvisor 端点提供了与独立 cAdvisor 几乎一致的容器资源指标,但路径和标签结构略有不同。下图展示了指标采集的完整链路:

cAdvisor 与 kubelet 指标集成架构 cAdvisor 与 kubelet 指标集成架构 容器运行时 (Docker / containerd / CRI-O) cAdvisor (独立 DaemonSet) kubelet (内置 cAdvisor) /metrics/cadvisor /metrics/resource (v1.18+) Prometheus 采集器 独立 cAdvisor 已逐步被 kubelet 替代
最佳实践: 在 Kubernetes v1.14+ 集群中,建议直接采集 kubelet 的 /metrics/cadvisor 端点,避免部署独立的 cAdvisor DaemonSet。这减少了资源开销,且指标标签与 kubelet 节点信息天然对齐。

4.2 核心指标路径与端点对比

kubelet 暴露了多个与容器运行时相关的指标端点,每个端点的用途和指标范围不同。下表列出了最关键的三个端点及其差异:

端点路径 引入版本 指标范围 标签丰富度 推荐用途
/metrics/cadvisor v1.12+ 容器、Pod、节点级别的 CPU/内存/磁盘/网络 高(包含 container, pod, namespace, image 等) 容器容量预警、资源使用率分析
/metrics/resource v1.18+ (alpha) 仅 CPU 和内存的瞬时使用量 中(包含 pod, namespace, node) HPA 指标源、实时调度决策
/metrics v1.0+ kubelet 自身进程指标、节点状态 低(主要是 kubelet 进程级) kubelet 健康监控、节点容量
关键区别: /metrics/cadvisor 提供的是 累积值(如 container_cpu_usage_seconds_total)和 瞬时值(如 container_memory_working_set_bytes),而 /metrics/resource 仅提供 瞬时采样值。对于容量预警,必须使用 /metrics/cadvisor 的累积指标计算速率和趋势。

4.3 标签解析与维度映射

cAdvisor 指标的最大价值在于其丰富的标签维度。每个容器指标都携带了从容器运行时元数据中提取的标签,这些标签直接映射到 Kubernetes 资源模型。以下是核心标签的解析规则:

  • container — 容器名称(对应 Pod spec 中的 container name),对于 pause 容器或系统容器可能为空或为 POD。
  • pod — Pod 名称,由 kubelet 从 Pod 元数据注入。
  • namespace — Pod 所在的命名空间。
  • image — 容器镜像全名(含 registry 和 tag),用于按镜像聚合资源消耗。
  • name — cAdvisor 内部容器标识,格式为 /kubepods/<guaranteed|burstable|besteffort>/pod<podUID>/<containerID>,可用于 QoS 类识别。
  • id — 完整的 cgroup 路径,可用于调试容器运行时层级。
  • instance — 节点 IP 或主机名(由 Prometheus 采集配置中的 __address__ 标签重写而来)。

4.4 指标路径与标签的 PromQL 应用

理解标签结构后,可以编写精准的 PromQL 查询。以下示例展示了如何利用标签维度进行容量预警:

# 查询指定命名空间下所有容器的 CPU 使用率(基于 container_cpu_usage_seconds_total)
rate(container_cpu_usage_seconds_total{namespace="production", container!="POD", container!=""}[5m])
  / on(container, pod, namespace)
container_spec_cpu_quota{namespace="production"}
* 100

# 查询内存使用量超过 80% 限制的容器(排除 pause 容器)
container_memory_working_set_bytes{container!="POD", container!=""}
  / on(container, pod, namespace)
container_spec_memory_limit_bytes{container!="POD", container!=""}
> 0.8

# 按 QoS 类聚合 CPU 使用总量
sum by (name) (
  rate(container_cpu_usage_seconds_total{container!="POD", container!=""}[5m])
)
* on(name) group_left()
label_replace(
  kube_pod_status_qos_class{},
  "name",
  "/kubepods/.+/pod$1/.*",
  "pod",
  "(.+)"
)
注意: container_spec_cpu_quota 和 container_spec_memory_limit_bytes 仅在容器设置了资源限制(limits)时才存在。对于未设置限制的容器,这些指标缺失,需要结合 kube_pod_container_resource_limits 进行关联查询。

4.5 采集配置示例

在 Prometheus 中采集 kubelet 的 cAdvisor 指标,推荐使用 kubernetes_sd_configs 自动发现节点,并通过 relabeling 保留关键标签:

scrape_configs:
  - job_name: 'kubelet-cadvisor'
    kubernetes_sd_configs:
      - role: node
    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/
    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
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
    metric_relabel_configs:
      - source_labels: [container]
        target_label: container
        regex: (.+)
        action: keep
      - source_labels: [pod]
        target_label: pod
        regex: (.+)
        action: keep

4.6 常见陷阱与避坑指南

陷阱 现象 根因 解决方案
Pause 容器干扰 CPU/内存使用率被稀释 pause 容器(container="POD")也暴露指标 查询时过滤 container!="POD"
标签基数爆炸 Prometheus 内存飙升 container_id 或 id 标签具有高基数 在采集时 drop 掉 id 和 container_id 标签
指标缺失 某些容器无 CPU 配额指标 未设置 resource limits 结合 kube_pod_container_resource_limits 判断
累积值误解 直接使用 container_cpu_usage_seconds_total 导致数值持续增长 未使用 rate() 或 irate() 函数 始终对累积指标使用 rate() 计算速率
生产建议: 在 Prometheus 的 metric_relabel_configs 中,建议保留 container、pod、namespace、image 四个核心标签,丢弃 id、container_id、name(cgroup 路径)等高频变化标签,以控制指标基数。