如何理解KubernetesAPI編程范式

這篇文章給大家介紹如何理解Kubernetes API 編程范式,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

在遷安等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站 網(wǎng)站設(shè)計(jì)制作按需設(shè)計(jì),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站建設(shè),成都全網(wǎng)營(yíng)銷,外貿(mào)網(wǎng)站制作,遷安網(wǎng)站建設(shè)費(fèi)用合理。

一、需求來源

首先我們先來看一下 API 編程范式的需求來源。

在 Kubernetes 里面, API 編程范式也就是 Custom Resources Definition(CRD)。我們常講的 CRD,其實(shí)指的就是用戶自定義資源。

為什么會(huì)有用戶自定義資源問題呢?

隨著 Kubernetes 使用的越來越多,用戶自定義資源的需求也會(huì)越來越多。而 Kubernetes 提供的聚合各個(gè)子資源的功能,已經(jīng)不能滿足日益增長(zhǎng)的廣泛需求了。用戶希望提供一種用戶自定義的資源,把各個(gè)子資源全部聚合起來。但 Kubernetes 原生資源的擴(kuò)展和使用比較復(fù)雜,因此誕生了用戶自定義資源這么一個(gè)功能。

二、用例解讀

CRD 的一個(gè)實(shí)例

我們首先具體地介紹一下 CRD 是什么。

CRD 功能是在 Kubernetes 1.7 版本被引入的,用戶可以根據(jù)自己的需求添加自定義的 Kubernetes 對(duì)象資源。值得注意的是,這里用戶自己添加的 Kubernetes 對(duì)象資源都是 native 的、都是一等公民,和 Kubernetes 中自帶的、原生的那些 Pod、Deployment 是同樣的對(duì)象資源。在 Kubernetes 的 API Server 看來,它們都是存在于 etcd 中的一等資源。

同時(shí),自定義資源和原生內(nèi)置的資源一樣,都可以用 kubectl  來去創(chuàng)建、查看,也享有 RBAC、安全功能。用戶可以開發(fā)自定義控制器來感知或者操作自定義資源的變化。

下面我們來看一個(gè)簡(jiǎn)單的 CRD 實(shí)例。下圖是一個(gè) CRD 的定義。

如何理解Kubernetes API 編程范式

首先最上面的 apiVersion 就是指 CRD 的一個(gè) apiVersion 聲明,聲明它是一個(gè) CRD 的需求或者說定義的 Schema。

kind 就是 CustomResourcesDefinition,指 CRD。name 是一個(gè)用戶自定義資源中自己自定義的一個(gè)名字。一般我們建議使用“頂級(jí)域名.xxx.APIGroup”這樣的格式,比如這里就是 foos.samplecontroller.k8s.io。

spec 用于指定該 CRD 的 group、version。比如在創(chuàng)建 Pod 或者 Deployment 時(shí),它的 group 可能為 apps/v1 或者 apps/v1beta1 之類,這里我們也同樣需要去定義 CRD 的 group。

  • 圖中的 group 為 samplecontroller.k8s.io;

  • verison 為 v1alpha1;

  • names 指的是它的 kind 是什么,比如 Deployment 的 kind 就是 Deployment,Pod 的 kind 就是 Pod,這里的 kind 被定義為了 Foo;

  • plural 字段就是一個(gè)昵稱,比如當(dāng)一些字段或者一些資源的名字比較長(zhǎng)時(shí),可以用該字段自定義一些昵稱來簡(jiǎn)化它的長(zhǎng)度;

  • scope 字段表明該 CRD 是否被命名空間管理。比如 ClusterRoleBinding 就是 Cluster 級(jí)別的。再比如 Pod、Deployment 可以被創(chuàng)建到不同的命名空間里,那么它們的 scope 就是 Namespaced 的。這里的 CRD 就是 Namespaced 的。

下圖就是上圖所定義的 CRD 的一個(gè)實(shí)例。

如何理解Kubernetes API 編程范式

  • 它的 apiVersion 就是我們剛才所定義的 samplecontroller.k8s.io/v1alpha1;

  • kind 就是 Foo;

  • metadata 的 name 就是我們這個(gè)例子的名字;

  • 這個(gè)實(shí)例中 spec 字段其實(shí)沒有在 CRD 的 Schema 中定義,我們可以在 spec 中根據(jù)自己的需求來寫一寫,格式就是 key:value 這種格式,比如圖中的 deploymentName: example-foo, replicas: 1。當(dāng)然我們也可以去做一些檢驗(yàn)或者狀態(tài)資源去定義 spec 中到底包含什么。

帶有校驗(yàn)的 CRD

我們來看一個(gè)包含校驗(yàn)的 CRD 定義:
如何理解Kubernetes API 編程范式

可以看到這個(gè)定義更加復(fù)雜了,validation 之前的字段我們就不再贅述了,單獨(dú)看校驗(yàn)這一段。

