Skip to content

Kubernetes v1.37:metrics.k8s.io/v1 正式毕业(GA)——稳定不等于“功能完备”,而是“契约可信”

一句话摘要:Kubernetes v1.37 将 metrics.k8s.io API 正式提升至 v1 稳定版本,标志着 Node/Pod 的 CPU 与内存使用率指标接口进入生产级契约保障阶段;但需清醒认知——它仍是轻量级资源指标通道,非监控替代品,亦不承载自定义指标或历史聚合能力。稳定性 ≠ 功能增强,而是 SLA 级的向后兼容承诺。

背景动机:为什么一个“只读指标 API”值得等 8 年?

从 v1.6(2016 年)的 alpha 到 v1.8(2017 年)升为 v1beta1,再到 v1.37(2026 年)终成 v1metrics.k8s.io 的演进周期长达近十年。这并非开发迟缓,而是 Kubernetes 对“稳定 API”的极端审慎——稳定版 API 意味着 Kubernetes 项目对所有字段语义、行为边界、错误码、序列化格式乃至弃用策略的长期(≥12 个月)SLA 承诺

许多工程师误以为“beta 就是能用”,但真实生产环境早已在“用”:

  • HorizontalPodAutoscaler(HPA)自 v1.2 起就依赖该 API 做基于 CPU/Memory 的扩缩容;
  • kubectl top node/pod 成为 SRE 日常巡检第一入口;
  • 大量内部运维平台、成本分析工具通过 /apis/metrics.k8s.io/v1beta1/... 直接调用原始端点。

然而,v1beta1 的隐性风险始终存在:
✅ 官方可随时引入非破坏性字段(如 timestamp);
⚠️ 但理论上允许在下一 beta 版本中移除字段、变更单位语义(如 memory 从 bytes 改为 KiB)、甚至重构响应结构——只要标注为 “breaking change in next beta”。

v1 的发布,本质是一份法律级技术契约

metrics.k8s.io/v1 的任何字段名、类型、单位、嵌套结构、HTTP 状态码含义,只要未进入正式弃用流程(deprecation policy),将保证向后兼容至少 12 个月;若需变更,必须先发布 v2 并同步维护 v1 至少 12 个月。”

这才是 v1.37 这一“看似平淡”的升级背后真正的重量级信号:Kubernetes 正式承认——资源利用率指标是集群基础设施的‘呼吸脉搏’,其接口稳定性应与 core/v1/Pod 同等级别。

核心技术:v1 做了什么?又刻意没做什么?

✅ 完全兼容的 API 升级(无 Breaking Change)

v1v1beta1 的差异仅在于 API 版本字符串,其余完全一致。以下对比清晰印证:

