了解压力停顿信息 (PSI) 指标
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。它们分为两种主要的压力类型:some 和 full。
some:此值表示某些任务 (一个或多个) 在资源上停滞。例如,如果某些任务正在等待 I/O,则此指标将增加。这可能是资源争用的早期指标。full:此值表示所有非空闲任务同时在资源上停滞。这表明更严重的资源短缺,整个系统无法取得进展。
每种压力类型提供四种指标:avg10、avg60、avg300 和 total。avg 值表示任务在 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
接下来
有关 集群故障排除 的任务页面讨论了如何使用依赖于这些数据的指标管道。