垃圾收集
垃圾收集是 Kubernetes 用於清理叢集資源的各種機制的統稱。這允許清理以下資源,例如
- 已終止的 Pod
- 已完成的工作
- 沒有擁有者參照的物件
- 未使用的容器和容器映像檔
- 具有刪除 StorageClass 回收策略的動態配置 PersistentVolumes
- 過時或過期的 CertificateSigningRequests (CSR)
- 節點 在下列情況下遭到刪除
- 在雲端上,當叢集使用 雲端控制器管理員 時
- 在內部部署上,當叢集使用類似於雲端控制器管理員的附加元件時
- 節點租約物件
擁有者與從屬
在 Kubernetes 中,許多物件透過擁有者參照連結彼此。擁有者參照會告知控制平面哪些物件依賴其他物件。Kubernetes 使用擁有者參照,讓控制平面和其他 API 用戶端有機會在刪除物件之前清理相關資源。在大多數情況下,Kubernetes 會自動管理擁有者參照。
擁有權與某些資源也使用的標籤和選擇器機制不同。例如,考慮一個 Service,它會建立 EndpointSlice
物件。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 finalizers 來控制垃圾收集如何以及何時刪除具有擁有者參照的資源。
前景串聯刪除
在前景串聯刪除中,您要刪除的擁有者物件首先進入刪除進行中狀態。在此狀態下,擁有者物件會發生以下情況:
- Kubernetes API 伺服器將物件的
metadata.deletionTimestamp
欄位設定為物件標記為刪除的時間。 - Kubernetes API 伺服器也會將
metadata.finalizers
欄位設定為foregroundDeletion
。 - 在刪除過程完成之前,物件會透過 Kubernetes API 保持可見。
在擁有者物件進入刪除進行中狀態後,控制器會刪除它知道的依賴項。在刪除所有它知道的依賴物件後,控制器會刪除擁有者物件。此時,該物件在 Kubernetes API 中不再可見。
在前景串聯刪除期間,唯一會阻止擁有者刪除的依賴項是那些具有 ownerReference.blockOwnerDeletion=true
欄位且位於垃圾收集控制器快取中的依賴項。垃圾收集控制器快取可能不包含資源型別無法成功列出/監看的物件,或與擁有者物件刪除同時建立的物件。請參閱使用前景串聯刪除以瞭解更多資訊。
背景串聯刪除
在背景串聯刪除中,Kubernetes API 伺服器會立即刪除擁有者物件,而垃圾收集器控制器(自訂或預設)會在背景中清理依賴物件。如果存在 finalizer,它可以確保在完成所有必要的清理工作之前不會刪除物件。預設情況下,Kubernetes 使用背景串聯刪除,除非您手動使用前景刪除或選擇孤立依賴物件。
請參閱使用背景串聯刪除以瞭解更多資訊。
孤立的依賴項
當 Kubernetes 刪除擁有者物件時,遺留下來的依賴項稱為孤立物件。預設情況下,Kubernetes 會刪除依賴物件。若要瞭解如何覆寫此行為,請參閱刪除擁有者物件並孤立依賴項。
未使用容器和映像檔的垃圾收集
kubelet 每五分鐘對未使用的映像檔執行垃圾收集,每分鐘對未使用的容器執行垃圾收集。您應避免使用外部垃圾收集工具,因為這些工具可能會破壞 kubelet 的行為並移除應該存在的容器。
若要設定未使用容器和映像檔垃圾收集的選項,請使用組態檔調整 kubelet,並使用 KubeletConfiguration
資源型別變更與垃圾收集相關的參數。
容器映像檔生命週期
Kubernetes 透過其映像檔管理員管理所有映像檔的生命週期,該管理員是 kubelet 的一部分,並與 cadvisor 協同運作。kubelet 在制定垃圾收集決策時會考量以下磁碟使用量限制:
HighThresholdPercent
LowThresholdPercent
高於設定的 HighThresholdPercent
值的磁碟使用量會觸發垃圾收集,這會根據映像檔上次使用的時間順序刪除映像檔,從最舊的開始。kubelet 會刪除映像檔,直到磁碟使用量達到 LowThresholdPercent
值。
未使用容器映像檔的垃圾收集
Kubernetes v1.30 [beta]
(預設啟用:true)作為 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 finalizers。
- 瞭解關於清理已完成 Job 的 TTL 控制器。