Kubernetes v1.33→1.36:PSI 指标正式 GA,节点资源阻塞终于看得见

2026-05-13 24 预计阅读时间:1 分钟
来源:kubernetes.io AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:10 分钟

CPU 利用率 80%,看起来还有余量——但调度延迟已经让关键 Pod 的请求排队数百毫秒。这种"利用率正常、实际已经卡死"的盲区,在 Kubernetes 里长期存在。v1.36 中 PSI(Pressure Stall Information)指标从 Beta 晋升 GA,意味着你终于有一个稳定接口,直接观测节点、Pod、容器三个层面的资源阻塞,而不是靠利用率猜。

利用率为什么会骗人

传统监控看的是"用了多少":CPU 百分比、内存占用率。问题在于,利用率低不代表没有压力。一个 4 核节点 CPU 利用率 60%,如果其中两个核被批处理任务占满、另外两个核上的交互服务在调度队列里等待,用户体验已经恶化——但利用率曲线一切正常。

PSI 的思路完全不同:它不问"用了多少",而是问"有多少时间被浪费在等待上"。内核从 2018 年开始提供 PSI,现在 Kubernetes 把这套信号正式接入了可观测体系。PSI 提供两类数据:

  • 累计总量(Cumulative Totals):任务处于阻塞状态的绝对时间,适合做趋势分析。
  • 滑动平均(Moving Averages):10 秒、60 秒、300 秒三个窗口,帮你区分瞬时抖动和持续压力。60 秒窗口突然跳到 5% 以上,基本可以确认资源饱和正在发生。

开销实测:高密度场景下的两次对照

可观测功能晋升 GA,最常被问的就是"开它要付出多少资源"。SIG Node 在 4 核机器、80+ Pod 密度下做了两组对照实验,结论很明确。

Kubelet 采集开销

第一组实验:内核 PSI 已开启(psi=1),对比 Kubelet Feature Gate 开关对资源使用的影响。

结果:Kubelet CPU 使用曲线在开启和关闭状态下几乎完全重叠,同步的波动在幅度和频率上一致。额外开销稳定在 0.1 核以内,约占节点总容量 2.5%,完全融入 Kubelet 常规的 housekeeping 周期。系统级 CPU 开销同样如此——操作系统本身在跟踪 PSI 大约消耗 2.5 核,Kubelet 去读 cgroup 指标带来的增量可以忽略。

内核跟踪开销

第二组实验:对比 psi=1psi=0 的内核开销,隔离出操作系统层面的记账成本。

在高 I/O 和 CPU 负载、80 Pod 密度下,系统 CPU 增量稳定在 0.037–0.125 核(0.925%–3.125%)。出现过一次 0.225 核(5.6%)的瞬时尖峰,几秒内回落。Kubelet 作为主要采集进程,周期性扫描 cgroup 层级时的 CPU 使用始终低于 0.25 核(6.25%),且尖峰不超过 1 秒。

结论:无论内核层还是 Kubelet 层,PSI 的开销都足够低,不需要在高密度节点上犹豫是否开启。

Beta 到 GA 之间修掉的一个坑

v1.34 Beta 版有一个容易踩的陷阱:如果 Kubelet Feature Gate 开了 PSI,但底层内核不支持(psi=0 或内核版本太旧),Kubelet 会输出全零指标。监控系统看到零值,可能误判为"没有压力"而非"指标不可用",触发误报或漏报。

v1.36 GA 版修复了这个问题:Kubelet 在采集前先检测 cgroup 配置,确认 OS 层面确实支持 PSI,才输出指标;不支持时直接不发射,避免零值污染告警链路。

快速上手:采集与查询 PSI 指标

前置条件

条件 要求
Linux 内核版本 ≥ 4.20
cgroup 版本 v2
内核编译选项 CONFIG_PSI=y
启动参数 不能带 psi=0
Kubernetes 版本 ≥ v1.36(GA,无需 Feature Gate)

先确认节点内核支持:

# 检查内核版本
uname -r

# 检查 cgroup 版本(v2 路径包含 "cgroup2_fs" 或挂载点为 /sys/fs/cgroup)
mount | grep cgroup2

