本節全部的代碼基於1.13.4版本。緩存
在kubernetes中,與存儲相關的controller主要由三種:
一、AttachDetachController,簡稱AD Controller,主要處理真實的與volume相關的操做;
二、PersistentVolumeBinderController,其實就是PV Controller,主要負責pv和pvc的生命週期以及狀態的切換;
三、VolumeExpandController,主要負責volume的擴容操做。
oop
首先追蹤PersistentVolumeBinderController方法,直接進入其Run方法。 插件
進入resync,代碼很簡單,以下: code
volumeWorker經過for循環,不停獲取resync緩衝的隊列信息,對pv,即volume作相應的更新操做。主要實現方法updateVolume
cdn
updateVolume
方法,主要調用
syncVolume
方法,這個方法是整個volumeWorker的核心。工做流程以下:
Available
;
Available
;Released
且不爲Failed
,更新PV狀態爲Released
,按照配置的回收策略執行pv的回收(調用reclaimVolume
方法);Bound
;claimWorker的工做流程和volumeWorker相似,核心調用方法爲updateClaim-->syncClaim
,主要處理的是pvc生命週期中的各類狀態:Pending、Bound以及Lost。不作過多贅述。
blog
PersistentVolumeBinderController的執行流程很清晰,依賴三個goroutine的協做,分別處理數據的獲取、pv的生命週期的狀態更新和pvc的生命週期的狀態更新。整個邏輯中,沒有對具體的volume作操做,更新的僅僅是kubernetes中定義的pv和pvc資源的信息,說白了就是etcd中的數據。具體幹活的主要仍是AttachDetachController,即AD Controller。接口
首先由Run
方法進入AD Controller的啓動方法,以下: 生命週期
populateActualStateOfWorld
方法獲取Node上Volume的信息;
populateDesiredStateOfWorld
方法獲取Pod須要對應的Volume信息;
reconciler.Run
負責檢查掛載狀態,判斷是否須要掛載或卸載(真正幹活的);
desiredStateOfWorldPopulator.Run
同步Pod與Volume的掛載信息,相應信息輸送給
reconciler.Run
使用;
pvcWorker
控制pvc的流控;
metrics
中,供Prometheus採集數據使用。
populateActualStateOfWorld
方法主要處理的是Node與Volume之間的關係,主要做用是將Node Volume當前的狀態存入到actualStateOfWorld
中。主要方法以下: 隊列
attached
的Volume,分別置於已經attached狀態和
in-user
狀態,將Volume信息添加到
actualStateOfWorld
中,並將Node添加到
desiredStateOfWorld
中。
actualStateOfWorld
和
desiredStateOfWorld
的數據會在
reconciler.Run
使用。
populateDesiredStateOfWorld
方法主要處理的是Pod與Volume之間的關係,主要做用是將Pod Volume指望的狀態添加到desiredStateOfWorld
中去。和populateActualStateOfWorld
相似,主要就是針對Volume作標記操做,並將相應的Pod信息緩存到desiredStateOfWorld
中或者從desiredStateOfWorld
中剔除不匹配的Pod信息。事件
desiredStateOfWorldPopulator.Run
方法經過不停的循環,調用findAndAddActivePods
方法,經過獲取全部的Pod,判斷是否須要添加到desiredStateOfWorld
中去。
前面幾步主要的目的是爲了獲取Node Volume和Pod Volume的狀態。其中,Node上的Volume是已經存在的,故稱做爲actualStateOfWorld
,而Pod Volume是最終須要生效的資源,故稱之爲desiredStateOfWorld
。reconciler.Run
的做用就是經過不停獲取actualStateOfWorld
和desiredStateOfWorld
狀態,將Pod與Volume置於相對應的狀態,保證磁盤的最終掛載成功或者卸載成功。主要方法以下:
reconciliationLoopFunc
方法。
reconcile
方法,這是真正幹活的地方。
reconcile
使用了三個大的for循環,處理三類事件:
UnmountVolume
方法最終調用後臺存儲的解綁接口;
/dev/xx
等。Mount操做包含了MountDevice和Mount兩部分,其中,MountDevice將生成的卷標掛載成Node的路徑,通常在
/var/lib/kubelet/xx/kubernetes.io/xx
下,依賴於不一樣的存儲,Mount最終將MountDevice生成的路徑和Pod須要使用的路徑Mount起來,通常路徑爲
/var/lib/kubelet/pods/xx/volumes/xx
。
sync
方法主要完成Volume的後續操做。若是Volume未被成功綁定,將Volume進行重建或者解綁操做。
Kubernetes在1.8開始支持卷的擴容操做,1.11功能已經處於Beta階段。主要代碼以下:
pvcPopulator.Run
監聽PVC的變化,只要PVC中Request字段的Storage值比Status中的大,即表示PVC容量發生了變化,須要擴容。此時,將相應的PV和PVC的信息緩存到
resizeMap
中去。以下:
syncResize
則是不停獲取
resizeMap
中的數據,若是有變化,則調用
ExpandVolume
方法生成擴展動做,完成磁盤的擴容和PV、PVC的狀態更新操做。代碼以下:
Kubernetes的存儲主要針對Node、Pod、PV以及PVC四類資源。經過獲取Node上Volume狀態,將其與Pod中的Volume進行綁定,完成卷的加載。最終的綁定或者解綁等操做依賴的是後臺的存儲,包括內置的開源存儲插件或者本身實現的插件(FlexVolume或者CSI)。
在kubelet中,同時存在VolumeManager
去管理其節點上的Volume資源信息,基本功能與AD Controller一致。能夠經過kube-controller-manager的--disable-attach-detach-reconcile-sync
參數或者kubelet的--enable-controller-attach-detach
參數控制是由kube-controller-manager執行volume的attach/detach操做仍是kubelet執行相應的操做。