您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關OpenKruise如何實現 K8s 社區首個規模化鏡像預熱能力,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
“鏡像” 也算是 Docker 為容器領域帶來的一大創新。在 Docker 之前,雖然 Linux 已經提供了 cgroup 隔離,盡管阿里巴巴從 2011 年已經逐漸基于 LXC 開始容器化,但都缺乏鏡像這種對運行環境的封裝。不過呢,盡管鏡像為我們帶來了諸多好處,但不可否認在實際場景中我們也面臨各種各樣拉鏡像帶來的問題,其中最常見的一點就是拉鏡像的耗時。
我們過去聽到過很多用戶對容器化的期待和認識,比如 “極致彈性”、“秒級擴容”、“高效發布” 等等,但結合 Kubernetes 中一個標準的 Pod 創建過程來看,和用戶的期望還是有一定差距的(假設 Pod 中包含 sidecar、app 兩個容器):
正常來說,對于小規模集群中調度、分配/掛載遠程盤、分配網絡等操作耗時較小,對于大規模集群需要做一定優化,但都還在可控的范圍內。然而對于拉鏡像的耗時,在大規模彈性的集群中則尤為棘手,即使采用了 P2P 等技術手段來優化,對于一個較大的業務鏡像還是可能需要較長的時間來拉取,與用戶所期望的擴容、發布速度不符。
而我們如果能做到將 sidecar 容器的鏡像、以及業務容器的基礎鏡像提前在節點上拉取好,則 Pod 創建過程可以大幅縮短,其中拉鏡像的耗時甚至能優化 70% 以上:
而 Kubernetes 自身是沒有提供任何面向鏡像的操作能力的,圍繞 Kubernetes 的生態來看,目前也沒有比較成熟的規模化鏡像預熱產品。這是我們在 OpenKruise 中提供鏡像預熱的原因,并且這套鏡像預熱能力已經在阿里巴巴內部的云原生環境大面積落地,在后文的實踐中也會簡單介紹我們的基本用法。
OpenKruise 實現鏡像預熱的原理,要先從它的運行架構看起:
從 v0.8.0 開始,安裝了 Kruise 之后,有兩個在 kruise-system 命名空間下的組件:kruise-manager 與 kruise-daemon。前者是一個由 Deployment 部署的中心化組件,一個 kruise-manager 容器(進程)中包含了多個 controller 和 webhook;后者則由 DaemonSet 部署到集群中的節點上,通過與 CRI 交互來繞過 Kubelet 完成一些擴展能力(比如拉取鏡像、重啟容器等)。
因此,Kruise 會為每個節點(Node)創建一個同名對應的自定義資源:NodeImage,而每個節點的 NodeImage 里寫明了在這個節點上需要預熱哪些鏡像,因此這個節點上的 kruise-daemon 只要按照 NodeImage 來執行鏡像的拉取任務即可:
如上圖所示,我們在 NodeImage 中能指定要拉取的鏡像名、tag、拉取的策略,比如單次拉取的超時、失敗重試次數、任務的 deadline、TTL 時間等等。
有了 NodeImage,我們也就擁有了最基本的鏡像預熱能力了,不過還不能完全滿足大規模場景的預熱需求。在一個有 5k 個節點的集群中,要用戶去一個個更新 NodeImage 資源來做預熱顯然是不夠友好的。因此,Kruise 還提供了一個更高抽象的自定義資源 ImagePullJob:
如上圖所示,在 ImagePullJob 中用戶可以指定一個鏡像要在哪些范圍的節點上批量做預熱,以及這個 job 的拉取策略、生命周期等。一個 ImagePullJob 創建后,會被 kruise-manager 中的 imagepulljob-controller 接收到并處理,將其分解并寫入到所有匹配節點的 NodeImage 中,以此來完成規模化的預熱。
整體的流程如下:
而有了鏡像預熱能力后,我們怎么去使用它,或者說什么場景下需要來使用呢?接下來我們介紹下鏡像預熱在阿里巴巴中的幾種常見使用方式。
最常見的預熱場景,是在整個集群維度持續預熱一些基礎鏡像:
apiVersion: apps.kruise.io/v1alpha1 kind: ImagePullJob metadata: name: base-image-job spec: image: xxx/base-image:latest parallelism: 10 completionPolicy: type: Never pullPolicy: backoffLimit: 3 timeoutSeconds: 300
如上述 ImagePullJob 有幾個特征:
不配置 selector 規則,即默認整個集群維度預熱
存量的節點上統一預熱
后續新增(導入)的節點上也會立即自動做預熱
采用 Never 的 completionPolicy 策略來長期運行
Never 策略表明這個 job 持續做預熱,不會結束(除非被刪除)
Never 策略下,ImagePullJob 每隔 24h 左右會觸發在所有匹配的節點上重試拉取一次,也就是每天都會確保一次鏡像存在
根據我們的經驗,一個集群中預熱基礎鏡像的 ImagePullJob 在 10~30 個左右,具體視集群以及業務場景而定。
我們同樣也可以對一些 sidecar 的鏡像做預熱,尤其是那些基本上每個業務 Pod 中都會帶有的基礎 sidecar:
apiVersion: apps.kruise.io/v1alpha1 kind: ImagePullJob metadata: name: sidecar-image-job spec: image: xxx/sidecar-image:latest parallelism: 20 completionPolicy: type: Always activeDeadlineSeconds: 1800 ttlSecondsAfterFinished: 300 pullPolicy: backoffLimit: 3 timeoutSeconds: 300
如上述 ImagePullJob 有幾個特征:
不配置 selector,默認整個集群維度預熱,這一點與基礎鏡像類似
采用 Always 策略一次性預熱
所有節點做一次預熱
整個 job 預熱超時時間 30min
job 完成后過 5min 自動刪除
當然,這里的 sidecar 預熱也可以配置為 Never 策略,視場景而定。以我們的經驗來看,尤其在 sidecar 做版本迭代、鏡像升級的時候,提前做一次規模化的鏡像預熱,可以大幅提升后續 Pod 擴容、發布的速度。
對于一些多租的 Kubernetes 集群中會存在多個不同的業務資源池,其中可能需要將一些特定的業務鏡像按資源池維度來預熱:
apiVersion: apps.kruise.io/v1alpha1 kind: ImagePullJob metadata: name: serverless-job spec: image: xxx/serverless-image:latest parallelism: 10 completionPolicy: type: Never pullPolicy: backoffLimit: 3 timeoutSeconds: 300 selector: matchLabels: resource-pool: serverless
如上述 ImagePullJob 有幾個特征:
采用 Never 策略長期預熱
指定 selector 預熱范圍,是匹配 resource-pool=serverless 標簽的節點
當然,這里只是以資源池為例,用戶可以根據自身的場景來定義在哪些節點上預熱某種鏡像。
最后,再來介紹下 OpenKruise 的下個版本(v0.9.0)中,我們會基于當前的鏡像預熱實現怎樣的增強能力呢?
之前對 OpenKruise 了解過的同學一定知道,我們提供的一大特性就是 “原地升級”,即打破了 Kubernetes 原生 workload 發布時必須將 Pod 刪除、重建的模式,支持在原 Pod 上只更新其中某個容器的鏡像。對原地升級原理感興趣的同學可以讀這篇文章:《揭秘:如何為 Kubernetes 實現原地升級?》。
由于原地升級避免了 Pod 刪除、重建的過程,它本身已經能為我們帶來了如下的好處:
節省了調度的耗時,Pod 的位置、資源都不發生變化
節省了分配網絡的耗時,Pod 還使用原有的 IP
節省了分配、掛載遠程盤的耗時,Pod 還使用原有的 PV(且都是已經在 Node 上掛載好的)
節省了大部分拉取鏡像的耗時,因為節點上已經存在了應用的舊鏡像,當拉取新版本鏡像時只需要下載少數的幾層 layer
原地升級 Pod 中某個容器時,其他容器保持正常運行,網絡、存儲均不受影響
其中,“節省了大部分拉取鏡像的耗時” 后,只需要下載新鏡像上層的部分 layer 即可。而我們有沒有可能把這個鏡像拉取時間徹底優化掉呢?答案是肯定的。
如上圖所示,在下個版本中 OpenKruise 的 CloneSet 將支持發布過程自動鏡像預熱。當用戶還在灰度升級第一批 Pod 的時候,Kruise 會提前在后續 Pod 所在節點上把新版本的鏡像預熱好。這樣一來,在后續批次的 Pod 做原地升級時候,新鏡像都已經在節點上準備好了,也就節省了真正發布過程中的拉鏡像耗時。
當然,這種 “發布+預熱” 的模式也只適用于 OpenKruise 的原地升級場景。對于原生 workload 如 Deployment 而言,由于發布時 Pod 是新建出來的,我們無法提前預知到它會被調度到的節點,自然也就沒辦法提前把鏡像預熱好了。
關于OpenKruise如何實現 K8s 社區首個規模化鏡像預熱能力就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。