〔CKS 筆記整理〕深入 Kubernetes 資源管理:從 ResourceQuota 到 Cgroups 的運作機制

更新 發佈閱讀 14 分鐘

在 Kubernetes 的維運實務中,我們常被要求設定 ResourceQuota、LimitRange,並在每個 Pod YAML 中精確定義 CPU 與 Memory 的 Requests/Limits。但這些設定究竟是為了什麼?當你寫下 cpu: "1" 時,底層系統發生了什麼事?

這篇文章將帶您從最上層的「多租戶治理策略」開始,一路向下挖掘,直到最底層的 Container Runtime 與 Linux Kernel Cgroups 是如何協同運作,來確保這些限制生效的。

1. 為什麼要設定 Limit 和 Quota?(The Why)

在一個共享的 Kubernetes 叢集中,如果不加限制,任何一個程式都可能因為 Memory Leak 或無窮迴圈,耗盡整個節點的資源,導致關鍵服務崩潰。這就是標準的「資源爭用 (Resource Contention)」或稱為「嘈雜鄰居 (Noisy Neighbor)」問題。

為了實現穩定的多租戶 (Multi-tenancy) 環境,Kubernetes 提供了兩層管理機制。

1.1 第一層機制:Namespace 級別的總量控制 (ResourceQuota)

ResourceQuota 是防止個別團隊過度消耗整個叢集資源的基礎。它限制的是該 Namespace 內所有 Pod 加總起來的資源用量。

  • 情境:規定 dev 團隊最多只能使用 4 顆 CPU 和 16GB 記憶體。
  • 機制:一旦超過上限,API Server 會在 Admission 階段直接拒絕任何新 Pod 的建立請求 (403 Forbidden)。

範例:ResourceQuota YAML

apiVersion: v1
kind: ResourceQuota
metadata:
name: team-quota
namespace: dev-team
spec:
hard:
# 計算資源總量限制
requests.cpu: "4"
requests.memory: "16Gi"
limits.cpu: "8"
limits.memory: "32Gi"

# 物件數量限制 (防止惡意建立大量 Pod 癱瘓系統) # optional
count/pods: "30"
count/services.loadbalancers: "2" # 限制 LB 數量以控制雲端成本

1.2 ResourceQuota 的協同運作:LimitRange

許多使用者啟用 ResourceQuota 後,發現 Pod 無法啟動,錯誤訊息顯示 failed quota: ...

  • 原因:這是因為 Kubernetes 需要明確的數值來進行加總計算,若 Pod 未定義資源需求,系統將無法判斷配額是否足夠,因此會拒絕建立請求。
  • 解法 (LimitRange):LimitRange 負責管理「個別 Pod」並提供「預設值」。
    • 設定:每個 Pod 預設給 500m CPU (Default),最大不超過 2 CPU (Max)。
    • 效果:即使開發者未在 Pod/Deployment YAML 中定義 resources,LimitRange 也會自動補上預設值,讓 ResourceQuota 能順利計算並放行。

範例:LimitRange YAML

apiVersion: v1
kind: LimitRange
metadata:
name: default-resource-limits
namespace: dev-team
spec:
limits:
- type: Container # 以「container 為單位」來判定。
# 也可以使用 "type: Pod" 來判定。
default: # 預設 Limit (若沒寫 limits 會自動套用此值)
cpu: "1"
memory: "1Gi"
defaultRequest: # 預設 Request (若沒寫 requests 會自動套用此值)
cpu: "500m"
memory: "512Mi"
max: # 單一 Pod 能設定的最大上限 (超過此值會被拒絕)
cpu: "2"
memory: "4Gi"
min: # 單一 Pod 能設定的最小下限
cpu: "100m"
memory: "128Mi"


2. 定義邊界:Pod 級別的 Requests 與 Limits

