這篇文章給大家介紹如何理解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 是什么。
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 的定義。
首先最上面的 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í)例。
它的 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 中到底包含什么。
我們來看一個(gè)包含校驗(yàn)的 CRD 定義:
可以看到這個(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 定義。
我們?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 的格式。在 “{}” 里寫什么,都是自定義的。
以一個(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。
首先創(chuàng)建一下這個(gè) CRD 的 Schema 讓我們的 Kubernetes Server 知道該 CRD 到底是什么樣的。創(chuàng)建的方式非常簡(jiǎn)單,就是 “kuberctl create -f crd.yaml”。
通過 “kuberctl get crd” 可以看到剛才的 CRD 已經(jīng)被創(chuàng)建成功了。
這個(gè)時(shí)候我們就可以去創(chuàng)建對(duì)應(yīng)的資源 “kuberctl create -f example-foo.yaml”:
下面來看一下它里面到底有什么東西 “kubectl get foo example-foo -o yaml” :
可以看到它是一個(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è) 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 的功能。
這里以 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)的操作。
下圖就是控制器的工作流程。
首先,通過 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)