它首先是一個(gè) openAPIV3Schema 的定義,spec 中則定義了有哪些資源,以 replicas 為例,這里將 replicas 定義為一個(gè) integer 的資源,最小值為 1,最大值是 10。那么,當(dāng)我們?cè)俅问褂眠@個(gè) CRD 的時(shí)候,如果我們給出的 replicas 不是 int 值,或者去寫一個(gè) -1,或者大于 10 的值,這個(gè) CRD 對(duì)象就不會(huì)被提交到 API Server,API Server 會(huì)直接報(bào)錯(cuò),告訴你不滿足所定義的參數(shù)條件。

帶有狀態(tài)字段的 CRD

再來看一下帶有狀態(tài)字段的 CRD 定義。

如何理解Kubernetes API 編程范式

我們?cè)谑褂靡恍?Deployment 或 Pod 的時(shí)候,部署完成之后可能要去查看當(dāng)前部署的狀態(tài)、是否更新等等。這些都是通過增加狀態(tài)字段來實(shí)現(xiàn)的。另外,Kubernetes 在 1.12 版本之前,還沒有狀態(tài)字段。

狀態(tài)實(shí)際上是一個(gè)自定義資源的子資源,它的好處在于,對(duì)該字段的更新并不會(huì)觸發(fā) Deployment 或 Pod 的重新部署。我們知道對(duì)于某些 Deployment 和 Pod,只要修改了某些 spec,它就會(huì)重新創(chuàng)建一個(gè)新的 Deployment 或者 Pod 出來。但是狀態(tài)資源并不會(huì)被重新創(chuàng)建,它只是用來回應(yīng)當(dāng)前 Pod 的整個(gè)狀態(tài)。上圖中的 CRD 聲明中它的子資源的狀態(tài)非常簡(jiǎn)單,就是一個(gè) key:value 的格式。在 “{}” 里寫什么,都是自定義的。

如何理解Kubernetes API 編程范式

以一個(gè) Deployment 的狀態(tài)字段為例,它包含 availableReplicas、當(dāng)前的狀態(tài)(比如更新到第幾個(gè)版本了、上一個(gè)版本是什么時(shí)候)等等這些信息。在用戶自定義 CRD 的時(shí)候,也可以進(jìn)行一些復(fù)雜的操作來告訴別的用戶它當(dāng)前的狀態(tài)如何。

三、操作演示

下面我們來具體演示一下 CRD。

我們這里有兩個(gè)資源:crd.yaml 和 example-foo.yaml。

如何理解Kubernetes API 編程范式

首先創(chuàng)建一下這個(gè) CRD 的 Schema 讓我們的 Kubernetes Server 知道該 CRD 到底是什么樣的。創(chuàng)建的方式非常簡(jiǎn)單,就是 “kuberctl create -f crd.yaml”。
如何理解Kubernetes API 編程范式

通過 “kuberctl get crd” 可以看到剛才的 CRD 已經(jīng)被創(chuàng)建成功了。

如何理解Kubernetes API 編程范式

這個(gè)時(shí)候我們就可以去創(chuàng)建對(duì)應(yīng)的資源 “kuberctl create -f example-foo.yaml”:

如何理解Kubernetes API 編程范式

下面來看一下它里面到底有什么東西 “kubectl get foo example-foo -o yaml” :

如何理解Kubernetes API 編程范式

可以看到它是一個(gè) Foo 的資源,spec 就是我們剛才所定義的,被選中的部分是基本上所有的 Kubernetes 的 metadata 資源中都會(huì)有的。因此,創(chuàng)建該資源和我們正常創(chuàng)建一個(gè) Pod 的區(qū)別并不大,但是這個(gè)資源不是一個(gè) Pod,也不是 Kubernetes 本身內(nèi)置的資源,這就是一個(gè)我們自己創(chuàng)建的資源。從使用方式和使用體驗(yàn)上來說,和 Kubernetes 內(nèi)置資源的使用幾乎一致。

四、架構(gòu)設(shè)計(jì)

控制器概覽

只定義一個(gè) CRD 其實(shí)沒有什么作用,它只會(huì)被 API Server 簡(jiǎn)單地計(jì)入到 etcd 中。如何依據(jù)這個(gè) CRD 定義的資源和 Schema 來做一些復(fù)雜的操作,則是由 Controller,也就是控制器來實(shí)現(xiàn)的。

Controller 其實(shí)是 Kubernetes 提供的一種可插拔式的方法來擴(kuò)展或者控制聲明式的 Kubernetes 資源。它是 Kubernetes 的大腦,負(fù)責(zé)大部分資源的控制操作。以 Deployment 為例,它就是通過 kube-controller-manager 來部署的。