# 检查 PSI 是否在内核中启用
cat /proc/pressure/cpu
# 如果输出类似 "some avg10=0.00 avg60=0.00 avg300=0.00 total=0" 说明已启用
# 如果报错 "No such file or directory" 说明内核未开启 PSI

通过 Prometheus 采集

Kubelet 的 /metrics/cadvisor 端点现在包含 PSI 指标,Prometheus 直接抓取即可。在 Prometheus 配置中添加:

scrape_configs:
  - job_name: 'kubernetes-cadvisor'
    scheme: https
    tls_config:
      ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    kubernetes_sd_configs:
      - role: node
    relabel_configs:
      - target_label: __metrics_path__
        replacement: /metrics/cadvisor
      - source_labels: [__address__]
        regex: '(.*):10250'
        target_label: __address__
        replacement: '${1}:10250'

部署后,在 Prometheus 中查询 PSI 相关指标名(以 psi 为关键词搜索),你会看到 container_cpu_psi_some_seconds_totalcontainer_memory_psi_some_seconds_total 等指标,覆盖 CPU、Memory、I/O 三个维度,分别有 some(部分任务阻塞)和 full(全部任务阻塞)两个级别。

通过 Summary API 实时查询

如果你是节点管理员,可以通过控制面代理到 Kubelet HTTP API,直接拿到某个容器的实时 PSI 数据:

# 设置你要查询的容器名
CONTAINER_NAME="example-container"

# 通过 API Server 代理查询该容器的 CPU / Memory / I/O PSI 数据
kubectl get --raw "/api/v1/nodes/$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')/proxy/stats/summary" \
  | jq '.pods[].containers[] | select(.name=="'$CONTAINER_NAME'") | {name, cpu: .cpu.psi, memory: .memory.psi, io: .io.psi}'

⚠️ 注意:代理到 Kubelet 是特权操作,存在安全风险。只在有明确管理权限时使用,不要在日常监控流水线中依赖这种方式。

一个基于 PSI 的告警规则示例

利用 PSI 的 60 秒滑动平均,可以写一条比利用率告警更精准的规则:

groups:
  - name: psi-alerts
    rules:
      # 内存阻塞持续超过阈值——比 "内存利用率 > 85%" 更可靠
      - alert: MemoryPressureStallDetected
        expr: container_memory_psi_some_seconds_total / container_memory_psi_some_seconds_created > 0.05
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "容器 {{ $labels.container }}  Pod {{ $labels.pod }} 中出现持续内存阻塞"
          description: "过去 2 分钟内,该容器约 5% 的时间因内存压力处于阻塞状态,可能需要扩容或调整资源限制。"

上述规则中的表达式需要根据你实际采集到的指标名和标签调整。some_seconds_total 是累计值,实际告警通常需要用 rate()increase() 函数计算窗口内的阻塞比例。以下是一个更实用的写法:

- alert: MemoryPressureStallDetected
  expr: rate(container_memory_psi_some_seconds_total[1m]) > 0.05
  for: 2m

这表示:过去 1 分钟内,每秒有超过 5% 的时间任务因内存阻塞被 stall,持续 2 分钟即告警。

采纳建议与注意事项

  • Windows 节点不适用:PSI 是 Linux 内核特性,Windows 节点上 Kubelet 会直接跳过 PSI 指标。混合集群中,Windows 节点的监控需要走其他路径。
  • 先看内核版本再升级:GKE COS 默认 psi=1,但部分自建节点可能用旧内核或 psi=0 启动参数。升级 K8s 到 v1.36 之前,先跑一遍前文的检查命令。
  • 不要立刻替换利用率告警:PSI 和利用率是互补关系。利用率告诉你"还剩多少余量",PSI 告诉你"阻塞有多严重"。建议先并行观察一段时间,建立 PSI 基线,再逐步将关键告警从利用率切换到 PSI。
  • fullsome 更严重some 表示至少一个任务在等待,full 表示所有任务都在等待——后者意味着整个 cgroup 已经实质停摆,优先关注 full 指标。

PSI 指标从 v1.33 Alpha、v1.34 Beta 到 v1.36 GA,走了三个版本。现在接口稳定、开销可控、零值陷阱已修复——如果你的节点满足内核条件,开起来没有理由再等。


相关推荐