Pods 與容器的資源管理

當您指定一個 Pod 時,您可以選擇性地指定一個 容器 需要多少的資源。最常指定的資源是 CPU 和記憶體 (RAM);還有其他資源類型。

當您為 Pod 中的容器指定資源「請求 (request)」時,kube-scheduler 會利用此資訊來決定將 Pod 放在哪個節點上。當您為容器指定資源「限制 (limit)」時,kubelet 會強制執行這些限制,以確保執行中的容器不會使用超過您設定的資源限制。kubelet 也會為該容器專門保留至少「請求 (request)」量的系統資源以供使用。

請求與限制

如果 Pod 執行所在的節點有足夠的可用資源,容器可以使用超過其針對該資源所指定之 `request` 量的資源,這是可能且允許的。

例如,如果您為容器設定 256 MiB 的 `memory` 請求,且該容器位於排程到一個具有 8GiB 記憶體且沒有其他 Pod 的節點上,那麼該容器可以嘗試使用更多的 RAM。

限制則不同。`cpu` 和 `memory` 限制都由 kubelet(和 容器執行時期)應用,並最終由核心強制執行。在 Linux 節點上,Linux 核心透過 cgroups 強制執行限制。`cpu` 和 `memory` 限制的強制執行行為略有不同。

`cpu` 限制透過 CPU 節流來強制執行。當容器接近其 `cpu` 限制時,核心將根據容器的限制來限制其對 CPU 的存取。因此,`cpu` 限制是核心強制執行的硬性限制。容器不得使用超過其 `cpu` 限制中指定的 CPU 量。

`memory` 限制透過核心的記憶體不足 (OOM) 終止機制來強制執行。當容器使用超過其 `memory` 限制時,核心可能會終止它。然而,終止只會在核心偵測到記憶體壓力時發生。因此,過度分配記憶體的容器可能不會立即被終止。這表示 `memory` 限制是反應性地強制執行的。容器可能會使用超過其 `memory` 限制的記憶體,但如果這樣做,它可能會被終止。

注意

有一個 `MemoryQoS` 的 alpha 功能,它使用 cgroup v2 在 Linux 節點上增加了記憶體節流和可選的分層記憶體保留。詳情請參閱使用 cgroup v2 的記憶體 QoS

注意

如果您為資源指定了限制,但未指定任何請求,並且沒有准入時機制為該資源應用預設請求,那麼 Kubernetes 會複製您指定的限制並將其用作該資源的請求值。

資源類型

「資源類型 (resource type)」具有一個基本單位,可以被請求、限制或兩者兼有。Kubernetes 具有以下內建資源類型

資源類型描述基本單位
cpu計算處理cpu (核心)
memoryRAM位元組 (Bytes)
ephemeral-storage本地臨時儲存位元組 (Bytes)
hugepages-<size>大頁面 (僅限 Linux)位元組 (Bytes)

叢集還可以提供擴充資源 (帶有自訂名稱的資源,通常由裝置外掛程式公開)。

大頁面

對於 Linux 工作負載,您可以指定「大頁面 (huge page)」資源。大頁面是 Linux 特有的功能,其中節點核心分配的記憶體區塊遠大於預設頁面大小。

例如,在預設頁面大小為 4KiB 的系統上,您可以指定一個限制,`hugepages-2Mi: 80Mi`。如果容器嘗試分配超過 40 個 2MiB 的大頁面 (總計 80 MiB),該分配將會失敗。

注意

您不能超額配置 `hugepages-*` 資源。這與 `memory` 和 `cpu` 資源不同。

CPU 和記憶體統稱為「計算資源 (compute resources)」或「資源 (resources)」。計算資源是可測量的數量,可以被請求、分配和使用。它們不同於 API 資源。API 資源,例如 Pods 和 Services,是透過 Kubernetes API 伺服器讀取和修改的物件。

Pod 和容器的資源請求與限制

對於每個容器,您可以指定資源限制和請求,包括以下內容

  • spec.containers[].resources.limits.cpu
  • spec.containers[].resources.limits.memory
  • spec.containers[].resources.limits.ephemeral-storage
  • spec.containers[].resources.limits.hugepages-<size>
  • spec.containers[].resources.requests.cpu
  • spec.containers[].resources.requests.memory
  • spec.containers[].resources.requests.ephemeral-storage
  • spec.containers[].resources.requests.hugepages-<size>