當請求通過了上述的治理層檢查,進入到 Pod 層級時,我們通常設定兩個數值:Requests 和 Limits。這兩個數值的組合不僅影響排程,更決定了 Pod 的 QoS 類別 (Quality of Service Classes),這是節點資源不足時的處理依據。

2.1 參數解釋

  • Requests (請求值):這是給 Kubernetes Scheduler 看的。Scheduler 根據這個數值決定把 Pod 放在哪個節點上(確保節點有足夠的剩餘空間)。
  • Limits (限制值):這是給 Linux Kernel 看的。這是硬上限,一旦超過,Process 就會被節流 (Throttled) 或終止 (OOM Killed)。

範例:Pod Resources YAML

apiVersion: v1
kind: Pod
metadata:
name: resource-demo
namespace: dev-team
spec:
containers:
- name: app
image: nginx
resources:
requests:
# Scheduler 會確保節點至少有 0.25 CPU 和 64Mi RAM 可用
cpu: "250m"
memory: "64Mi"
limits:
# Kernel Cgroups 會執行此硬上限
# CPU 超過 0.5 會被 Throttled (變慢)
cpu: "500m"
# Memory 超過 128Mi 會被 OOM Killed (重啟)
memory: "128Mi"

2.2 QoS (Quality of Service) 類別與驅逐順序

節點 (Node) 本身資源耗盡發生 Node-pressure Eviction 時,Kubelet 會根據 QoS 類別來決定優先驅逐哪些 Pod,而不僅僅是看誰用最多。

QoS 類別定義條件驅逐優先級 (回收順序)適用場景:

raw-image


3. 核心機制:Runtime 如何使用 Cgroups (The How)

當你在 YAML 寫下 resources: limits: cpu: "1" 時,這行文字最終之所以能生效,完全是因為底層的 Container Runtime (如 runc) 操作了 Linux Kernel 的 Control Groups (Cgroups)

3.1 指令下達與傳遞

  1. Kubelet:讀取 Pod YAML,發現使用者設定了 memory: 512Mi
  2. CRI 溝通:Kubelet 透過 CRI (Container Runtime Interface) 告訴 High-Level Runtime (如 containerd):「幫我啟動一個容器,並將記憶體上限設定為 512MB」。

3.2 實作配置 (Runtime 的工作)

High-Level Runtime (containerd) 會呼叫 Low-Level Runtime (runc)。這時,runc 會執行關鍵動作:

  1. 在宿主機的 Cgroup 階層中建立一個對應此容器的資料夾。
  2. 將數值 536870912 (即 512MB 的 Bytes 值) 寫入該 Cgroup 資料夾下的設定檔中。

注意:Cgroup 版本差異 上述提到的路徑 /sys/fs/cgroup/memory 與檔案 memory.limit_in_bytes 是 Cgroup v1 的標準。 若您的節點使用較新的 Linux Kernel (如 Ubuntu 22.04+),可能會啟用 Cgroup v2 (Unified Hierarchy)。此時路徑會變為 /sys/fs/cgroup/...,且設定檔名稱會變為 memory.max。雖然檔案位置不同,但底層概念是一致的。

3.3 核心執行 (Kernel 的工作)

一旦設定檔被寫入,Linux Kernel 就接手了。Kernel 會根據這個 Cgroup 的設定,嚴格監控該容器內所有 Process 的資源用量。

  • Memory:一旦用量超過設定值,Kernel 會觸發 OOM Killer。
    • 實務細節:OOM 的兩種層級
      1. Pod 層級 (Cgroup OOM):Pod 用量超過 Limit,Kernel 精準終止該 Pod 內的 Process。
      2. Node 層級 (System OOM):整台機器記憶體不足,Kernel 會隨機終止機器上的 Process (有可能誤殺 Docker Daemon 或 Kubelet 導致節點異常)。這就是為什麼設定 Limit 保護 Node 如此重要。
  • CPU:一旦用量超過設定的時間片 (Quota/Period),Kernel 會強制暫停該 Process 的執行 (Throttling),直到下一個週期。
