垃圾回收
垃圾回收是 Kubernetes 用於清理叢集資源的各種機制的統稱。它允許清理以下資源:
- 已終止的 Pod
- 已完成的 Job
- 沒有屬主引用的物件
- 未使用的容器和容器映象
- StorageClass 回收策略為 Delete 的動態製備 PersistentVolume
- 過期或失效的 CertificateSigningRequest(CSR)
- 在以下場景中刪除的節點
- 叢集使用雲控制器管理器時的雲環境
- 叢集使用類似於雲控制器管理器的附加元件時的本地環境
- 節點租約物件
屬主和依賴項
Kubernetes 中的許多物件透過**屬主引用**相互關聯。屬主引用告訴控制平面哪些物件依賴於其他物件。Kubernetes 使用屬主引用讓控制平面和其他 API 客戶端有機會在刪除物件之前清理相關資源。在大多數情況下,Kubernetes 會自動管理屬主引用。
屬主引用與某些資源也使用的標籤和選擇器機制不同。例如,考慮一個建立 `EndpointSlice` 物件的Service。該 Service 使用**標籤**讓控制平面確定哪些 `EndpointSlice` 物件用於該 Service。除了標籤之外,代表 Service 管理的每個 `EndpointSlice` 都包含一個屬主引用。屬主引用有助於 Kubernetes 的不同部分避免干擾它們不控制的物件。
注意
跨名稱空間屬主引用是設計上不允許的。名稱空間依賴項可以指定叢集範圍或名稱空間範圍的屬主。名稱空間屬主**必須**與依賴項存在於同一名稱空間中。如果不存在,則該屬主引用被視為不存在,一旦所有屬主都被驗證為不存在,依賴項就會被刪除。
叢集範圍的依賴項只能指定叢集範圍的屬主。在 v1.20+ 中,如果叢集範圍的依賴項指定了名稱空間種類作為屬主,則會被視為具有無法解析的屬主引用,並且無法進行垃圾回收。
在 v1.20+ 中,如果垃圾回收器檢測到無效的跨名稱空間 `ownerReference`,或者叢集範圍的依賴項的 `ownerReference` 引用了名稱空間種類,則會報告一個警告事件,其原因為 `OwnerRefInvalidNamespace`,`involvedObject` 為無效的依賴項。你可以透過執行 `kubectl get events -A --field-selector=reason=OwnerRefInvalidNamespace` 來檢查此類事件。
級聯刪除
Kubernetes 會檢查並刪除不再具有屬主引用的物件,例如刪除 ReplicaSet 時留下的 Pod。當你刪除一個物件時,你可以控制 Kubernetes 是否自動刪除該物件的依賴項,這個過程稱為**級聯刪除**。級聯刪除有兩種型別,如下所示:
- 前臺級聯刪除
- 後臺級聯刪除
你還可以使用 Kubernetes 終結器來控制垃圾回收如何以及何時刪除具有屬主引用的資源。
前臺級聯刪除
在前臺級聯刪除中,你正在刪除的屬主物件首先進入**刪除進行中**狀態。在此狀態下,屬主物件會發生以下情況:
- Kubernetes API 伺服器將物件的 `metadata.deletionTimestamp` 欄位設定為物件被標記為刪除的時間。
- Kubernetes API 伺服器還將 `metadata.finalizers` 欄位設定為 `foregroundDeletion`。
- 物件在刪除過程完成之前透過 Kubernetes API 可見。
在屬主物件進入**刪除進行中**狀態後,控制器會刪除它知道的所有依賴項。刪除所有它知道的依賴物件後,控制器會刪除屬主物件。此時,該物件在 Kubernetes API 中不再可見。
在前臺級聯刪除期間,唯一阻止屬主刪除的依賴項是那些具有 `ownerReference.blockOwnerDeletion=true` 欄位且位於垃圾回收控制器快取中的物件。垃圾回收控制器快取可能不包含無法成功列出/監視其資源型別的物件,或者與屬主物件的刪除同時建立的物件。有關更多資訊,請參閱使用前臺級聯刪除。
後臺級聯刪除
在後臺級聯刪除中,Kubernetes API 伺服器會立即刪除屬主物件,垃圾回收器控制器(自定義或預設)會在後臺清理依賴物件。如果存在終結器,它會確保在所有必要的清理任務完成之前不會刪除物件。預設情況下,除非你手動使用前臺刪除或選擇孤立依賴物件,否則 Kubernetes 會使用後臺級聯刪除。
有關更多資訊,請參閱使用後臺級聯刪除。
孤立依賴項
當 Kubernetes 刪除一個屬主物件時,留下的依賴項稱為**孤立**物件。預設情況下,Kubernetes 會刪除依賴物件。要了解如何覆蓋此行為,請參閱刪除屬主物件並孤立依賴項。
未使用的容器和映象的垃圾回收
kubelet 每五分鐘對未使用的映象執行一次垃圾回收,每分鐘對未使用的容器執行一次垃圾回收。你應該避免使用外部垃圾回收工具,因為這些工具可能會破壞 kubelet 的行為並刪除應該存在的容器。
要配置未使用的容器和映象垃圾回收的選項,請使用配置檔案調整 kubelet,並使用 `KubeletConfiguration` 資源型別更改與垃圾回收相關的引數。
容器映象生命週期
Kubernetes 透過其**映象管理器**(kubelet 的一部分)與 cadvisor 協作管理所有映象的生命週期。kubelet 在做出垃圾回收決策時會考慮以下磁碟使用限制:
HighThresholdPercent
LowThresholdPercent
磁碟使用量超過配置的 `HighThresholdPercent` 值會觸發垃圾回收,垃圾回收會根據映象最後使用的時間順序刪除映象,從最舊的開始。kubelet 會刪除映象,直到磁碟使用量達到 `LowThresholdPercent` 值。
未使用的容器映象的垃圾回收
作為 Beta 功能,你可以指定本地映象可以不使用多長時間,無論磁碟使用情況如何。這是一個 kubelet 設定,你可以在每個節點上進行配置。
要配置此設定,你需要為 kubelet 配置檔案中的 `imageMaximumGCAge` 欄位設定一個值。
該值被指定為 Kubernetes 持續時間。有關詳細資訊,請參閱詞彙表中的持續時間。
例如,你可以將配置欄位設定為 `12h45m`,這意味著 12 小時 45 分鐘。
注意
此功能不跟蹤 kubelet 重啟後的映象使用情況。如果 kubelet 重啟,跟蹤的映象年齡會重置,導致 kubelet 在根據映象年齡進行垃圾回收之前,等待完整的 `imageMaximumGCAge` 持續時間。容器垃圾回收
kubelet 根據你可以定義的以下變數對未使用的容器進行垃圾回收:
- `MinAge`:kubelet 可以垃圾回收容器的最小年齡。透過設定為 `0` 停用。
- `MaxPerPodContainer`:每個 Pod 最多可以擁有的死容器數量。透過設定為小於 `0` 停用。
- `MaxContainers`:叢集最多可以擁有的死容器數量。透過設定為小於 `0` 停用。
除了這些變數之外,kubelet 還會垃圾回收未識別和已刪除的容器,通常從最舊的開始。
在保留每個 Pod 的最大容器數量 (`MaxPerPodContainer`) 會超出全域性死容器的總允許數量 (`MaxContainers`) 的情況下,`MaxPerPodContainer` 和 `MaxContainers` 可能會相互衝突。在這種情況下,kubelet 會調整 `MaxPerPodContainer` 以解決衝突。最壞的情況是將 `MaxPerPodContainer` 降級為 `1` 並驅逐最舊的容器。此外,屬於已刪除 Pod 的容器在超過 `MinAge` 後也會被刪除。
注意
kubelet 只會垃圾回收它管理的容器。配置垃圾回收
你可以透過配置管理這些資源的控制器的特定選項來調整資源的垃圾回收。以下頁面向你展示如何配置垃圾回收:
下一步
- 瞭解更多關於Kubernetes 物件的屬主關係。
- 瞭解更多關於 Kubernetes 終結器。
- 瞭解清理已完成 Job 的 TTL 控制器。