圖解kubernetes中的api多版本中反序列化與轉換

在以前的文章中分析過kubernetes是如何進行多版本管理中提到了一個關鍵的設計解碼器, 負責將請求對象反序列化成一個具體的數據模型,今天一塊兒來了解下其內部是如何實現多版本管理、轉換的設計要點web

1.版本化管理的關鍵設計

1.1 從拓撲轉換到星狀轉換

在一般的web開發中更多的時候,你們都是斷代向前兼容更新,大多數狀況下當版本更新以後會獨立演進,若是要在多版本之間轉換一般則會出現以下的狀況 image.png 若是咱們要爲每一個版本都去適配其餘全部的版本,則複雜度會指數級上升,而在kubernetes中則經過一個內部版本的設計來進行解決,內部版本是一個穩定的版本,全部的版本都只針對目標版原本進行轉換的實現,而不關注其餘版本數組

1.2 兼容設計之轉換

image.png 那若是謀個版本須要獨立的演進,或者增設一些新的字段,修改字段名稱等破壞性更新的時候,則就須要一種轉換機制,負責在當前版本和內部版本之間來進行字段或者數據的轉換微信

1.3 轉換的最終之反射

image.png 轉換其實核心目標是完成從目標對象的字段中獲取數據,而後通過一系列操做最終爲目標對象的對應的字段進行賦值操做,要完成該操做,則就須要藉助反射來實現,經過枚舉字段,來獲取對應的轉換函數,執行轉換函數,完成目標賦值數據結構

2. 關鍵設計的實現

爲了實現上面的方案,kubernetes中設計了以下組件:Scheme(負責各個版本的註冊和管理)、Convert(轉換實現)、Serializer(實現對應版本的反序列化),讓咱們依次看下其關鍵設計ide

2.1 Convert

image.png

Convert實現從一個目標對象到另一個目標對象的轉換, 爲了實現這種轉換,kubernetes裏面主要是藉助反射和不一樣版本的轉換函數來共同完成函數

1.首先咱們經過目標函數來獲取對應的屬性字段,而後針對該字段進行計算賦值操做 2.若是發現對應的字段須要來轉換,則會調用對應的轉換函數來進行賦值操做,若是不須要轉換則會直接經過反射來進行賦值源碼分析

2.2 外部版本到內部版本的轉換

image.png 在構建rest接口的時候,每一個rest接口都會持有一個生成當前版本對象的構造函數,當請求進入以後,會首先經過目標版本獲取對應的decoder decoder會利用當前的GroupVersionKind來進行第一步解析,首先將字節數組解析成當前版本,而後在解析成目標對象以後,又會根據目標版本進行轉換學習

2.3 Scheme

image.png Scheme負責各個資源版本的統一註冊和管理,爲其餘組件提供根據GVK來獲取對應的資源對象,也提供經過資源對象獲取版本等操做,內部還持有convert對象,包裝了源對象到目標對象的轉換操做ui

Scheme對象是一個複合的數據結構,其實現了多種結果,諸如typer、defaulter、creater等,不少地方都是經過直接傳遞scheme來進行對應的參數的填充, 其內部關鍵數據結構以下設計

GVK與資源類型的映射,以及當前資源類型支持哪些GVK

gvkToType map[schema.GroupVersionKind]reflect.Type

	typeToGVK map[reflect.Type][]schema.GroupVersionKind

則建立對象的時候能夠直接經過New來實例化對應的對象

func (s *Scheme) New(kind schema.GroupVersionKind) (Object, error) {
	if t, exists := s.gvkToType[kind]; exists {
		// 利用反射來建立對象
		return reflect.New(t).Interface().(Object), nil
	}
	// 省略相關代碼
}

默認初始化函數

defaulterFuncs map[reflect.Type]func(interface{})

根據對應的類型來完成初始化操做

func (s *Scheme) Default(src Object) {
	if fn, ok := s.defaulterFuncs[reflect.TypeOf(src)]; ok {
		fn(src)
	}
}

提供轉換函數註冊接口, 註冊到convert中

func (s *Scheme) AddConversionFunc(a, b interface{}, fn conversion.ConversionFunc) error {
	return s.converter.RegisterUntypedConversionFunc(a, b, fn)
}

3.學習總結

image.png 實現上無疑是複雜的做爲一個工業設計有不少須要care的邊緣狀況,剖絲抽繭每一個人看到的都不同,這可能就是源碼閱讀的樂趣,從上面能夠看到核心其實就三個點:將HTTP數據反序列化成爲當前URL的資源對象,而後目標資源對象進行初始化默認值函數的執行,最後經過convert來處理不一樣版本之間的差別,最後統一操做內部版本,好了今天就到這了,但願對你們有所幫助 > 微信號:baxiaoshi2020 > 關注公告號閱讀更多源碼分析文章 21天大棚 > 更多文章關注 www.sreguide.com > 本文由博客一文多發平臺 OpenWrite 發佈

相關文章
相關標籤/搜索