理解壓力停頓資訊 (PSI) 指標

詳細解釋了壓力暫停資訊 (PSI) 指標以及如何使用它們來識別 Kubernetes 中的資源壓力。
特性狀態: Kubernetes v1.34 [beta]

作為一項 Beta 功能,Kubernetes 允許您配置 kubelet 以收集 CPU、記憶體和 I/O 使用情況的 Linux 核心 壓力暫停資訊 (PSI)。這些資訊在節點、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 秒和 3 分鐘的移動平均值中被暫停的實際掛鐘時間的百分比。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,導致核心的頁面快取增長並強制進行記憶體回收,從而產生壓力。

建立一個名為 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

隨著 Pod 不斷寫入磁碟,您將看到 I/O 的 some 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("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

下一步

有關 叢集故障排除的任務頁面討論瞭如何使用依賴於這些資料的指標管道。