圖解kubernetes資源擴展機制實現(下)

昨天咱們介紹了k8s中資源插件機制的核心關鍵組件,今天咱們繼續來看下各個組件是如何進行通訊的,以及k8s中針對事件處理背後的關鍵設計後端

1.PluginManager

PluginManager是一個上層組件,其內部包含了上篇文章中的關鍵組件,而且協調其內部數據流,並且還提供針對不一樣插件的具體的控制器 image.pngapi

1.1 核心數據結構

核心結構裏面其實就是按照數據流來進行設計的,首先須要一個感知插件desiredStateOfWorldPopulator用於感知後端服務的建立或者刪除,而後將感知到的事件加入到desiredStateOfWorld指望狀態緩存,由reconciler負責期進行底層的註冊和下線,而且將結果存儲到actualStateOfWorld實際狀態緩存緩存

type pluginManager struct {
	// 插件感知
	desiredStateOfWorldPopulator *pluginwatcher.Watcher

    // 協調器插件
	reconciler reconciler.Reconciler

    // 實際狀態緩存
	actualStateOfWorld cache.ActualStateOfWorld
	// 指望狀態緩存
	desiredStateOfWorld cache.DesiredStateOfWorld
}

1.2 初始化

初始化中會將dsw和asw都交給reconciler用於進行事件的感知和更新對應的緩存微信

func NewPluginManager(
	sockDir string,
	recorder record.EventRecorder) PluginManager {
	asw := cache.NewActualStateOfWorld()
	dsw := cache.NewDesiredStateOfWorld()
    // 這裏會將指望狀態緩存和實際狀態緩存,都交給reconciler
	reconciler := reconciler.NewReconciler(
		operationexecutor.NewOperationExecutor(
			operationexecutor.NewOperationGenerator(
				recorder,
			),
		),
		loopSleepDuration,
		dsw,
		asw,
	)

	pm := &pluginManager{
        //  啓動一個watcher而且存儲dsw指望狀態緩存,後續reconciler就能夠經過dsw感知到新的狀態了
		desiredStateOfWorldPopulator: pluginwatcher.NewWatcher(
			sockDir,
			dsw,
		),
		reconciler:          reconciler,
		desiredStateOfWorld: dsw,
		actualStateOfWorld:  asw,
	}
	return pm
}

1.3 啓動插件管理器

插件管理器啓動其實就是啓動內部的desiredStateOfWorldPopulator就會講watcher感知的事件,不斷的修改本身的內部緩存這樣reconciler就能夠不斷的經過指望狀態緩存,進行對應grpc的調用從而知足指望狀態數據結構

func (pm *pluginManager) Run(sourcesReady config.SourcesReady, stopCh <-chan struct{}) {
	defer runtime.HandleCrash()

    // 運行指望狀態緩存,其實主要是經過watcher感知到的事件,修改自身的緩存
    // 後續reconciler會週期性的獲取
	pm.desiredStateOfWorldPopulator.Start(stopCh)
	klog.V(2).Infof("The desired_state_of_world populator (plugin watcher) starts")

	klog.Infof("Starting Kubelet Plugin Manager")
    // 週期性的運行校證數據
	go pm.reconciler.Run(stopCh)

	metrics.Register(pm.actualStateOfWorld, pm.desiredStateOfWorld)
	<-stopCh
	klog.Infof("Shutting down Kubelet Plugin Manager")
}

1.4 控制器註冊

控制器其實主要是指的reconciler經過對比指望緩存和實際緩存之間的差別,產生對應的事件以後,針對該類型的插件,後續的處理流程是什麼,好比註冊/下線具體的grpc接口和對應插件類型的處理機制ide

func (pm *pluginManager) AddHandler(pluginType string, handler cache.PluginHandler) {
	pm.reconciler.AddHandler(pluginType, handler)
}

1.5 CSI與普通設備

當前的kubelet中有註冊兩種類型的插件控制器,CSI與DEVICPLUGIn,從名字上你們也能知道大概的意思oop

kl.pluginManager.AddHandler(pluginwatcherapi.CSIPlugin, plugincache.PluginHandler(csi.PluginHandler))
	kl.pluginManager.AddHandler(pluginwatcherapi.DevicePlugin, kl.containerManager.GetPluginRegistrationHandler())

2. PluginHandler

這裏咱們只介紹一個即DevicePlugin的核心實現機制 image.png源碼分析

2.1 Endpoint

Endpoint其實指的就是某個提供擴展資源的服務,在以前說的reconciler中,會獲取其對應的grpc服務的地址,後續則會直接調用grpc進行通訊ui

Endpoint須要感知對應的資源設備的變化,同時將對應的設備信息,回調通知給當前的插件

2.2 Manager

Manager則是主要負責實現後端真正的Register/UnRegister的具體實現,其在內部會爲每一個Device建立一個Endpoint並負責收集後端提供資源服務上報上來的信息, 最終會講對應的信息發送給kubelet,而後由kubelet在負責節點信息更新的時候,將信息傳遞給APIServer

2.3 Checkpoint

Checkpoint機制其實在不少系統中都比較經常使用,主要是用於週期性的將內存中的數據序列化存儲到本地的磁盤中,在後續恢復的時候,會經過磁盤從新加載以前的數據,從而實現內存資源的快速恢復

擴展資源的總體實現流程大概就是這個樣子,從如何感知數據,註冊資源服務,獲取資源服務的資源信息,並最終彙報給kubelet,同時落地本地磁盤,實現了完整的資源從感知到上報的總體流程的探測,其不足主要是在於關於資源實體的描述,從而致使資源的分配和資源的上報上有比較大的擴展性限制,好比要實現精細化的資源分配擴展,則不太能實現

k8s源碼閱讀電子書地址: https://www.yuque.com/baxiaoshi/tyado3

> 微信號:baxiaoshi2020 > 關注公告號閱讀更多源碼分析文章 21天大棚 > 更多文章關注 www.sreguide.com > 本文由博客一文多發平臺 OpenWrite 發佈

相關文章
相關標籤/搜索