深度剖析Kubernetes API Server三部曲 - part 2

      網友投稿 818 2022-05-30

      歡迎來到深入學習Kubernetes API Server的系列文章的第二部分。在上一部分Part1中我們對APIserver總體,相關術語及request請求流進行探討說明。在本部分文章中,我們主要聚焦于探究如何對Kubernetes 對象的狀態以一種可靠,持久的方式進行管理。之前的文章中提到過 API Server自身是無狀態的,并且它是唯一能夠與分布式存儲etcd直接通信的組件。

      etcd的簡要說明

      在*nix操作系統中,我們一般使用/etc來存儲相關配置數據。實際上etcd的名字就是由此發展而來,在etc后面加上個”d”表示”distributed”分布式。任何分布式系統都需要有像etcd這樣能夠存儲系統數據的東西,使其能夠以一致和可靠的方式檢索相關數據。為了能實現分布式的數據訪問,etcd使用Raft?協議。從概念上講,etcd支持的數據模型是鍵值(key-value)存儲。在etcd2中,各個key是以層次結構存在,而在etcd3中這個就變成了遍布模型,但同時也保持了層次結構方式的兼容性。

      使用容器化版本的etcd,我們可以創建上面的樹,然后按如下方式檢索它:

      現在我們已經大致了解了etcd是如何工作的,接下去我們繼續討論etcd在Kubernetes是如何被使用的。

      集群中的etcd

      在Kubernetes中,etcd是控制平面中的一耳光獨立組成部分。在Kubernetes1.5.2版本之前,我們使用的是etcd2版本,而在Kubernetes1.5.2版本之后我們就轉向使用etcd3版本了。值得注意的是在Kubernetes1.5.x版本中etcd依舊使用的是v2的API模型,之后這將開始變為v3的API模型,包括使用的數據模型。站在開發者角度而言這個似乎沒什么直接影響,因為API Server與存儲之前是抽象交互,而并不關心后端存儲的實現是etcd v2還是v3。但是如果是站在集群管理員的角度來看,還是需要知道etcd使用的是哪個版本,因為集群管理員需要日常對數據進行一些備份,恢復的維護操作。

      你可以API Server的相關啟動項中配置使用etcd的方式,API Server的etcd相關啟動項參數如下所示:

      Kubernetes?存儲在etcd中的數據,是以JSON字符串或Protocol Buffers?格式存儲。下面我們來看一個具體的例子:在apiserver-sandbox的命名空間中創建一個webserver的pod。然后我們使用?etcdctl工具來查看相關etcd(在本環節中etcd版本為3.1.0)數據。

      下面我們來看一下這個pod對象是如何最終存儲到etcd中,通過kubectl create -f pod.yaml的方式。

      下圖描繪了這個總體流程:

      1.客戶端(比如kubectl)提供一個理想狀態的對象,比如以YAML格式,v1版本提供。

      2.Kubectl將YAML轉換為JSON格式,并發送。

      3.對應同類型對象的不同版本,API Server執行無損耗轉換。對于老版本中不存在的字段則存儲在annotations中。

      4.API Server將接受到的對象轉換為規范存儲版本,這個版本由API Server指定,一般是最新的穩定版本,比如v1。

      5.最后將對象通過JSON?或protobuf方式解析為一個value,通過一個特定的key存入etcd當中。

      我們可以通過配置?kube-apiserver的啟動參數--storage-media-type來決定想要序列化數據存入etcd的格式,默認情況下為application/vnd.kubernetes.protobuf格式。我們也可以通過配置--storage-versions啟動參數,來確定存入etcd的每個群組Group對象的默認版本號。

      現在讓我們來看看無損轉換是如何進行的,我們將使用Kubernetes?對象Horizontal Pod Autoscaling (HPA)來列舉說明。HPA顧名思義是指通過監控資源的使用情況結合ReplicationController控制Pod的伸縮。

      首先我們期待一個API代理(以便于我們能夠在本地直接訪問它),并啟動ReplicationController,以及HPA?。

      現在,你能夠使用httpie?——當然你也能夠使用curl的方式——向API server 請求獲取HPA對象使用當前的穩定版本(autoscaling/v1),或者使用之前的版本(extensions/v1beta1)。

      獲取的兩個版本的區別如下所示:

      我們能夠看到HorizontalPodAutoscale的版本從v1beta1變為了v1。API server能夠在不同的版本之前無損耗轉換,不論在etcd中實際存的是哪個版本。

      在了解整個存儲流程之后,我們下面來探究一下API server如何將數據進行編碼,解碼存入etcd中以JSON?或protobuf的方式,同時也考慮到etcd的版本。

      API Server將所有已知的Kubernetes對象類型保存在名為Scheme的Go類型注冊表(registry)中。在此注冊表中,定義每種了Kubernetes對象的類型以及如何轉換它們,如何創建新對象,以及如何將對象編碼和解碼為JSON或protobuf。

      當API Server從客戶端接收到一個對象時,比如kubectl,通過HTTP路徑,能夠知道這個對象的具體版本號。首先會為這個對象使用對應的版本Scheme創建一個空對象,然后通過JSON或protobuf將HTTP傳過來的對象內容進行解碼轉換。解碼完成后創建對象,存入etcd中。

      在API中可能會有很多版本,如果要支持每個版本之間的直接轉換,這樣往往處理起來比較麻煩。比如某個API下面有三個版本,那么它就要支持一個版本到另兩個版本的直接轉換(比如v1 ? v1alpha1, v1 ? v1beta1, v1beta1 ? v1alpha1)。為了避免這個問題,在API server中有一個特別的?“internal”?版本。當兩個版本之間需要轉換時,先轉換為internal版本,再轉換為相應轉換的版本。這樣的話,每個版本只要支持能夠轉換為internal版本,那么就能夠與其它任何版本進行間接的轉換。所以一個對象先轉換為internal版本,然后在轉換為穩定的v1版本,然后在存入etcd中。

      v1beta1 ? internal ? v1

      校驗及準入

      在轉換的第一步中,如果某些字段用戶沒有賦值指定,那么這些會被賦為一個默認值。比如在v1beta1?中肯定沒有在v1版本新增的一個字段。在這種情況下,用戶肯定無法在v1beta1版本為這個字段賦值。這時候,在轉換的第一步中,我們會為這個字段賦一個默認值以生成一個有效的internal。

      在轉換過程中有兩個重要的步驟,如下圖所示:

      準入和校驗是創建和更新對象存入etcd之前必須通過的步驟。

      深度剖析Kubernetes API Server三部曲 - part 2

      它們的一些規則如下所示:

      1.準入(Admission):查看集群中的一些約束條件是否允許創建或更新此對象,并根據此集群的相關配置為對象設置一些默認值。在Kubernetes有很多這種約束條件,下面列舉一些例子:

      NamespaceLifecycle:如果命名空間不存在,則拒絕該命名空間下的所有傳入請求。

      LimitRanger:強制限制命名空間中資源的使用率。

      ServiceAccount:為pod創建 service account 。

      DefaultStorageClass:如果用戶沒有為PersistentVolumeClaims賦值,那么將它設置為一個默認值。

      ResourceQuota:對群集上的當前用戶強制執行配額約束,如果配額不足,可能會拒絕請求。

      2.校驗(Validation):檢查傳入對象(在創建和更新期間)是否格式是否合法以及相關值是否有效。比如:

      1.檢查必填字段是否已填。

      2.檢查字符串格式是否正確(比如只允許小寫形式)。

      3.是否有些字段存在沖突(比如,有兩個容器的名字一樣)。

      校驗(Validation)并不關心其它類型的對象實例,換言之,它只關心每個對象的靜態檢查,無關集群配置。

      準入(Admission)可以用flag

      --admission-control=來啟動或禁用。它們中的大多數可以有集群管理配置。此外,在Kubernetes 1.7中可以用webhook機制來擴展準入機制,使用控制器來實現對對象的傳統的校驗。

      遷移存儲對象

      關于存儲對象遷移的最后說明:當Kubernetes需要升級到新的版本時,根據每個版本的相關文檔步驟備份相關集群的數據是至關重要的。這一方面是由于etcd2到etcd3的轉變,另一方面是由于Kubernetes 對象的Kind及version的不斷發展。

      在etcd中,每個對象是首選存儲版本(preferred storage version)存在的。但是,隨著時間的推移,etcd存儲中的對象可能以一個非常老的版本存在。如果在將來某個時間這個對象版本被廢棄了,那么將無法再解碼它的protobuf?或JSON。因此,在集群升級之前需要重寫,遷移這些數據。

      API Kubernetes

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:李沐大神火遍知乎的《動手學深度學習》出版啦!
      下一篇:C# Xamarin 數據綁定入門基礎
      相關文章
      亚洲AV无码成人网站在线观看| 亚洲中文字幕乱码AV波多JI| 亚洲乱码中文字幕在线| 亚洲av午夜福利精品一区| 亚洲欧洲自拍拍偷精品 美利坚| 含羞草国产亚洲精品岁国产精品| 亚洲一区二区三区国产精华液| 亚洲人精品亚洲人成在线| 91丁香亚洲综合社区| 亚洲五月综合网色九月色| 精品亚洲AV无码一区二区| 亚洲伊人色一综合网| 中文字幕亚洲男人的天堂网络| 国产99在线|亚洲| 亚洲性无码AV中文字幕| 亚洲欧美aⅴ在线资源| 亚洲а∨精品天堂在线| 国产亚洲美女精品久久久久| 亚洲AV永久无码精品一区二区国产| 亚洲AV无码乱码精品国产| 亚洲AV无码一区二区三区鸳鸯影院| 亚洲av无码片vr一区二区三区| 久久精品国产亚洲av品善| 少妇亚洲免费精品| 久久久久亚洲AV综合波多野结衣| 国内精品久久久久久久亚洲| 亚洲AV一宅男色影视| 337p欧洲亚洲大胆艺术| 亚洲一区二区三区播放在线| 久久亚洲精品国产精品婷婷 | 亚洲无人区码一二三码区别图片| 亚洲综合精品成人| 青草久久精品亚洲综合专区| 亚洲阿v天堂在线2017免费| 在线观看国产区亚洲一区成人| 亚洲va久久久噜噜噜久久狠狠| 亚洲小视频在线观看| 亚洲av无码片区一区二区三区| 亚洲人成网亚洲欧洲无码| 亚洲AV无码乱码在线观看牲色| 国产亚洲精品无码专区|