4. cAdvisor 与 kubelet 指标集成:指标路径与标签解析
在 Kubernetes 集群中,容器运行时指标主要通过两条路径暴露:cAdvisor(独立 DaemonSet 或嵌入 kubelet)和 kubelet(内置 cAdvisor 的 /metrics/cadvisor 端点)。理解这两者的集成方式、指标路径差异以及标签解析规则,是设计精准容量预警规则的前提。
4.1 指标暴露架构
cAdvisor 最初作为独立组件运行,从 Kubernetes 1.12 起被直接嵌入 kubelet 中。当前主流集群中,kubelet 的 /metrics/cadvisor 端点提供了与独立 cAdvisor 几乎一致的容器资源指标,但路径和标签结构略有不同。下图展示了指标采集的完整链路:
最佳实践: 在 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 路径)等高频变化标签,以控制指标基数。