一句話總結:ResourceQuota 是政策,Cgroups 是執行機制,而 Runtime 是負責傳達命令的組件。

4. 關鍵配置細節:Cgroup Driver 的不一致

這是資源管理中常見的配置問題,也是生產環境中導致節點不穩定的主要原因之一。Runtime 可以透過兩種方式來修改 Cgroups:

  1. cgroupfs 驅動:Runtime 直接去寫 /sys/fs/cgroup 下的檔案。這是最原始的做法。
  2. systemd 驅動:Runtime 發送請求給 init system (systemd),請 systemd 幫忙建立 Cgroup。

配置衝突的後果: 如果您的 Kubelet 設定為使用 systemd (現代 Kubernetes 的預設),但底層的 Runtime (如 containerd) 卻設定為使用 cgroupfs,系統就會出現「兩套 Cgroup 管理者」。

  • 影響:當系統負載變高時,Kubelet 與 Runtime 對資源的認知會不同步,可能導致 Kubelet 誤判資源壓力而驅逐 Pod,或是 Cgroup 限制未生效導致節點不穩。
  • 最佳實務:務必確保 Kubelet 和 Container Runtime 的 Cgroup Driver 一致,通常建議統一使用 systemd

如何檢查 Cgroup Driver? 您可以在節點上執行以下指令來確認當前的配置狀態:

# 檢查 Container Runtime (containerd) 的設定
crictl info | grep -i "cgroup"

5. RuntimeClass 視角:不同 Runtime 的 Cgroup 行為

隨著技術演進,我們開始使用 RuntimeClass 來調度不同的 Runtime。它們在處理資源限制時的行為也有所不同:

raw-image

6. 總結

Kubernetes 的資源管理是一個從上到下的完整體系:

  1. ResourceQuota & LimitRange (治理層):決定了「誰」可以使用「多少」資源,防止多租戶間的資源爭用。
  2. Pod Requests/Limits (宣告層):開發者宣告需求,並透過 QoS 類別 決定資源不足時的處理順序。
  3. Runtime (配置層):containerd/runc 負責將這些抽象需求轉譯為作業系統的設定。
  4. Cgroups (執行層):Linux Kernel 真正執行資源隔離與限制,並區分 Cgroup OOM 與 System OOM。

理解從上到下的關係,才能在遇到 OOMKilled 或效能瓶頸時,準確判斷是策略設定問題,還是底層實作的配置誤差,或是主機資源真的不足夠了。

補充連結

