本文將詳細介紹 Kubernetes 如何管理節點上的映象。
拉取映象
Kubelet
透過 gRPC 協議與 CRI
元件(如 containerd
、cri-o
)進行互動。在建立新 Pod 時,kubelet
呼叫 gRPC 的 ImageService.PullImage
方法,由 CRI
元件將映象下載到節點上。映象在磁碟上的組織和管理由 CRI
元件負責,不同的 CRI 元件存在差異。
Containerd
的配置檔案預設為 /etc/containerd/config.toml
,其中的配置項 root=/var/lib/containerd/
指定了儲存路徑(這是一個根目錄,內部會再細分子目錄)。
Cri-o
儲存相關的配置檔案則是 /etc/containers/storage.conf
,其中的配置項 root=/var/lib/containers/storage
指定儲存路徑,另外存在一個配置項 imagestore
可以單獨指定映象的儲存位置。
Image GC
Kubelet
透過垃圾回收策略來管理映象的刪除,相關的配置項包括:
imageMinimumGCAge
:預設值為 2 分鐘,表示映象的最小存在時間,避免在垃圾回收時刪除過於新的映象。imageMaximumGCAge
:預設值為 0 秒(表示不開啟此特性),表示映象的最大存在時間(此特性在 v1.30 中引入)。如果映象自上次使用以來的時間超過此值,該映象將被刪除。imageGCHighThresholdPercent
:預設值是 85,當磁碟的使用率大於等於 85%,觸發映象的垃圾回收。imageGCLowThresholdPercent
:預設值是 80,映象垃圾回收過程中,一旦磁碟使用率小於等於 80%,則停止刪除映象。
Kubelet
每隔 5 分鐘(這個值在程式碼中寫死了),不停的迴圈以下對映象的 GC 過程:
imagesInEvictionOrder
:kubelet 向 CRI 發起ImageService.ListImages
、RuntimeService.ListPodSandbox
、RuntimeService.ListContainers
三個 gRPC 請求,以獲取該節點上所有映象的使用資訊,並按上次使用時間排序。freeOldImages
:如果映象從上一次使用至今的時間間隔超過了imageMaximumGCAge
,kubelet 會向 CRI 發起ImageService.RemoveImage
請求,刪除這些映象。ImageFsStats
:kubelet 發 CRI 發起ImageService.ImageFsInfo
請求(cri-o 依賴於 cadvisor),以獲取磁碟使用情況。freeSpace
:當磁碟使用率大於等於imageGCHighThresholdPercent
高水位線時,觸發映象的刪除行為,映象會按照時間順序從最久未被使用開始,一個接一個被刪除,每刪除完一個映象都會判斷一次磁碟使用率是否小於等於imageGCLowThresholdPercent
低水位線,一旦降至低水位線,則停止刪除映象。
總結
在 node 節點上,映象由 CRI
元件(如 containerd
、cri-o
)管理。kubelet 每 5 分鐘進行一次映象的垃圾回收。如果配置了 imageMaximumGCAge
映象的最大存在時間,則不管磁碟使用率是否達到高水位線,都會刪除符合條件的映象。之後,映象的刪除將依據 imageGCHighThresholdPercent
、imageGCLowThresholdPercent
高低水位線的配置來觸發,具體刪除操作由 CRI 元件執行,而 kubelet 僅負責發起 gRPC 呼叫。
(關注我,無廣告,專注技術,不煽動情緒,也歡迎與我交流)
參考資料:
- https://kubernetes.io/docs/concepts/architecture/garbage-coll...
- https://kubernetes.io/docs/reference/config-api/kubelet-confi...
- https://github.com/containerd/containerd/blob/main/docs/ops.md
- https://github.com/cri-o/cri-o/blob/main/docs/crio.conf.5.md
- https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/images/image_gc_manager.go