儘管您只能為單個容器指定請求和限制,但考量 Pod 的整體資源請求和限制也很有用。對於特定資源,「Pod 資源請求/限制」是 Pod 中每個容器該類型資源請求/限制的總和。

Pod 層級資源規範

功能狀態: Kubernetes v1.34 [beta] (預設啟用)

如果您的叢集已啟用 `PodLevelResources` 功能閘門,您可以在 Pod 層級指定資源請求和限制。在 Pod 層級,Kubernetes 1.36 僅支援特定資源類型的請求或限制:`cpu` 和/或 `memory` 和/或 `hugepages`。透過此功能,Kubernetes 允許您為 Pod 宣告一個整體資源預算,這在處理大量容器時特別有用,因為很難精確評估每個容器的個別資源需求。此外,它還能讓 Pod 中的容器彼此共用閒置資源,從而提高資源利用率。

對於 Pod,您可以透過包含以下內容來指定 CPU 和記憶體的資源限制和請求

  • spec.resources.limits.cpu
  • spec.resources.limits.memory
  • spec.resources.limits.hugepages-<size>
  • spec.resources.requests.cpu
  • spec.resources.requests.memory
  • spec.resources.requests.hugepages-<size>

Kubernetes 中的資源單位

CPU 資源單位

CPU 資源的限制和請求以「cpu」單位測量。在 Kubernetes 中,1 個 CPU 單位相當於 **1 個實體 CPU 核心**,或 **1 個虛擬核心**,這取決於節點是實體主機還是運行在實體機器內的虛擬機器。

允許使用分數請求。當您定義一個 `spec.containers[].resources.requests.cpu` 設定為 `0.5` 的容器時,您所請求的 CPU 時間是請求 `1.0` CPU 時的一半。對於 CPU 資源單位,數量表達式 `0.1` 等同於表達式 `100m`,可讀作「一百毫核 (one hundred millicpu)」。有些人會說「一百毫核心 (one hundred millicores)」,兩者意思相同。

CPU 資源始終以絕對量指定,而非相對量。例如,無論容器是在單核、雙核還是 48 核機器上運行,`500m` CPU 都表示大致相同的計算能力。

注意

Kubernetes 不允許您以小於 `1m` 或 `0.001` CPU 的精度指定 CPU 資源。為了避免意外使用無效的 CPU 數量,當使用的 CPU 單位小於 1 時,使用毫核 (milliCPU) 形式而非十進位形式來指定 CPU 單位會很有幫助。

例如,您有一個使用 `5m` 或 `0.005` CPU 的 Pod,並希望減少其 CPU 資源。透過使用十進位形式,很難察覺 `0.0005` CPU 是一個無效值,而透過使用毫核 (milliCPU) 形式,則更容易察覺 `0.5m` 是一個無效值。

記憶體資源單位

`memory` 的限制和請求以位元組 (bytes) 為單位測量。您可以使用這些數量後綴之一來表示記憶體為純整數或定點數:E、P、T、G、M、k。您也可以使用二的冪次等效單位:Ei、Pi、Ti、Gi、Mi、Ki。Kubernetes API 也允許 `m` 作為後綴 (代表毫位元組:1/1000 位元組),但這在指定時並不實用:您必須始終分配整數位元組,或有時是更大的區塊,例如 1 gibibyte 的倍數。

以下是一些表示大致相同值的記憶體數量範例

128974848, 129e6, 129M,  128974848000m, 123Mi

請注意後綴的大小寫。「M」表示 megabytes (百萬位元組),而「m」表示 millibytes (毫位元組)。如果您請求 `400m` 記憶體,這表示請求 0.4 位元組。輸入此內容的人可能原本是想請求 400 mebibytes (`400Mi`) 或 400 megabytes (`400M`)。

容器資源範例

