在以前的文章中分析過kubernetes是如何進行多版本管理中提到了一個關鍵的設計解碼器, 負責將請求對象反序列化成一個具體的數據模型,今天一塊兒來了解下其內部是如何實現多版本管理、轉換的設計要點web
在一般的web開發中更多的時候,你們都是斷代向前兼容更新,大多數狀況下當版本更新以後會獨立演進,若是要在多版本之間轉換一般則會出現以下的狀況 若是咱們要爲每一個版本都去適配其餘全部的版本,則複雜度會指數級上升,而在kubernetes中則經過一個內部版本的設計來進行解決,內部版本是一個穩定的版本,全部的版本都只針對目標版原本進行轉換的實現,而不關注其餘版本數組
那若是謀個版本須要獨立的演進,或者增設一些新的字段,修改字段名稱等破壞性更新的時候,則就須要一種轉換機制,負責在當前版本和內部版本之間來進行字段或者數據的轉換微信
轉換其實核心目標是完成從目標對象的字段中獲取數據,而後通過一系列操做最終爲目標對象的對應的字段進行賦值操做,要完成該操做,則就須要藉助反射來實現,經過枚舉字段,來獲取對應的轉換函數,執行轉換函數,完成目標賦值數據結構
爲了實現上面的方案,kubernetes中設計了以下組件:Scheme(負責各個版本的註冊和管理)、Convert(轉換實現)、Serializer(實現對應版本的反序列化),讓咱們依次看下其關鍵設計ide
Convert實現從一個目標對象到另一個目標對象的轉換, 爲了實現這種轉換,kubernetes裏面主要是藉助反射和不一樣版本的轉換函數來共同完成函數
1.首先咱們經過目標函數來獲取對應的屬性字段,而後針對該字段進行計算賦值操做 2.若是發現對應的字段須要來轉換,則會調用對應的轉換函數來進行賦值操做,若是不須要轉換則會直接經過反射來進行賦值源碼分析
在構建rest接口的時候,每一個rest接口都會持有一個生成當前版本對象的構造函數,當請求進入以後,會首先經過目標版本獲取對應的decoder decoder會利用當前的GroupVersionKind來進行第一步解析,首先將字節數組解析成當前版本,而後在解析成目標對象以後,又會根據目標版本進行轉換學習
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) }
實現上無疑是複雜的做爲一個工業設計有不少須要care的邊緣狀況,剖絲抽繭每一個人看到的都不同,這可能就是源碼閱讀的樂趣,從上面能夠看到核心其實就三個點:將HTTP數據反序列化成爲當前URL的資源對象,而後目標資源對象進行初始化默認值函數的執行,最後經過convert來處理不一樣版本之間的差別,最後統一操做內部版本,好了今天就到這了,但願對你們有所幫助 > 微信號:baxiaoshi2020 > 關注公告號閱讀更多源碼分析文章 > 更多文章關注 www.sreguide.com > 本文由博客一文多發平臺 OpenWrite 發佈