日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

课时 23:Kubernetes API 编程范式(陈显鹭)

發(fā)布時(shí)間:2025/3/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 课时 23:Kubernetes API 编程范式(陈显鹭) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文將主要分享以下四個(gè)方面的內(nèi)容:

  • 需求來(lái)源
  • 用例解讀
  • 操作演示
  • 架構(gòu)設(shè)計(jì)
  • 需求來(lái)源

    首先我們先來(lái)看一下 API 編程范式的需求來(lái)源。

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

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

    隨著 Kubernetes 使用的越來(lái)越多,用戶自定義資源的需求也會(huì)越來(lái)越多。而 Kubernetes 提供的聚合各個(gè)子資源的功能,已經(jīng)不能滿足日益增長(zhǎng)的廣泛需求了。用戶希望提供一種用戶自定義的資源,把各個(gè)子資源全部聚合起來(lái)。但 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 看來(lái),它們都是存在于 etcd 中的一等資源。

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

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

    首先最上面的 apiVersion 就是指 CRD 的一個(gè) apiVersion 聲明,聲明它是一個(gè) CRD 的需求或者說(shuō)定義的 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í),可以用該字段自定義一些昵稱來(lái)簡(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í)沒(méi)有在 CRD 的 Schema 中定義,我們可以在 spec 中根據(jù)自己的需求來(lái)寫一寫,格式就是 key:value 這種格式,比如圖中的 deploymentName: example-foo, replicas: 1。當(dāng)然我們也可以去做一些檢驗(yàn)或者狀態(tài)資源去定義 spec 中到底包含什么。

    帶有校驗(yàn)的 CRD

    我們來(lái)看一個(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

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

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

    狀態(tài)實(shí)際上是一個(gè)自定義資源的子資源,它的好處在于,對(duì)該字段的更新并不會(huì)觸發(fā) Deployment 或 Pod 的重新部署。我們知道對(duì)于某些 Deployment 和 Pod,只要修改了某些 spec,它就會(huì)重新創(chuàng)建一個(gè)新的 Deployment 或者 Pod 出來(lái)。但是狀態(tài)資源并不會(huì)被重新創(chuàng)建,它只是用來(lái)回應(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ù)雜的操作來(lái)告訴別的用戶它當(dāng)前的狀態(tài)如何。

    操作演示

    下面我們來(lá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。

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

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

    下面來(lái)看一下它里面到底有什么東西 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)上來(lái)說(shuō),和 Kubernetes 內(nèi)置資源的使用幾乎一致。

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

    控制器概覽

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

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

    比如說(shuō)聲明一個(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)出來(lái)的狀態(tài)的大腦。

    用戶聲明完成 CRD 之后,也需要?jiǎng)?chuàng)建一個(gè)控制器來(lái)完成對(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ī)制就是通過(guò)去 watch kube-apiserver,而 kube-apiserver 會(huì)去監(jiān)督所有 etcd 中資源的創(chuàng)建、更新與刪除。Informer 主要有兩個(gè)方法:一個(gè)是 ListFunc;一個(gè)是 WatchFunc。

    • ListFunc 就是像 kuberctl get pods 這類操作,把當(dāng)前所有的資源都列出來(lái);
    • WatchFunc 會(huì)和 apiserver 建立一個(gè)長(zhǎng)鏈接,一旦有一個(gè)新的對(duì)象提交上去之后,apiserver 就會(huì)反向推送回來(lái),告訴 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)的資源的名字。比如我們剛才所說(shuō)的在 default 的 namespace 中創(chuàng)建一個(gè) foo 類型的資源,那么它的 key 值就是 default/example-foo。Controller 從隊(duì)列中拿到一個(gè)對(duì)象之后,就會(huì)去做相應(yīng)的操作。

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

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

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

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

    本節(jié)總結(jié)(對(duì)本節(jié)內(nèi)容進(jìn)行分點(diǎn)概括)

    本節(jié)課的主要內(nèi)容就到此為止了,這里為大家簡(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)。
    《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

    總結(jié)

    以上是生活随笔為你收集整理的课时 23:Kubernetes API 编程范式(陈显鹭)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。