维度v1beta1v1是否变更
Endpoint 路径/apis/metrics.k8s.io/v1beta1/nodes/apis/metrics.k8s.io/v1/nodes❌ 仅路径版本号
NodeMetrics 字段metadata, timestamp, window, usage(含 cpu, memory完全相同
PodMetrics.containers 结构数组,每项含 name, usage.cpu, usage.memory完全相同
CPU 单位100m = 0.1 CPU core(millicores)完全相同
Memory 单位12893456Ki(二进制 KiB)完全相同

实操验证(直接 curl 或 kubectl):

bash
# 获取所有 Node 当前指标(v1 稳定端点)
kubectl get --raw "/apis/metrics.k8s.io/v1/nodes" | jq '.items[] | {name: .metadata.name, cpu: .usage.cpu, memory: .usage.memory}'

# 获取 default 命名空间下所有 Pod 指标(含容器级拆分)
kubectl get --raw "/apis/metrics.k8s.io/v1/namespaces/default/pods" | \
  jq '.items[] | {pod: .metadata.name, containers: [.containers[] | {name: .name, cpu: .usage.cpu, memory: .usage.memory}]}'

输出示例:

json
{
  "pod": "nginx-7c8f9c7d4-abcde",
  "containers": [
    {
      "name": "nginx",
      "cpu": "214m",
      "memory": "12893456Ki"
    },
    {
      "name": "sidecar",
      "cpu": "12m",
      "memory": "4505600Ki"
    }
  ]
}

⚠️ 明确划清的边界:这不是 Prometheus,也不是 vLLM 的推理指标通道

metrics.k8s.io/v1 的设计哲学是 “Just Enough Metrics” —— 仅提供 HPA 和基础运维所需的最小可行集:

能力✅ 支持❌ 不支持替代方案
实时 CPU/Memory 使用率(采样窗口默认 60s)
按容器粒度拆分(PodMetrics.containers
指标历史查询(如“过去 1 小时峰值”)需外部存储Prometheus + kube-state-metrics
自定义指标(如 HTTP QPS、GPU-util、vLLM 的 num_requests_waitingcustom.metrics.k8s.io/v1beta1Prometheus Adapter / KEDA
指标标签扩展(如按 app, env, team 聚合)原生无 label需 Prometheus Relabel
多维聚合(如 “default ns 下所有 nginx Pod 内存均值”)仅返回原始样本需客户端聚合或 Prometheus

🔍 关键洞察v1 的“稳定”恰恰体现在它的“克制”。Kubernetes 团队拒绝将 metrics API 膨胀为通用监控协议——因为那会拖慢核心控制平面、增加 etcd 压力、并模糊职责边界。真正的监控必须交给 Prometheus、Thanos 或云厂商托管服务。

运维建议:从 v1beta1 迁移到 v1 的实操清单

1. 客户端迁移(零风险,推荐立即执行)

kubectl top 已内置智能降级:

bash
# v1.37+ 集群自动优先用 v1;旧集群无缝回退到 v1beta1
kubectl top node  # 无需修改命令

自研工具/脚本必须显式升级

python
# ❌ 旧代码(硬编码 v1beta1)
url = "https://api.cluster.local/apis/metrics.k8s.io/v1beta1/nodes"

# ✅ 新代码(动态发现 + fallback)
import requests
for version in ["v1", "v1beta1"]:
    try:
        resp = requests.get(f"https://api.cluster.local/apis/metrics.k8s.io/{version}/nodes", 
                           headers={"Authorization": f"Bearer {token}"})
        if resp.status_code == 200:
            return resp.json()
    except:
        continue

2. HPA 兼容性:当前仍需 v1beta1,但已明确路线图

官方文档明确指出:HPA 控制器在 v1.37 中仍仅支持 v1beta1。这不是疏忽,而是因 HPA 的指标解析逻辑深度耦合于 beta 版本的 client-go 代码路径。但 SIG Autoscaling 已确认:

“HPA 对 metrics.k8s.io/v1 的原生支持将于 v1.39(2027 Q1)GA。v1.37–v1.38 期间,建议通过 --metric-config 参数或自定义指标适配器桥接。”

临时方案(适用于严格要求 v1 的集群):

yaml
# hpa-v1-bridge.yaml:用 Prometheus Adapter 将 v1 指标“翻译”为 HPA 可识别格式
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx
  metrics:
  - type: External
    external:
      metric:
        name: container_cpu_usage_seconds_total  # 来自 Prometheus
      target:
        type: AverageValue
        averageValue: 500m

3. 监控告警策略重审:警惕“API 稳定”带来的思维惯性

许多团队在 v1beta1 时代习惯性地将 metrics.k8s.io 作为唯一指标源配置告警(如 “Node memory > 90%”)。v1 发布后,请务必重审:

  • 错误做法kubectl get --raw /v1/nodes | jq '... > 0.9' 做定时轮询告警
  • 正确做法:将 metrics.k8s.io/v1 作为实时决策快照源,告警逻辑下沉至 Prometheus(利用 node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes 等更精准指标,并支持历史趋势、降噪、多维下钻)。

延伸阅读:超越 v1 的下一步

  • 📚 官方权威Kubernetes Metrics API v1 Design Doc —— 深入理解为何拒绝添加 disk_usagenetwork_rx_bytes 等字段。
  • 🛠️ 工程实践k8s-metrics-collector —— 开源工具,将 metrics.k8s.io/v1 数据标准化推送到 OpenTelemetry Collector,实现与 APM 体系打通。
  • 🌐 生态演进:SIG Instrumentation 正在推进 KEP-3821: Metrics Aggregation API,目标是在 v1.40+ 提供 /apis/metrics.k8s.io/v1/aggregated 端点,支持跨节点/跨 Pod 的服务级聚合(如 “orders-service 平均 CPU”),这才是真正面向 SLO 的下一代指标层——而 v1,只是这场远征的坚实起点。

最后结语metrics.k8s.io/v1 的 GA,不是终点,而是 Kubernetes 在可观测性领域确立“分层治理”范式的里程碑。它把最基础、最高频、最不可妥协的资源指标钉死在稳定契约上,从而为上层 Prometheus、OpenTelemetry、eBPF tracing 留出自由创新空间。作为 SRE,我们的任务不是拥抱所有指标,而是精准选择每一层的“可信源”——v1,就是你该无条件信任的那一层。