下列 Pod 有兩個容器。這兩個容器都定義了 0.25 CPU 和 64MiB (226 位元組) 記憶體的請求。每個容器的限制為 0.5 CPU 和 128MiB 記憶體。可以說此 Pod 的請求為 0.5 CPU 和 128 MiB 記憶體,限制為 1 CPU 和 256MiB 記憶體。

---
apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: app
    image: images.my-company.example/app:v4
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: log-aggregator
    image: images.my-company.example/log-aggregator:v6
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

Pod 資源範例

功能狀態: Kubernetes v1.34 [beta] (預設啟用)

此功能可透過設定 `PodLevelResources` 功能閘門來啟用。下列 Pod 有一個明確的 1 CPU 和 100 MiB 記憶體的請求,以及一個明確的 1 CPU 和 200 MiB 記憶體的限制。`pod-resources-demo-ctr-1` 容器已設定明確的請求和限制。然而,`pod-resources-demo-ctr-2` 容器將僅共用 Pod 資源範圍內可用的資源,因為它沒有設定明確的請求和限制。

apiVersion: v1
kind: Pod
metadata:
  name: pod-resources-demo
  namespace: pod-resources-example
spec:
  resources:
    limits:
      cpu: "1"
      memory: "200Mi"
    requests:
      cpu: "1"
      memory: "100Mi"
  containers:
  - name: pod-resources-demo-ctr-1
    image: nginx
    resources:
      limits:
        cpu: "0.5"
        memory: "100Mi"
      requests:
        cpu: "0.5"
        memory: "50Mi"
  - name: pod-resources-demo-ctr-2
    image: fedora
    command:
    - sleep
    - inf 

如何排程帶有資源請求的 Pods

當您建立一個 Pod 時,Kubernetes 排程器會為該 Pod 選擇一個節點來運行。每個節點對於每種資源類型都有最大容量:它可以為 Pod 提供多少 CPU 和記憶體。排程器確保對於每種資源類型,所有已排程容器的資源請求總和小於該節點的容量。請注意,儘管節點上實際的記憶體或 CPU 資源使用量可能非常低,如果容量檢查失敗,排程器仍會拒絕將 Pod 放置在該節點上。這可以防止在資源使用量稍後增加時 (例如,在每日請求高峰期間) 節點上出現資源短缺。

Kubernetes 如何應用資源請求與限制

當 kubelet 啟動 Pod 中的一個容器時,kubelet 會將該容器的記憶體和 CPU 請求與限制傳遞給容器執行時期。

在 Linux 上,容器執行時期通常會配置核心 cgroups,以應用和強制執行您定義的限制。

  • CPU 限制定義了容器可以使用多少 CPU 時間的硬性上限。在每個排程區間 (時間片) 內,Linux 核心會檢查此限制是否超出;如果超出,核心會等待,然後才允許該 cgroup 恢復執行。
  • CPU 請求通常定義了一個權重。如果多個不同的容器 (cgroups) 想要在一個競爭激烈的系統上運行,具有較大 CPU 請求的工作負載將被分配比具有較小請求的工作負載更多的 CPU 時間。
  • 記憶體請求主要用於 (Kubernetes) Pod 排程期間。在使用 cgroups v2 的節點上,容器執行時期可能會使用記憶體請求作為設定 `memory.min` 和 `memory.low` 的提示。
  • 記憶體限制定義了該 cgroup 的記憶體上限。如果容器嘗試分配超過此限制的記憶體,Linux 核心的記憶體不足子系統將會啟動,並且通常會透過停止容器中嘗試分配記憶體的其中一個程序來進行干預。如果該程序是容器的 PID 1,並且容器被標記為可重新啟動,Kubernetes 會重新啟動該容器。
  • Pod 或容器的記憶體限制也可以應用於記憶體支援磁碟區 (例如 `emptyDir`) 中的頁面。kubelet 將 `tmpfs` `emptyDir` 磁碟區視為容器記憶體使用,而非本機暫時儲存。使用記憶體支援的 `emptyDir` 時,請務必查看下方的注意事項。

如果容器超出其記憶體請求,並且它運行的節點整體記憶體不足,則該容器所屬的 Pod 很可能會被驅逐

