(轉)如何使用 CRD 拓展 Kubernetes 集群


https://blog.ihypo.net/15642142854314.html

在 6 月底 KubeCon 回來之后,就打算寫幾篇關於 CRD 的文章,還在 Twitter 上給人做了些許改進 CRD 相關文檔的承諾,零零碎碎的事很多,直到現在才有時間落筆。不過在這一個多月里,我做了一個關於 CRD 的內部分享,兩個 CRD Demo,向同事、客戶數人解釋 CRD 是什么東西,反而讓我對這個東西更加的清晰。

我會分兩到三篇文章介紹 CRD,這是第一篇,簡單聊一下什么是 CRD。

太長不看版:

CRD 本身是 Kubernetes 的一種資源,允許我們自己自定義新的資源類型
除了 CRD 我們還要提供一個 controller 以實現自己的邏輯
CRD 允許我們基於已有的 Kube 資源,拓展集群能力
CRD 可以使我們自己定義一套成體系的規范,自造概念
什么是 CRD
CRD 本身是一種 Kubernetes 內置的資源類型,是 CustomResourceDefinition 的縮寫,可以通過 kubectl get 命令查看集群內定義的 CRD 資源。

kubectl get crd

NAME CREATED AT
apps.app.o0w0o.cn 2019-07-25T07:02:47Z
microservices.app.o0w0o.cn 2019-07-25T07:02:47Z
當和人聊 CRD 聊多了的之后,發現大家對 CRD 有一些常見的誤區,因此,有些概念需要提前明確:

在 Kubernetes,所有的東西都叫做資源(Resource),就是 Yaml 里 Kind 那項所描述的
但除了常見的 Deployment 之類的內置資源之外,Kube 允許用戶自定義資源(Custom Resource),也就是 CR
CRD 其實並不是自定義資源,而是我們自定義資源的定義(來描述我們定義的資源是什么樣子)
對於一個 CRD 來說,其本質就是一個 Open Api 的 schema,就像 Kuber Blog 的一篇文章(https://kubernetes.io/blog/2019/06/20/crd-structural-schema/ )講到的,無論 R 還是 CR 都需要 Yaml 來描述,但是,如何確保 Yaml 描述的資源是規范的、合法的,那就是 schema 要做的事情,CRD 就其功能來講,就是想集群注冊一種新資源,並告知 ApiServer,這種資源怎么怎么被合法的定義。

控制器模式
在具體講 CRD 之前先簡單講解一下控制器模式。對 Kubernetes 有過了解的就知道,我們可以通過創建 Deployment 來管理 Pod,而其實 Deployment 並沒有直接創建 Pod,而是 Deployment 管理 RS,而 RS 管理 Pod,這其實就是控制器模式。

控制器模式允許基於已有的資源定義更高階的控制器,來實現更復雜的能力,當然,具體的細節要更復雜,推薦我司楊老濕的文章 《淺析 Kubernetes 控制器的工作原理》(https://www.yangcs.net/posts/a-deep-dive-into-kubernetes-controllers/

CRD 能做什么
一般情況下,我們利用 CRD 所定義的 CR 就是一個新的控制器,我們可以自定義控制器的邏輯,來做一些 Kubernetes 集群原生不支持的功能。

拿一個具體的例子來講,我用 Kubebulder 創建了一個簡單的 CRD(https://github.com/Coderhypo/KubeService ),嘗試在 Kubernetes 集群內置微服務管理。

我創建了兩種資源,一個叫 App,負責管理整個應用的生命周期,另一個叫 MicroService,負責管理微服務的生命周期。

具體的邏輯結構可以這樣理解:

App 可以直接管理多個 MicroService,並且,每個 MicroService 支持多個版本,得益於控制器模式,MicroService 可以為每個版本創建一個 Deployment,使得可以多個版本同時被部署。

如果只是管理應用的部署未免有些簡單,MicroService 支持為每個微服務創建 Service 和 Ingress,以實現四層負載均衡和七層負載均衡:

並且,如果開啟負載均衡的功能,MicroService 將為每個版本都創建一個 Service,因此,一個服務將擁有 n + 1 個 SVC,其中 n 是每個版本都擁有一個,而額外的 1 是微服務創建之后就不會再變動(名字和 clusterIP)的 SVC,而這個 SVC 的 Selector 會始終保持和 CurrentVersion 的 SVC 一致。

換句話講,有一個穩定的 SVC 可以對其他組件提供當前版本的服務,而其他組件也有途徑訪問到特定版本的服務。這個 SVC + CurrentVersion 就非常輕松的實現了藍綠發布的能力。

除了 SVC 外,MicroService 還基於 nginx ingress controller 的能力,實現了灰度發布的功能,同過修改 LoadBalance 里 canary 的配置,可以實現按 比例 / header / cookie 進行灰度發布。

這個例子中,App 和 MicroService 並沒有創造 “新能力”,而只是通過對 Kubernetes 已有資源進行組合,就實現了新功能。

但是除了快速對微服務進行藍綠、灰度之外,App 和 MicroService 還有沒有新的價值呢,另一個看不到的價值就是管理的標准化,之前對應用下的任何操作都需要被翻譯為 “Kube 語言”,即對那個 Deployment 或者 Ingress 管理,現在可以有一個統一的入口規范化管理。

總結
以一個簡單的小 Demo 來描述什么是 CRD 很容易以偏概全,就我目前的思考,我認為 CRD 有兩個非常重要的能力:

首先是功能上,CRD 使得 Kubernetes 已有的資源和能力變成了樂高積木,我們很輕松就可以利用這些積木拓展 Kubernetes 原生不具備的能力。

其次是產品上,基於 Kubernetes 做的產品無法避免的需要讓我們將產品術語向 Kube 術語靠攏,比如一個服務就是一個 Deployment,一個實例就是一個 Pod 之類。但是 CRD 允許我們自己基於產品創建概念(或者說資源),讓 Kube 已有的資源為我們的概念服務,這可以使產品更專注與解決的場景,而不是如何思考如何將場景應用到 Kubernetes。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM