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

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

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



1.1 從拓撲轉換到星狀轉換
在一般的web開發中更多的時候,你們都是斷代向前兼容更新,大多數狀況下當版本更新以後會獨立演進,若是要在多版本之間轉換一般則會出現以下的狀況 若是咱們要爲每一個版本都去適配其餘全部的版本,則複雜度會指數級上升,而在kubernetes中則經過一個內部版本的設計來進行解決,內部版本是一個穩定的版本,全部的版本都只針對目標版原本進行轉換的實現,而不關注其餘版本
1.2 兼容設計之轉換
那若是謀個版本須要獨立的演進,或者增設一些新的字段,修改字段名稱等破壞性更新的時候,則就須要一種轉換機制,負責在當前版本和內部版本之間來進行字段或者數據的轉換
1.3 轉換的最終之反射
轉換其實核心目標是完成從目標對象的字段中獲取數據,而後通過一系列操做最終爲目標對象的對應的字段進行賦值操做,要完成該操做,則就須要藉助反射來實現,經過枚舉字段,來獲取對應的轉換函數,執行轉換函數,完成目標賦值

分佈式應用架構在阿里巴巴的現狀


2. 關鍵設計的實現

爲了實現上面的方案,kubernetes中設計了以下組件:Scheme(負責各個版本的註冊和管理)、Convert(轉換實現)、Serializer(實現對應版本的反序列化),讓咱們依次看下其關鍵設計
2.1 Convert
Convert實現從一個目標對象到另一個目標對象的轉換, 爲了實現這種轉換,kubernetes裏面主要是藉助反射和不一樣版本的轉換函數來共同完成
1.首先咱們經過目標函數來獲取對應的屬性字段,而後針對該字段進行計算賦值操做2.若是發現對應的字段須要來轉換,則會調用對應的轉換函數來進行賦值操做,若是不須要轉換則會直接經過反射來進行賦值

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


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


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


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.學習總結




實現上無疑是複雜的做爲一個工業設計有不少須要care的邊緣狀況,剖絲抽繭每一個人看到的都不同,這可能就是源碼閱讀的樂趣,從上面能夠看到核心其實就三個點:
  • 將HTTP數據反序列化成爲當前URL的資源對象
  • 而後目標資源對象進行初始化默認值函數的執行
  • 最後經過convert來處理不一樣版本之間的差別,最後統一操做內部版本

好了今天就到這了,但願對你們有所幫助css

kubernetes學習筆記地址: https://www.yuque.com/baxiaoshi/tyado3web

文章來源:圖解源碼 / 原文連接swift


END

Kubernetes CKA實戰培訓班推薦:

北京:12月18-20日數組


本文分享自微信公衆號 - K8S中文社區(k8schina)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。微信

相關文章
相關標籤/搜索