容器可能允許或不允許長時間超過其 CPU 限制。然而,容器執行時期不會因為過度使用 CPU 而終止 Pods 或容器。

要判斷容器是否因資源限制而無法排程或被終止,請參閱疑難排解章節。

調整容器資源大小

建立 Pod 後,您可能需要根據實際使用模式調整其 CPU 或記憶體資源。Kubernetes 提供兩種方法來調整 Pod 資源大小

原地調整大小

功能狀態: Kubernetes v1.35 [stable](預設啟用)

您可以在不重新建立的情況下,修改執行中 Pod 中容器的 CPU 和記憶體「請求 (requests)」和「限制 (limits)」。這稱為「原地 Pod 垂直擴展 (in-place Pod vertical scaling)」或「原地 Pod 調整大小 (in-place Pod resize)」。要執行原地調整大小,請使用 Pod 的 `/resize` 子資源更新容器的資源規範。您可以透過在容器規範中設定 `resizePolicy` 欄位來控制是否需要容器重新啟動。

注意

原地調整大小目前適用於容器層級資源。如需調整 Pod 層級資源大小,請參閱調整 Pod 的 CPU 和記憶體資源

透過啟動替換 Pods 來調整大小

改變 Pod 資源的雲原生方法是更新工作負載物件 (例如 Deployment 或 StatefulSet) 中的 Pod 模板,並讓工作負載的控制器以具有更新資源的新 Pod 替換舊 Pod。此方法適用於任何 Kubernetes 版本,並且可以更改任何 Pod 規範。

有關 Pod 調整大小的更多詳細資訊,請參閱調整 Pod 大小。有關原地調整大小的詳細說明,請參閱調整分配給容器的 CPU 和記憶體資源。您也可以使用垂直 Pod 自動縮放器來自動管理 Pod 資源建議。

監控計算與記憶體資源使用量

kubelet 會將 Pod 的資源使用情況作為 Pod `status` 的一部分進行報告。

如果您的叢集中提供了可選的監控工具,則 Pod 資源使用量可以直接從指標 API 取得,或從您的監控工具中取得。

記憶體支援的 `emptyDir` 磁碟區考量事項

注意

如果您未為 `emptyDir` 磁碟區指定 `sizeLimit`,該磁碟區可能會消耗高達該 Pod 的記憶體限制 (`Pod.spec.containers[].resources.limits.memory`)。如果您未設定記憶體限制,Pod 的記憶體消耗將沒有上限,並且可以消耗節點上所有可用的記憶體。Kubernetes 會根據資源請求 (`Pod.spec.containers[].resources.requests`) 來排程 Pods,並且在決定另一個 Pod 是否可以放入給定節點時,不會考量超過請求的記憶體使用量。這可能導致服務拒絕,並使作業系統執行記憶體不足 (OOM) 處理。有可能建立任意數量的 `emptyDir`,這些 `emptyDir` 可能會消耗節點上所有可用的記憶體,從而使 OOM 發生的可能性更高。

從記憶體管理的角度來看,程序使用記憶體作為工作區與使用記憶體支援的 `emptyDir` 之間存在一些相似之處。但當記憶體被用作磁碟區時,例如記憶體支援的 `emptyDir`,您應該注意以下額外事項

  • 儲存在記憶體支援磁碟區上的檔案幾乎完全由使用者應用程式管理。與作為程序的暫存工作區使用時不同,您不能依賴諸如語言層級的垃圾收集等機制。
  • 將檔案寫入磁碟區的目的是儲存資料或在應用程式之間傳遞資料。Kubernetes 和作業系統都不會自動從磁碟區刪除檔案,因此,當系統或 Pod 承受記憶體壓力時,這些檔案使用的記憶體無法被回收。
  • 記憶體支援的 `emptyDir` 因其效能而有用,但記憶體通常比其他儲存媒體 (例如磁碟或 SSD) 體積更小且成本更高。為 `emptyDir` 磁碟區使用大量記憶體可能會影響 Pod 或整個節點的正常運作,因此應謹慎使用。

