了解压力停顿信息 (PSI) 指标

详细解释压力失速信息 (PSI) 指标以及如何使用它们来识别 Kubernetes 中的资源压力。
功能状态: Kubernetes v1.34 [beta]

作为一项 Beta 功能,Kubernetes 允许您配置 kubelet 以收集 Linux 内核的 压力失速信息 (PSI),用于 CPU、内存和 I/O 使用情况。这些信息在节点、Pod 和容器级别收集。默认情况下,通过设置 KubeletPSI 功能门 启用此功能。

PSI 指标通过两种不同的来源公开

  • kubelet 的 Summary API,它提供节点、Pod 和容器级别的 PSI 数据。
  • kubelet 上的 /metrics/cadvisor 端点,它以 Prometheus 格式公开 PSI 指标。

要求

压力失速信息需要在您的 Linux 节点上满足以下要求

  • Linux 内核必须是 4.20 或更高版本
  • 内核必须使用 CONFIG_PSI=y 选项进行编译。大多数现代发行版默认启用此选项。您可以通过运行 zgrep CONFIG_PSI /proc/config.gz 来检查您的内核配置。
  • 某些 Linux 发行版可能会将 PSI 编译到内核中,但默认情况下禁用它。如果是这样,您需要在启动时通过将 psi=1 参数添加到内核命令行来启用它。
  • 节点必须使用 cgroup v2

了解 PSI 指标

PSI 指标 (压力失速信息) 针对三种资源提供:CPU、内存和 I/O。它们分为两种主要的压力类型:somefull

  • some:此值表示某些任务 (一个或多个) 在资源上停滞。例如,如果某些任务正在等待 I/O,则此指标将增加。这可能是资源争用的早期指标。
  • full:此值表示所有非空闲任务同时在资源上停滞。这表明更严重的资源短缺,整个系统无法取得进展。

每种压力类型提供四种指标:avg10avg60avg300totalavg 值表示任务在 10 秒、60 秒和 5 分钟移动平均时间内的停滞壁钟时间的百分比。total 值是以微秒为单位的累积计数器,显示任务停滞的总时间。

示例场景

您可以使用带有压力测试工具的简单 Pod 来生成资源压力并观察 PSI 指标。以下示例使用 agnhost 容器镜像,其中包含 stress 工具。

生成 CPU 压力

创建一个使用 stress 实用程序生成 CPU 压力的 Pod。此工作负载将对一个 CPU 核心施加沉重负载。

创建一个名为 cpu-pressure-pod.yaml 的文件

apiVersion: v1
kind: Pod
metadata:
  name: cpu-pressure-pod
spec:
  restartPolicy: Never
  containers:
  - name: cpu-stress
    image: registry.k8s.io/e2e-test-images/agnhost:2.47
    args:
    - "stress"
    - "--cpus"
    - "1"
    resources:
      limits:
        cpu: "500m"
      requests:
        cpu: "500m"

将其应用于您的集群:kubectl apply -f cpu-pressure-pod.yaml

观察 CPU 压力

Pod 运行后,您可以通过 Summary API 或 Prometheus 指标端点观察 CPU 压力。

使用 Summary API

监视您的节点的摘要统计信息。在另一个终端中,运行

# Replace <node-name> with the name of a node in your cluster
kubectl get --raw "/api/v1/nodes/<node-name>/proxy/stats/summary" | jq '.pods[] | select(.podRef.name | contains("cpu-pressure-pod"))'

您将在 Summary API 输出中看到 CPU 的 some PSI 指标增加。some 压力的 avg10 值应高于零,表明任务正在花费时间停滞在 CPU 上。

使用 Prometheus 指标端点

查询 /metrics/cadvisor 端点以查看 container_pressure_cpu_waiting_seconds_total 指标。

# Replace <node-name> with the name of the node where the pod is running
kubectl get --raw "/api/v1/nodes/<node-name>/proxy/metrics/cadvisor" | \
    grep 'container_pressure_cpu_waiting_seconds_total{container="cpu-stress"'