比如說聲明一個(gè) Deployment 有 replicas、有 2 個(gè) Pod,那么 kube-controller-manager 在觀察 etcd 時(shí)接收到了該請(qǐng)求之后,就會(huì)去創(chuàng)建兩個(gè)對(duì)應(yīng)的 Pod 的副本,并且它會(huì)去實(shí)時(shí)地觀察著這些 Pod 的狀態(tài),如果這些 Pod 發(fā)生變化了、回滾了、失敗了、重啟了等等,它都會(huì)去做一些對(duì)應(yīng)的操作。

所以 Controller 才是控制整個(gè) Kubernetes 資源最終表現(xiàn)出來的狀態(tài)的大腦。

用戶聲明完成 CRD 之后,也需要?jiǎng)?chuàng)建一個(gè)控制器來完成對(duì)應(yīng)的目標(biāo)。比如之前的 Foo,它希望去創(chuàng)建一個(gè) Deployment,replicas 為 1,這就需要我們創(chuàng)建一個(gè)控制器用于創(chuàng)建對(duì)應(yīng)的 Deployment 才能真正實(shí)現(xiàn) CRD 的功能。

控制器工作流程概覽

如何理解Kubernetes API 編程范式

這里以 kube-controller-manager 為例。

如上圖所示,左側(cè)是一個(gè) Informer,它的機(jī)制就是通過去 watch kube-apiserver,而 kube-apiserver 會(huì)去監(jiān)督所有 etcd 中資源的創(chuàng)建、更新與刪除。Informer 主要有兩個(gè)方法:一個(gè)是 ListFunc;一個(gè)是 WatchFunc。

  • ListFunc 就是像 “kuberctl get pods” 這類操作,把當(dāng)前所有的資源都列出來;

  • WatchFunc 會(huì)和 apiserver 建立一個(gè)長(zhǎng)鏈接,一旦有一個(gè)新的對(duì)象提交上去之后,apiserver 就會(huì)反向推送回來,告訴 Informer 有一個(gè)新的對(duì)象創(chuàng)建或者更新等操作。

Informer 接收到了對(duì)象的需求之后,就會(huì)調(diào)用對(duì)應(yīng)的函數(shù)(比如圖中的三個(gè)函數(shù) AddFunc, UpdateFunc 以及 DeleteFunc),并將其按照 key 值的格式放到一個(gè)隊(duì)列中去,key 值的命名規(guī)則就是 “namespace/name”,name 就是對(duì)應(yīng)的資源的名字。比如我們剛才所說的在 default 的 namespace 中創(chuàng)建一個(gè) foo 類型的資源,那么它的 key 值就是 “default/example-foo”。Controller 從隊(duì)列中拿到一個(gè)對(duì)象之后,就會(huì)去做相應(yīng)的操作。

下圖就是控制器的工作流程。

如何理解Kubernetes API 編程范式

首先,通過 kube-apiserver 來推送事件,比如 Added, Updated, Deleted;然后進(jìn)入到 Controller 的 ListAndWatch() 循環(huán)中;ListAndWatch 中有一個(gè)先入先出的隊(duì)列,在操作的時(shí)候就將其 Pop() 出來;然后去找對(duì)應(yīng)的 Handler。Handler 會(huì)將其交給對(duì)應(yīng)的函數(shù)(比如 Add(), Update(), Delete())。

一個(gè)函數(shù)一般會(huì)有多個(gè) Worker。多個(gè) Worker 的意思是說比如同時(shí)有好幾個(gè)對(duì)象進(jìn)來,那么這個(gè) Controller 可能會(huì)同時(shí)啟動(dòng)五個(gè)、十個(gè)這樣的 Worker 來并行地執(zhí)行,每個(gè) Worker 可以處理不同的對(duì)象實(shí)例。

工作完成之后,即把對(duì)應(yīng)的對(duì)象創(chuàng)建出來之后,就把這個(gè) key 丟掉,代表已經(jīng)處理完成。如果處理過程中有什么問題,就直接報(bào)錯(cuò),打出一個(gè)事件來,再把這個(gè) key 重新放回到隊(duì)列中,下一個(gè) Worker 就可以接收過來繼續(xù)進(jìn)行相同的處理。

這里為大家簡(jiǎn)單總結(jié)一下:

  • CRD 是 Custom Resources Definition 的縮寫,也就是用戶自定義資源,用戶可以使用這個(gè)功能擴(kuò)展自己的Kubernetes 原生資源信息;

  • CRD 和普通的 Kubernetes 資源一樣,都可以受 RBAC 權(quán)限控制,并且支持 status 狀態(tài)字段;

  • CRD-controller 也就是 CRD 控制器,能夠?qū)崿F(xiàn)用戶自行編寫,并且解析 CRD 并把它變成用戶期望的狀態(tài)。

關(guān)于如何理解Kubernetes API 編程范式就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

當(dāng)前名稱:如何理解KubernetesAPI編程范式
網(wǎng)站URL:http://muchs.cn/article12/iegpgc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄網(wǎng)站營(yíng)銷、網(wǎng)站導(dǎo)航搜索引擎優(yōu)化、品牌網(wǎng)站制作服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站