如果您是叢集或命名空間的管理員,您也可以設定資源配額 (ResourceQuota) 來限制記憶體使用;您可能還希望定義一個限制範圍 (LimitRange) 以進行額外強制執行。如果您為每個 Pod 指定 `spec.containers[].resources.limits.memory`,那麼 `emptyDir` 磁碟區的最大大小將會是該 Pod 的記憶體限制。

作為替代方案,叢集管理員可以使用政策機制 (例如ValidationAdmissionPolicy) 來強制執行新 Pods 中 `emptyDir` 磁碟區的大小限制。

本地臨時儲存

有關本機暫時儲存的一般概念,以及關於為容器配置暫時儲存的請求和/或限制的提示,請查閱本機暫時儲存頁面。

本機暫時儲存的資源監控

kubelet 可以測量正在使用多少本機暫時儲存。只要您已啟用本機暫時儲存容量隔離,它就會這樣做。

Kubernetes 追蹤 Pod 從以下來源使用的暫時儲存量

  • 寫入容器的可寫層 (rootfs)、容器映像檔,或兩者。
  • 寫入本機 `emptyDir` 磁碟區。
  • Pod 自己的日誌 (通常儲存在 `/var/log/pods` 下)。
  • 由 Kubernetes 管理並映射到 Pod 中的系統檔案,例如 `/etc/hosts`。

擴充資源

擴充資源是 `kubernetes.io` 網域之外的完整資源名稱。它們允許叢集操作員宣傳非 Kubernetes 內建資源,並供使用者使用。

使用擴充資源需要兩個步驟。首先,叢集操作員必須宣傳一個擴充資源。其次,使用者必須在 Pods 中請求擴充資源。

管理擴充資源

節點層級擴充資源

節點層級擴充資源與節點綁定。

裝置外掛程式管理的資源

有關如何在每個節點上宣傳裝置外掛程式管理的資源,請參閱裝置外掛程式

其他資源

要宣傳新的節點層級擴充資源,叢集操作員可以向 API 伺服器提交 `PATCH` HTTP 請求,以指定叢集中節點 `status.capacity` 中的可用數量。在此操作之後,節點的 `status.capacity` 將包含一個新資源。`status.allocatable` 欄位將由 kubelet 自動且非同步地使用新資源進行更新。

因為排程器在評估 Pod 適配性時使用節點的 `status.allocatable` 值,排程器只會在該非同步更新後才考慮新值。將新資源修補到節點容量與第一個請求該資源的 Pod 可以在該節點上排程之間可能會有一小段延遲。

範例:

這是一個範例,展示如何使用 `curl` 構成一個 HTTP 請求,用於在主節點為 `k8s-master` 的節點 `k8s-node-1` 上宣傳五個 "example.com/foo" 資源。

curl --header "Content-Type: application/json-patch+json" \
--request PATCH \
--data '[{"op": "add", "path": "/status/capacity/example.com~1foo", "value": "5"}]' \
http://k8s-master:8080/api/v1/nodes/k8s-node-1/status

注意

在前述請求中,`~1` 是修補路徑中字元 `/` 的編碼。JSON-Patch 中的操作路徑值被解釋為 JSON-Pointer。詳情請參閱IETF RFC 6901,第 3 節

叢集層級擴充資源

叢集層級擴充資源不與節點綁定。它們通常由排程器擴充器 (scheduler extenders) 管理,這些擴充器負責處理資源消耗和資源配額。

您可以在排程器設定中指定由排程器擴充器處理的擴充資源

範例:

下列排程器政策設定表示叢集層級擴充資源 "example.com/foo" 由排程器擴充器處理。

  • 排程器僅在 Pod 請求 "example.com/foo" 時,才會將 Pod 傳送給排程器擴充器。
  • `ignoredByScheduler` 欄位指定排程器在其 `PodFitsResources` 判斷式中不檢查 "example.com/foo" 資源。
{
  "kind": "Policy",
  "apiVersion": "v1",
  "extenders": [
    {
      "urlPrefix":"<extender-endpoint>",
      "bindVerb": "bind",
      "managedResources": [
        {
          "name": "example.com/foo",
          "ignoredByScheduler": true
        }
      ]
    }
  ]
}

透過 DRA 分配擴充資源

