CPU和內存是節點重要的資源,分配不當時可能導致容器頻繁重啟或者被驅趕,甚至導致節點宕機。特別是內存這類不可壓縮的資源。
Kubernetes 將運行的 Pod 分為不同的 QoS 類,QoS 類由 Pod 中容器的資源請求(request)和限制(limit)決定。當 Node 資源不足時,Kubernetes 會根據 QoS 類驅逐可驅逐的 Pod。此外,Pod 或因超過限制(limit)被 kubelet 終止,或因沒有限制而導致節點 OOM。
Kubernetes QoS 類有Guaranteed、Burstable、BestEffort。
Guaranteed
Guaranteed Pod 具有最嚴格的資源限制,且最不可能被驅逐。在這些 Pod 未超過其資源的limit,或沒有可從 Node 搶占的低優先級 Pod 之前,它們不會被kill。即它們只能使用其指定的資源限制。Pod 被賦予 Guaranteed QoS 類的幾個判斷:
- Pod 中的每個容器必須有 CPU 和內存的 request 和 limit
- 對于 Pod 中的每個容器,CPU 和內存的 limit 必須分別等于 CPU 和內存的 request
Burstable
Burstable Pod 具有基于請求的資源下限保證,但不需要資源限制。如果未指定資源limit,則默認為節點容量。這允許 Burstable Pod 在資源可用時靈活地增加其資源。在由于節點資源壓力導致 Pod 被驅逐的情況下,Burstable
Pod 只會在所有 BestEffort Pod 被驅逐后才會被驅逐。Burstable Pod 可以包括沒有資源 limit 或 request 的容器,因此可以嘗試使用任意數量的節點資源。
- Pod 不滿足 QoS 類 Guaranteed 的判定依據
- Pod 中至少一個容器有CPU或內存的 request 或 limit
BestEffort
BestEffort Pod 可以使用未分配給其他 QoS 類 Pod 的節點資源。在節點遇到資源壓力時,kubelet 將優先驅逐 BestEffort Pod。
- Pod 中所有的容器都沒有 CPU 和內存的 request 和 limit
場景一
節點內存超過了預留的上限,導致節點 OOMkill。
解決方法:
- 升級節點的規格
- 遷移 Pod 至其他資源充足的節點
場景二
Pod 的內存 limit 設置過低,導致容器在使用內存超過限制時觸發了OOMkill。此時,kubelet 會重啟容器,但由于內存限制仍未改變,容器將再次超過限制并被終止。這種情況會導致容器反復重啟,影響應用程序的穩定性。
解決方法:
- 擴大容器的內存 limit 設置