1. 程式人生 > >【轉載】深入分析Kubelet Bootstrap Checkpoint

【轉載】深入分析Kubelet Bootstrap Checkpoint

Kubelet Bootstrap Checkpoint是什麼

Kubelet Bootstrap Checkpoint是kubelet對特定的Pods的進行備份、恢復的kubelet內建模組。

  • Kubelet Bootstrap Checkpoint是對當前Node上帶有Annotation:node.kubernetes.io/bootstrap-checkpoint=true的Pods的Checkpoint到檔案系統機制。
  • 當kubelet重啟時,會檢查checkpoint目錄下各個Pods對應的checkpoint檔案,載入所有的checkpoint檔案,轉換成Pod Object,然後啟動這些Pods。

Kubelet Bootstrap Checkpoint應用場景

看起來似乎有點像static pod的使用方式:根據某個目錄下Pod的描述檔案,kubelet監控這些檔案,根據檔案的變更與否,決定是否刪除、建立、更新對應的Pods。又或者有點像DaemonSet的使用場景。

最大的不同是,Kubelet Bootstrap Checkpoint是會對特定Pods的checkpoint,如果Pods通過API發生變更或者建立,那麼最新的Pod資料會寫入到Pod對應的checkpoint檔案中,Pod對應的checkpoint檔名格式是Pod_UID.yaml,存放的內容是完整的Pod API Object的Yaml格式內容,包括Status。

Kubelet Bootstrap Checkpoint主要的應用場景:

  • self-hosted-kubernetes用來對k8s託管的apiserver,controller-manager,scheduler,kubelet,etcd,Adds-on元件進行升級、維護的場景。關於self-hosted-kubernetes的更多內容請參考self-hosted-kubernetes design-proposals,bootkube, kubeadm upgrade等都與此相關。這也是社群設計這一特性的主要動機。下圖是bootkube的原理圖。

那麼,對於使用者來說,部署普通應用時給Pod加上Annotation:node.kubernetes.io/bootstrap-checkpoint=true

來給該Pod提供bootstrap checkpoint會帶來什麼好處嗎?

對於使用者而言,如果apiserver能正常訪問,那麼bootstrap checkpoint確實沒有什麼用處,因為etcd中已經有Pods API Object資訊了,checkpoint就顯得多此一舉了。如果checkpoint檔案和etcd中資料存在不一致的情況,反而會導致Pod先通過checkpoint恢復後,很快又根據etcd中Object Info進行重建的問題。

但是,對於Node上一些特殊的常駐Agent,比如cmdb agent,需要定期上報Node的狀態等資訊,以DaemonSet Pod方式執行在Node上,如果在對Kubernetes進行升級時方式不對或者不順暢,Node系統重啟並長時間無法與apiserver進行通訊(比如apiserver升級失敗),這將導致Node上無法執行DaemonSet Pod,那麼這個Node上的cmdb agent就無法正常上報資訊。對於這種情況,如果我們給這個DaemonSet Pod設定了對應Annotation和啟用了Kubelet Bootstrap Checkpoint,那麼kubelet可以在不依賴apiserver的情況下,通過本地的checkpoint檔案恢復之前備份的Pods。

因此,給一些per-node上的關鍵使用者元件使用Bootstrap Checkpoint是有價值的。

怎麼啟用Kubelet Bootstrap Checkpoint

  • Kubelet啟動引數中配置--bootstrap-checkpoint-path,預設為“”,意味著預設Disable。

  • 給需要Bootstrap Checkpoint的Pods加上Annotation:node.kubernetes.io/bootstrap-checkpoint=true

Bootstrap Checkpoint工作機制

  • kubelet啟動時,在NerMainKubelet中會檢查--bootstrap-checkpoint-path是否不為空,如果不為空,就會建立checkpointManager。

建立或者變更Pod

  • 當用戶提交建立Pod請求後,經過scheduler排程,最後由kubelet發現排程到本節點,由kubelet開始Pod的建立流程。
  • checkpointManager不為空的情況下,kubelet會檢查Pod是都有Annotation:node.kubernetes.io/bootstrap-checkpoint=true,kubelet在HandlePodAddtions時會遍歷所有Pods,在dispatchWorker去建立Pod前,PodManager會呼叫checkpoint.WritePod介面先將滿足Annotation的Pods寫入到它們對應的checkpoint檔案(Pod_UID.yaml)中。
  • 同樣的,當Pod Spec發生變更,kubelet通過HandlePodUpdates遍歷所有Pods,由PodManager呼叫checkpoint.WritePod介面將滿足Annotation的Pods最新內容寫入到它們對應的的checkpoint檔案中。
  • 如果checkpoint.WritePod發生Error,可以在kubelet日誌中看到,但是並不會引發流程異常,也就是說,Pod還會繼續建立起來,但是checkpoint失敗。

刪除Pod

  • 當用戶提交刪除Pod請求後,kubelet通過HandlePodRemove遍歷所有Pods,由PodManager呼叫checkpoint.DeletePod介面將Pod對應的checkpoint檔案刪除。
  • 如果Pod對應的checkpoint檔案不存在,不會有異常返回,也不應該有異常返回。
  • 如果Pod對應的checkpoint檔案存在,但是刪除失敗,那麼會有kubelet Error日誌,但是流程不會失敗。

注意,這裡並不會去檢查Pod的Annotation是否滿足條件,而是對所有Pods都試圖去刪除對個格式的檔名。為什麼不先檢查Annotation呢?這樣效能不是會更高麼?試想一下這種場景,Pod的Checkpoint Annotation在變更時被刪除了,那麼他的checkpoint檔案就會被殘留。之後該Pod被刪除了,然後kubelet發生重啟時,還會從checkpoint中恢復這個已經被刪除的Pod,這很糟糕。當然,很快這個Pod會從apiserver中同步中知道已經被刪除了,然後kubelet再次刪除這個Pod.

Kubelet重啟

  • 當kubelet發生冷重啟時,會先檢查--bootstrap-checkpoint-path是否配置了,如果是,就會呼叫checkpoint.LoadPods根據配置的目錄下的所有Pod_UID.yaml格式的檔案,並通過FNV Hash演算法進行CheckSum檢查。

  • 檢查通過後,將checkpoint yaml檔案內容轉換成Pod API Object,然後把這些Pods物件通過kubetypes.PodUpdate型別的channel一直傳遞給Kubelet.syncLoopIteration,最終由dispatch給Kubelet podWorkers去建立對應的Pods例項。

Bootstrap Checkpoint工作流

Bootstrap Checkpoint的程式碼很簡單,也不多,這裡直接貼出對應的程式碼流程概要圖。

其他注意事項

  • 目前Bootstrap Checkpoint只是對本節點的特定Pods進行Checkpoint,並不包括其他Kubernetes Object的Checkpoint。
  • 更不是對kubelet記憶體資料的Checkpoint。這些都不是它想做的事,更不是應該做的事,叢集狀態儲存的地方越多,問題就會越多。

總結

本文對Kubelet Bootstrap Checkpoint的使用方法、應用場景、工作機制及其程式碼工作流程進行了全面分析,目前仍處於Alpha階段,不確定性較大,但值得持續的關注它在self-hosted kubernetes, kubeadm upgrade, bootkube等方向的應用,相信Kubernetes的部署和升級還會變的更加簡單。

本文轉載自:https://my.oschina.net/jxcdwangtao/blog/2960614