留言
avatar-img
Marcos的方格子
25會員
52內容數
歡迎來到「Marcos的方格子」!目前在「Marcos談科技」撰寫在職涯上學習到的知識,在「Marcos談書」分享我在日常的閱讀和心得,歡迎您的到來!!
Marcos的方格子的其他內容
2025/12/10
這篇文章將帶您深入探討 Kubernetes 的流量入口架構,剖析 Ingress 的設計哲學與限制,並解析下一代標準 Gateway API 如何透過「角色導向」的設計解決當前的 Ingress 架構瓶頸。
Thumbnail
2025/12/10
這篇文章將帶您深入探討 Kubernetes 的流量入口架構,剖析 Ingress 的設計哲學與限制,並解析下一代標準 Gateway API 如何透過「角色導向」的設計解決當前的 Ingress 架構瓶頸。
Thumbnail
2025/12/08
探索 API Server 稽核日誌 (Audit Logging) 如何提供安全 (Security)、合規 (Compliance) 和事件響應 (Incident Response) 所需的關鍵鑑識證據。
Thumbnail
2025/12/08
探索 API Server 稽核日誌 (Audit Logging) 如何提供安全 (Security)、合規 (Compliance) 和事件響應 (Incident Response) 所需的關鍵鑑識證據。
Thumbnail
2025/12/08
在 Kubernetes 環境中,預設的網路配置往往是「扁平化」的,這意味著 Pods 之間可以自由通訊,帶來潛在的安全風險。本文將深入探討 NetworkPolicy 的核心機制,並透過 SRE 的角度,從零開始建構一套基於零信任 原則的網路架構,提升 Kubernetes 叢集的整體防禦能力。
Thumbnail
2025/12/08
在 Kubernetes 環境中,預設的網路配置往往是「扁平化」的,這意味著 Pods 之間可以自由通訊,帶來潛在的安全風險。本文將深入探討 NetworkPolicy 的核心機制,並透過 SRE 的角度,從零開始建構一套基於零信任 原則的網路架構,提升 Kubernetes 叢集的整體防禦能力。
Thumbnail
看更多
你可能也想看
Thumbnail
如果你也是那種在職場上追求極致效率,對生活品質有堅持,且渴望一段成熟、穩定、不拖泥帶水關係的專業人士,那麼 Ping! 會是你目前市面上最值得嘗試的選擇。 成熟的大人,不需要在低效的社交中消磨熱情。讓 Ping!,為你的情感生活進行「降噪」,把精力和時間,留給那個真正能與你靈魂共鳴、頻率一致的人。
Thumbnail
如果你也是那種在職場上追求極致效率,對生活品質有堅持,且渴望一段成熟、穩定、不拖泥帶水關係的專業人士,那麼 Ping! 會是你目前市面上最值得嘗試的選擇。 成熟的大人,不需要在低效的社交中消磨熱情。讓 Ping!,為你的情感生活進行「降噪」,把精力和時間,留給那個真正能與你靈魂共鳴、頻率一致的人。
Thumbnail
厭倦只看外貌的交友方式嗎?Ping!主打真實、安全的深度交友體驗,透過真人驗證與多樣化的個人化問答,幫助使用者在認識彼此之前,先理解價值觀、關係期待與交友目標。即使是慢熟的 I 人,也能透過提問找到適合的人選,避免聊到一半才發現方向不同。適合想被理解、重視心理連結與安心互動的你。
Thumbnail
厭倦只看外貌的交友方式嗎?Ping!主打真實、安全的深度交友體驗,透過真人驗證與多樣化的個人化問答,幫助使用者在認識彼此之前,先理解價值觀、關係期待與交友目標。即使是慢熟的 I 人,也能透過提問找到適合的人選,避免聊到一半才發現方向不同。適合想被理解、重視心理連結與安心互動的你。
Thumbnail
Ping!主打真人驗證機制,透過AI人臉比對確保用戶真實性,讓人放心。獨特的照片主題功能、個性化標籤和趣味文字問答,讓用戶更深入展現自我,為開啟話題提供契機,甚至有機會找到擁有相似冷門興趣的同好。Ping!注重高品質的交友關係,透過共同點建立雙方的連結,為現代人提供一個舒適、真實且有意義的交友環境。
Thumbnail
Ping!主打真人驗證機制,透過AI人臉比對確保用戶真實性,讓人放心。獨特的照片主題功能、個性化標籤和趣味文字問答,讓用戶更深入展現自我,為開啟話題提供契機,甚至有機會找到擁有相似冷門興趣的同好。Ping!注重高品質的交友關係,透過共同點建立雙方的連結,為現代人提供一個舒適、真實且有意義的交友環境。
Thumbnail
也許不是我不適合交友,而是我適合的節奏,本來就比較慢。 比起快速認識很多人,我更在意人與人怎麼相遇,才不會那麼累。當對話可以慢慢發生,當我們從想法開始靠近彼此,那種剛剛好的距離,反而讓人更願意走近。
Thumbnail
也許不是我不適合交友,而是我適合的節奏,本來就比較慢。 比起快速認識很多人,我更在意人與人怎麼相遇,才不會那麼累。當對話可以慢慢發生,當我們從想法開始靠近彼此,那種剛剛好的距離,反而讓人更願意走近。
Thumbnail
本篇文章將教你如何在Kubernetes cluster內部署一個MongoDB,包括取得Manifests、建立Volume、部署實務、基本操作和結論。透過操作演示,讓你瞭解在實務上如何成功建立MongoDB,並進行基本操作。
Thumbnail
本篇文章將教你如何在Kubernetes cluster內部署一個MongoDB,包括取得Manifests、建立Volume、部署實務、基本操作和結論。透過操作演示,讓你瞭解在實務上如何成功建立MongoDB,並進行基本操作。
Thumbnail
本文闡述了Kubernetes內部網路通訊的基本概念,從容器到服務的溝通流程,並討論了Kubernetes使用的各種技術。重要的是,管理Kubernetes叢集時理解這些基本概念是極其重要的。
Thumbnail
本文闡述了Kubernetes內部網路通訊的基本概念,從容器到服務的溝通流程,並討論了Kubernetes使用的各種技術。重要的是,管理Kubernetes叢集時理解這些基本概念是極其重要的。
Thumbnail
本篇說明如何利用Kubernetes特色,將PostgreSQL DB以HA的架構來提供服務,並說明相關的實作流程與說明。
Thumbnail
本篇說明如何利用Kubernetes特色,將PostgreSQL DB以HA的架構來提供服務,並說明相關的實作流程與說明。
Thumbnail
本文將演示在安裝完 Kubernetes Cluster 後的基本元件安裝,包括 Calico/Calicoctl、Metric Server 和 Dashboard UI 的安裝方法以及相關問題與解決方式。
Thumbnail
本文將演示在安裝完 Kubernetes Cluster 後的基本元件安裝,包括 Calico/Calicoctl、Metric Server 和 Dashboard UI 的安裝方法以及相關問題與解決方式。
Thumbnail
這篇文章教你如何搭建Kubernetes Cluster,包括節點安裝前設定、軟體套件安裝、Control-Plane部署和加入運算節點等步驟。在建置之後,作者會分享一些基礎服務的安裝。希望這篇文章對你有所幫助。
Thumbnail
這篇文章教你如何搭建Kubernetes Cluster,包括節點安裝前設定、軟體套件安裝、Control-Plane部署和加入運算節點等步驟。在建置之後,作者會分享一些基礎服務的安裝。希望這篇文章對你有所幫助。
Thumbnail
本文章將說明如果您想要從頭建置一組具有Loadbalancer HA架構的Kubernetes Cluster時,你可能會需要做的事前準備工作。
Thumbnail
本文章將說明如果您想要從頭建置一組具有Loadbalancer HA架構的Kubernetes Cluster時,你可能會需要做的事前準備工作。
Thumbnail
本文將說明在安裝完Kubernetes Cluster之後,接下來必須要進行的CNI Plugin安裝建置方式,同時也透過這篇文章進行基本的CNI說明與比較。 1. Container Network Interface (CNI)
Thumbnail
本文將說明在安裝完Kubernetes Cluster之後,接下來必須要進行的CNI Plugin安裝建置方式,同時也透過這篇文章進行基本的CNI說明與比較。 1. Container Network Interface (CNI)
Thumbnail
在現今快速發展的數據應用環境之下,Kubernetes已經成為部署和管理容器化應用的首選平台。但是隨著應用服務愈來愈複雜、被攻擊的風險也愈來愈高。為了保護Kubernetes環境的安全性,跟大家介紹一個針對Kubernetes安全合規掃描的工具,幫助確保您的 Kubernetes 叢集設置和應用程序
Thumbnail
在現今快速發展的數據應用環境之下,Kubernetes已經成為部署和管理容器化應用的首選平台。但是隨著應用服務愈來愈複雜、被攻擊的風險也愈來愈高。為了保護Kubernetes環境的安全性,跟大家介紹一個針對Kubernetes安全合規掃描的工具,幫助確保您的 Kubernetes 叢集設置和應用程序
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News