Skip to content

antony@notes:~/kubernetes$ cat "Kubernetes-CPU-throttling.md"

Kubernetes CPU throttling

2025-04-23· kubernetes

Kubernetes CPU throttling

你必須小心設定 K8s Workload 的 CPU limit,太小的值會為你的應用程式帶來額外的、無意義的延遲,太大的值會削弱叢集的整體穩定性。

1. 先備知識

Linux 上的 CPU 是如何運作的?

就像我們的大腦,CPU 每次只能處理一件事。然而,與人腦不同的是,CPU 能以極高速度在不同任務間切換,因此給人一種「同時處理很多事情」的錯覺。

在 Linux 作業系統中,CFS(Completely Fair Scheduler)就是負責控制哪些程式可以被排入 CPU 執行、哪些必須等待的調度機制。

CFS 的工作原理是:將 CPU 的處理時間分割成極短的「時間片」(time slice),並記錄每個程式實際佔用了多少時間。它會根據這些紀錄,公平地讓每個程式輪流使用 CPU,避免某些程式佔用過多、而其他程式被忽視。

為了幫助理解這個概念,想像三個小孩睡前搶著跟爸媽說話:爸媽一次只能聽一個孩子講話,這就像 CPU 只能一次處理一項任務。此時爸媽就像 CFS,會小心且公平地輪流聆聽每個孩子,讓大家都有說話的機會,還會記住誰講得多、誰講得少,防止某個孩子講太久而忽略其他人。

如果其中兩個小孩先睡著了,爸媽就能把所有注意力放在剩下清醒的那一位身上。同樣的,如果當前只有一個程式需要 CPU,那麼它就可以獨佔所有的處理資源。

核心觀念總結:

  • CPU 雖快,但實際上一次只能做一件事
  • CFS 是 Linux 核心中控制「哪一個程式可以用 CPU」的公平調度機制
  • 它透過公平分配時間片,確保所有程式有機會執行

背景脈絡與核心概念

在伺服器或 containerized 環境中,單純用「公平分配」CPU 時間的方式(例如桌面系統所偏好的模式)已經不敷使用。原因是:

  • 某些服務(如資料庫、監控或網頁服務)比其他服務更關鍵,需要優先取得資源
  • containerized 環境常同時執行多個應用程式,若沒有資源隔離與優先級控管,會造成性能不可預期。

為了解決這個問題,Google 工程師在 2006 年開發了 Cgroups(Control Groups),並於 2008 年併入 Linux 主線核心,成為現今資源控制的關鍵基礎。

Cgroups 是什麼?

Cgroups 是 Linux 核心提供的一個機制,可用來限制、追蹤和隔離一個或多個程序的資源使用情況(如 CPU、記憶體、磁碟 I/O、網路等)。

Cgroups 的 CPU 模組允許你設定每個 container 的「share」值,CFS 在管理 CPU 時間時會考慮該值

  • 單位通常為 milliCPU(或是 millicores),1000m = 1 顆實體 CPU。
  • 若某 container 設定為 200m,代表它在資源競爭情況下會被保證至少拿到 20% 的 CPU 時間。
  • 如果沒有其他 container 需要 CPU,則可獲得高達 100% 的 CPU 時間。

2. K8s 如何套用 CPU 資源的限制?

當 kubelet 啟動 Pod 中的 container 時,它會將該 container 的記憶體與 CPU 的需求(requests)和限制(limits)資訊傳遞給 container runtime (Containerd/CRI-O…)。

在 Linux 系統中,container runtime 通常會設定在 kernel 中的 cgroups ,以應用並強制執行定義的資源限制。

以下引用來自 K8s 官網的定義與描述 :

  • The CPU limit defines a hard ceiling on how much CPU time the container can use. During each scheduling interval (time slice), the Linux kernel checks to see if this limit is exceeded; if so, the kernel waits before allowing that cgroup to resume execution.

    container 設定 CPU limit 時,這個限制會被視為 container 可使用 CPU 時間的「硬上限」。在每個 time slice(排程週期)中,Linux 核心會檢查該 container 是否已超過其限制;如果超過,核心會暫停該 container,一直等待到下一個排程週期開始,重新分配 CPU 時間後,container 才能去執行。

Kubelet 還會使用 Linux Kernel CFS(Completely Fair Scheduler,完全公平調度) 來限制 Workload 的 CPU time 的使用率,要點如下:

  • CPU 使用量的計量週期為 100ms
  • CPU limit 決定每計量週期(100ms)內 container 可以使用的 CPU 時間的上限
  • 本週期若 container 的 CPU 時間用量達到上限,CPU throttling (限流) 開始,container 只能在下個週期繼續執行
  • 1 CPU = 100 ms CPU 時間每計量週期,以此類推,0.2 CPU = 20 ms CPU 時間每計量週期,2.5 CPU = 250 ms CPU 時間每計量週期
  • 如果程式用了多個核,CPU 時間會累積統計。

cgroups 提供了資源限制與隔離的框架,而 CFS 則在此框架下,實施具體的 CPU 時間分配與調度。