透過 DRA 分配擴充資源允許叢集管理員在 DeviceClass 中指定 `extendedResourceName`,然後可以從 Pod 的擴充資源請求中請求與 DeviceClass 匹配的裝置。閱讀更多關於透過 DRA 分配擴充資源

使用擴充資源

使用者可以在 Pod 規範中像 CPU 和記憶體一樣使用擴充資源。排程器會處理資源會計,以確保同時分配給 Pods 的資源不會超過可用數量。

API 伺服器將擴充資源的數量限制為整數。「有效」數量的範例為 `3`、`3000m` 和 `3Ki`。「無效」數量的範例為 `0.5` 和 `1500m` (因為 `1500m` 將導致 `1.5`)。

注意

擴充資源取代了不透明整數資源 (Opaque Integer Resources)。使用者可以使用除 `kubernetes.io` (已保留) 以外的任何網域名稱前綴。

要在 Pod 中使用擴充資源,請將資源名稱作為鍵包含在容器規範中的 `spec.containers[].resources.limits` 映射中。

注意

擴充資源不能超額配置,因此,如果容器規範中同時存在請求和限制,則兩者必須相等。

僅當所有資源請求 (包括 CPU、記憶體和任何擴充資源) 都滿足時,Pod 才會被排程。只要資源請求無法滿足,Pod 就會保持在 `PENDING` 狀態。

範例:

下面的 Pod 請求 2 個 CPU 和 1 個 "example.com/foo" (一個擴充資源)。

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: myimage
    resources:
      requests:
        cpu: 2
        example.com/foo: 1
      limits:
        example.com/foo: 1

PID 限制

程序 ID (PID) 限制允許設定 kubelet 來限制給定 Pod 可以消耗的 PID 數量。詳情請參閱PID 限制

疑難排解

我的 Pods 處於 Pending 狀態並顯示事件訊息 `FailedScheduling`

如果排程器找不到任何可以容納 Pod 的節點,該 Pod 將保持未排程狀態,直到找到一個位置為止。每當排程器未能為 Pod 找到位置時,就會產生一個事件 (Event)。您可以使用 `kubectl` 查看 Pod 的事件;例如

kubectl describe pod frontend | grep -A 9999999999 Events
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  23s   default-scheduler  0/42 nodes available: insufficient cpu

在前述範例中,名為 "frontend" 的 Pod 因任何節點上的 CPU 資源不足而無法排程。類似的錯誤訊息也可能表示因記憶體不足 (`PodExceedsFreeMemory`) 導致的失敗。一般來說,如果 Pod 處於 Pending 狀態並顯示此類訊息,有幾種解決方法可以嘗試

  • 向叢集中新增更多節點。
  • 終止不需要的 Pods 以為 Pending 中的 Pods 騰出空間。
  • 檢查 Pod 的大小是否沒有超過所有節點的容量。例如,如果所有節點的容量都是 `cpu: 1`,那麼請求 `cpu: 1.1` 的 Pod 將永遠不會被排程。
  • 檢查節點污點 (taints)。如果您的大多數節點都被污染 (tainted),並且新的 Pod 無法容忍該污點 (taint),排程器只會考慮將 Pod 放置在沒有該污點的其餘節點上。

您可以使用 `kubectl describe nodes` 指令檢查節點容量和已分配的數量。例如

kubectl describe nodes e2e-test-node-pool-4lw4
Name:            e2e-test-node-pool-4lw4
[ ... lines removed for clarity ...]
Capacity:
 cpu:                               2
 memory:                            7679792Ki
 pods:                              110
Allocatable:
 cpu:                               1800m
 memory:                            7474992Ki
 pods:                              110
