加速 Kubernetes 映象拉取

使用者bPEIr6發表於2022-03-13

加速 Kubernetes 映象拉取

Kubernetes pod 啟動時會拉取使用者指定的映象,一旦這個過程耗時太久就會導致 pod 長時間處於 pending 的狀態,從而無法快速提供服務。

映象拉取的過程參考下圖所示:
k8s image pull

Pod 的 imagePullPolicy 映象拉取策略有三種:

  • IfNotPresent:只有當映象在本地不存在時才會拉取。
  • Always:kubelet 會對比映象的 digest ,如果本地已快取則直接使用本地快取,否則從映象倉庫中拉取。
  • Never:只使用本地映象,如果不存在則直接失敗。

說明:每個映象的 digest 一定唯一,但是 tag 可以被覆蓋。


從映象拉取的過程來看,我們可以從以下三個方面來加速映象拉取:

  1. 縮減映象大小:
    使用較小的基礎映象、移除無用的依賴、減少映象 layer 、使用多階段構建等等。
    推薦使用 docker-slim
  2. 加快映象倉庫與 k8s 節點之間的網路傳輸速度。
  3. 主動快取映象:
    Pre-pulled 預拉取映象,以便後續直接使用本地快取,比如可以使用 daemonset 定期同步倉庫中的映象到 k8s 節點本地。

題外話 1:本地映象快取多久?是否會造成磁碟佔用問題?

本地快取的映象一定會佔用節點的磁碟空間,也就是說快取的映象越多,佔用的磁碟空間越大,並且快取的映象預設一直存在,並沒有 TTL 機制(比如說多長時間以後自動過期刪除)。

但是,k8s 的 GC 機制會自動清理掉映象。當節點的磁碟使用率達到 HighThresholdPercent 高百分比閾值時(預設 85% )會觸發垃圾回收,此時 kubelet 會根據使用情況刪除最舊的不再使用的映象,直到磁碟使用率達到 LowThresholdPercent(預設 80% )。

題外話 2:映象 layer 層數真的越少越好嗎?

我們經常會看到一些文章說在 Dockerfile 裡使用更少的 RUN 命令之類的減少映象的 layer 層數然後縮減映象的大小,layer 越少映象越小這確實沒錯,但是某些場景下得不償失。首先,如果你的 RUN 命令很大,一旦你修改了其中某一個小的部分,那麼這個 layer 在構建的時候就只能重新再來,無法使用任何快取;其次,映象的 layer 在上傳和下載的過程中是可以併發的,而單獨一個大的層無法進行併發傳輸。

相關文章