输出应显示一个增加的值,表明容器正在花费时间等待 CPU 资源。

清理

完成时清理 Pod

kubectl delete pod cpu-pressure-pod

生成内存压力

此示例创建一个 Pod,该 Pod 会持续将文件写入容器的可写层,导致内核页面缓存增长并强制进行内存回收,从而产生压力。

创建一个名为 memory-pressure-pod.yaml 的文件

apiVersion: v1
kind: Pod
metadata:
  name: memory-pressure-pod
spec:
  restartPolicy: Never
  containers:
  - name: memory-stress
    image: registry.k8s.io/e2e-test-images/agnhost:2.47
    command: ["/bin/sh", "-c"]
    args:
    - "i=0; while true; do dd if=/dev/zero of=testfile.$i bs=1M count=50 &>/dev/null; i=$(((i+1)%5)); sleep 0.1; done"
    resources:
      limits:
        memory: "200M"
      requests:
        memory: "200M"

将其应用于您的集群:kubectl apply -f memory-pressure-pod.yaml

观察内存压力

使用 Summary API

在摘要输出中,您将观察到内存的 full PSI 指标增加,表明系统正承受巨大的内存压力。

# Replace <node-name> with the name of a node in your cluster
kubectl get --raw "/api/v1/nodes/<node-name>/proxy/stats/summary" | jq '.pods[] | select(.podRef.name | contains("memory-pressure-pod"))'

使用 Prometheus 指标端点

查询 /metrics/cadvisor 端点以查看 container_pressure_memory_waiting_seconds_total 指标。

# Replace <node-name> with the name of the node where the pod is running
kubectl get --raw "/api/v1/nodes/<node-name>/proxy/metrics/cadvisor" | \
    grep 'container_pressure_memory_waiting_seconds_total{container="memory-stress"'

在输出中,您将观察到该指标的值增加,表明系统正承受巨大的内存压力。

清理

完成时清理 Pod

kubectl delete pod memory-pressure-pod

生成 I/O 压力

此 Pod 通过重复将文件写入磁盘并使用 sync 将数据从内存刷新出来来生成 I/O 压力,从而产生 I/O 停滞。

创建一个名为 io-pressure-pod.yaml 的文件

apiVersion: v1
kind: Pod
metadata:
  name: io-pressure-pod
spec:
  restartPolicy: Never
  containers:
  - name: io-stress
    image: registry.k8s.io/e2e-test-images/agnhost:2.47
    command: ["/bin/sh", "-c"]
    args:
      - "while true; do dd if=/dev/zero of=testfile bs=1M count=128 &>/dev/null; sync; rm testfile &>/dev/null; done"

将其应用于您的集群:kubectl apply -f io-pressure-pod.yaml

观察 I/O 压力

使用 Summary API

您将看到 I/O 的 some PSI 指标增加,因为 Pod 会持续写入磁盘。

# Replace <node-name> with the name of a node in your cluster
kubectl get --raw "/api/v1/nodes/<node-name>/proxy/stats/summary" | jq '.pods[] | select(.podRef.name | contains("io-pressure-pod"))'

使用 Prometheus 指标端点

查询 /metrics/cadvisor 端点以查看 container_pressure_io_waiting_seconds_total 指标。

# Replace <node-name> with the name of the node where the pod is running
kubectl get --raw "/api/v1/nodes/<node-name>/proxy/metrics/cadvisor" | \
    grep 'container_pressure_io_waiting_seconds_total{container="io-stress"'

您将看到该指标的值增加,因为 Pod 会持续写入磁盘。

清理

完成时清理 Pod

kubectl delete pod io-pressure-pod

接下来

有关 集群故障排除 的任务页面讨论了如何使用依赖于这些数据的指标管道。

上次修改时间:2025 年 11 月 30 日下午 3:34 PST:更正 PSI 指标描述中的移动平均持续时间 (997b8d14fd)