[ ... lines removed for clarity ...]
Non-terminated Pods:        (5 in total)
  Namespace    Name                                  CPU Requests  CPU Limits  Memory Requests  Memory Limits
  ---------    ----                                  ------------  ----------  ---------------  -------------
  kube-system  fluentd-gcp-v1.38-28bv1               100m (5%)     0 (0%)      200Mi (2%)       200Mi (2%)
  kube-system  kube-dns-3297075139-61lj3             260m (13%)    0 (0%)      100Mi (1%)       170Mi (2%)
  kube-system  kube-proxy-e2e-test-...               100m (5%)     0 (0%)      0 (0%)           0 (0%)
  kube-system  monitoring-influxdb-grafana-v4-z1m12  200m (10%)    200m (10%)  600Mi (8%)       600Mi (8%)
  kube-system  node-problem-detector-v0.1-fj7m3      20m (1%)      200m (10%)  20Mi (0%)        100Mi (1%)
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  CPU Requests    CPU Limits    Memory Requests    Memory Limits
  ------------    ----------    ---------------    -------------
  680m (34%)      400m (20%)    920Mi (11%)        1070Mi (13%)

在前述輸出中,您可以看到,如果 Pod 請求超過 1.120 CPU 或超過 6.23Gi 的記憶體,該 Pod 將無法放入節點。

透過查看「Pods」區段,您可以看到哪些 Pods 正在佔用節點上的空間。

可供 Pods 使用的資源量少於節點容量,因為系統守護程序會使用一部分可用資源。在 Kubernetes API 中,每個節點都有一個 `.status.allocatable` 欄位 (詳情請參閱NodeStatus)。

`.status.allocatable` 欄位描述了該節點上可供 Pods 使用的資源量 (例如:15 個虛擬 CPU 和 7538 MiB 記憶體)。有關 Kubernetes 中節點可分配資源的更多資訊,請參閱為系統守護程序保留計算資源

您可以設定資源配額 (resource quotas) 來限制命名空間可以消耗的總資源量。當特定命名空間中存在 ResourceQuota 時,Kubernetes 會對該命名空間中的物件強制執行配額。例如,如果您將特定的命名空間分配給不同的團隊,您可以在這些命名空間中新增 ResourceQuotas。設定資源配額有助於防止一個團隊使用過多的任何資源,以致於這種過度使用影響到其他團隊。

您還應該考慮您授予該命名空間的存取權限:對命名空間的完全寫入存取權限允許擁有該存取權限的人移除任何資源,包括已配置的 ResourceQuota。

我的容器已終止

您的容器可能會因為資源不足而被終止。要檢查容器是否因為達到資源限制而被終止,請在相關 Pod 上執行 `kubectl describe pod`。

kubectl describe pod simmemleak-hra99

輸出類似於

Name:                           simmemleak-hra99
Namespace:                      default
Image(s):                       saadali/simmemleak
Node:                           kubernetes-node-tf0f/10.240.216.66
Labels:                         name=simmemleak
Status:                         Running
Reason:
Message:
IP:                             10.244.2.75
Containers:
  simmemleak:
    Image:  saadali/simmemleak:latest
    Limits:
      cpu:          100m
      memory:       50Mi
    State:          Running
      Started:      Tue, 07 Jul 2019 12:54:41 -0700
    Last State:     Terminated
      Reason:       OOMKilled
      Exit Code:    137
      Started:      Fri, 07 Jul 2019 12:54:30 -0700
      Finished:     Fri, 07 Jul 2019 12:54:33 -0700
    Ready:          False
    Restart Count:  5
Conditions:
  Type      Status
  Ready     False
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  42s   default-scheduler  Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f
  Normal  Pulled     41s   kubelet            Container image "saadali/simmemleak:latest" already present on machine
  Normal  Created    41s   kubelet            Created container simmemleak
  Normal  Started    40s   kubelet            Started container simmemleak
  Normal  Killing    32s   kubelet            Killing container with id ead3fb35-5cf5-44ed-9ae1-488115be66c6: Need to kill Pod

在前述範例中,`Restart Count: 5` 表示 Pod 中的 `simmemleak` 容器已被終止並重新啟動了五次 (截至目前為止)。`OOMKilled` 原因顯示該容器試圖使用的記憶體超過了其限制。

您的下一步可能是檢查應用程式程式碼是否存在記憶體洩漏。如果您發現應用程式的行為符合預期,請考慮為該容器設定更高的記憶體限制 (以及可能的請求)。

接下來


上次修改 2026 年 4 月 13 日下午 6:38 PST:簡化 CPU 基本單位措辭 (0f42539bd6)