kubernetes1.9管中窺豹-CRD概念、使用場景及例項
歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。
前言
預設讀者有kubernetes基礎概念的背景知識,因此基礎概念例如有狀態、pod、Replica Sets、Deployments、statefulsets等不在此文詳細闡述。 可以看我之前的一些關於kubernetes的文章:
kubernetes 1.3管中窺豹- RS(Replica Sets)
kubernetes pod&container生命週期淺析
kubernetes1.6管中窺豹-StatefulSets概念、約束、原理及例項
本文主要介紹一個1.7+以後出現的新概念CRD(CustomResourceDefinition )的概念、使用場景及例項。
CRD歷史來源 | |
---|---|
k8s1.6~1.7 | TRP(CRD的前身):Third Party Resource。 |
k8s1.7+ | CRD: Custom Resource Definition。 |
CRD的概念
Custom resources:是對K8S API的擴充套件,代表了一個特定的kubetnetes的定製化安裝。在一個執行中的叢集中,自定義資源可以動態註冊到叢集中。註冊完畢以後,使用者可以通過kubelet建立和訪問這個自定義的物件,類似於操作pod一樣。
Custom controllers:Custom resources可以讓使用者簡單的儲存和獲取結構化資料。只有結合控制器才能變成一個真正的declarative API(被宣告過的API)。控制器可以把資源更新成使用者想要的狀態,並且通過一系列操作維護和變更狀態。定製化控制器是使用者可以在執行中的叢集內部署和更新的一個控制器,它獨立於叢集本身的生命週期。 定製化控制器可以和任何一種資源一起工作,當和定製化資源結合使用時尤其有效。
Operator模式 是一個customer controllers和Custom resources結合的例子。它可以允許開發者將特殊應用編碼至kubernetes的擴充套件API內。
如何新增一個Custom resources到我的kubernetes叢集呢? kubernetes提供了兩種方式將Custom resources新增到叢集。
1. Custom Resource Definitions (CRDs):更易用、不需要編碼。但是缺乏靈活性。
2. API Aggregation:需要編碼,允許通過聚合層的方式提供更加定製化的實現。
本文重點講解Custom Resource Definitions (CRD)的使用方法。
CRD使用場景
假設需要在原生kubernetes完成一些額外的功能開發,而且想使用restful風格的API 去呼叫這個功能。比如像開發容器儲存映象或者重啟映象等操作(一般都通過命令傳送給容器內部完成)。就可以在原生kubernetes上增加一個CRD,命名為task。通過task觸發一些邏輯。當使用apiserver下發這個task建立時,Custom controllers watch到這個task就開始處理相關業務邏輯,然後通過agent呼叫docker命令完成容器儲存映象功能並且重啟容器。當Custom controllers watch到pod重新執行的時候,本次操作完成。 流程圖如下:
CRD使用示例
如果想要完成上述場景的功能,需要定義一個CRD,並且創建出來。 舉例如下,以下是一個可以在1.9叢集環境中建立成功的crd yaml檔案。
apiVersion: apiextensions.k8s.io/v1beta1kind: CustomResourceDefinitionmetadata: # name must match the spec fields below, and be in the form: <plural>.<group> name: tasks.163yun.comspec: # group name to use for REST API: /apis/<group>/<version> group: 163yun.com # version name to use for REST API: /apis/<group>/<version> version: v1 # either Namespaced or Cluster scope: Namespaced names: # plural name to be used in the URL: /apis/<group>/<version>/<plural> plural: tasks # singular name to be used as an alias on the CLI and for display singular: task # kind is normally the CamelCased singular type. Your resource manifests use this. kind: Task # shortNames allow shorter string to match your resource on the CLI shortNames: - task
其中幾個關鍵要素是name、group、scope以及names裡面的一些定義。
name:用於定義CRD的名字,字尾需要跟group一致,例如tasks.163yun.com,字首需要跟names中的plural一致。
group以及version用於標識restAPI:即/apis//。 上文中的介面前面一部分就是/apis/163yun.com/v1
scope: 表明作用於,可以是基於namespace的,也可以是基於叢集的。 如果是基於namespace的。則API格式為:/apis/{group}/v1/namespaces/{namespace}/{spec.names.plural}/… 如果是基於cluster的。則API格式為:/apis/{group}/v1/{spec.names.plural}/… 上文建立的CRD的API則為:/apis/163yun.com/v1/namespaces/{namespace}/tasks
names:描述了一些自定義資源的名字以及型別的名字(重點是plural定義以及kind定義,因為會在url或者查詢資源中用的到)。
當以上面的模板創建出來一個CRD後,可以查到crd的資訊:
[email protected]:~/cxq# kubectl get CustomResourceDefinition tasks.163yun.com -o yaml apiVersion: apiextensions.k8s.io/v1beta1kind: CustomResourceDefinitionmetadata: creationTimestamp: 2018-03-16T06:17:03Z generation: 1 name: tasks.163yun.com resourceVersion: "35442027" selfLink: /apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions/tasks.163yun.com uid: a538030c-28e1-11e8-b047-fa163ef9812dspec: group: 163yun.com names: kind: Task listKind: TaskList plural: tasks shortNames: - task singular: task scope: Namespaced version: v1status: acceptedNames: kind: Task listKind: TaskList plural: tasks shortNames: - task singular: task conditions: - lastTransitionTime: 2018-03-16T06:17:03Z message: no conflicts found reason: NoConflicts status: "True" type: NamesAccepted - lastTransitionTime: 2018-03-16T06:17:03Z message: the initial names have been accepted reason: InitialNamesAccepted status: "True" type: Established
這時查詢crd中定義的task型別的資源,是空的:
[email protected]:~/cxq# kubectl get task -o yaml apiVersion: v1items: []kind: Listmetadata: resourceVersion: "" selfLink: ""
這時需要自定義一個task型別的模板,建立,以使得task可以觸發自定義的一些事件
[email protected]:~/cxq# cat cxq-task.yaml apiVersion: "163yun.com/v1"kind: Taskmetadata: name: cxq-nce-taskspec: cronSpec: "* * * * /5" image: my-awesome-cron-image [email protected]:~/cxq# kubectl create -f cxq-task.yaml task "cxq-nce-task" created [email protected]:~/cxq# kubectl get task -o yamlapiVersion: v1items:- apiVersion: 163yun.com/v1 kind: Task metadata: clusterName: "" creationTimestamp: 2018-03-16T06:43:10Z labels: {} name: cxq-nce-task namespace: default resourceVersion: "35444352" selfLink: /apis/163yun.com/v1/namespaces/default/tasks/cxq-nce-task uid: 4ad237aa-28e5-11e8-b047-fa163ef9812d spec: cronSpec: '* * * * /5' image: my-awesome-cron-imagekind: Listmetadata: resourceVersion: "" selfLink: ""
注意由於CRD和自定義的Task資源本身是namespace無關的,因此對所有namespace都可見。如果指定了scope為namespace。那麼建立的自定義task也需要指定namespace,如果不指定的話,系統會自動將task分配到default 的namespace下。
這時可以通過task的url去對自定義的task資源進行操作,或者watch。結合上一節的流程圖來完成實現自定義功能的目的。以下是呼叫watch介面對task資源進行長連線監控(變化)。
[email protected]:~/cxq# curl http://10.180.156.79:8080/apis/163yun.com/v1/namespaces/default/tasks?watch=true {"type":"ADDED","object":{"apiVersion":"163yun.com/v1","kind":"Task","metadata":{"clusterName":"","creationTimestamp":"2018-03-16T06:43:10Z","labels":{},"name":"cxq-nce-task","namespace":"default","resourceVersion":"35444352","selfLink":"/apis/163yun.com/v1/namespaces/default/tasks/cxq-nce-task","uid":"4ad237aa-28e5-11e8-b047-fa163ef9812d"},"spec":{"cronSpec":"* * * * /5","image":"my-awesome-cron-image"}}}
總結
CRD提供了一種無須編碼就可以擴充套件原生kubenetes API介面的方式。很適合在雲應用中擴充套件kubernetes的自定義介面和功能。在一些無須太多定製和靈活的開發場景下,CRD的方式已經足夠使用。如果想更為靈活的新增邏輯就需要參考API Aggregation的使用了。
網易雲容器服務為使用者提供了無伺服器容器,讓企業能夠快速部署業務,輕鬆運維服務。容器服務支援彈性伸縮、垂直擴容、灰度升級、服務發現、服務編排、錯誤恢復及效能監測等功能。點選免費試用
相關閱讀:淺談 kubernetes service 那些事(上篇)
淺談 kubernetes service 那些事 (下篇)
本文來自網易實踐者社群,經作者崔曉晴授權釋出。
相關文章:
【推薦】 nkv客戶端效能調優
【推薦】 純乾貨!live2d動畫製作簡述以及踩坑