Kubernetes API Resources

這邊假設你已經對 Kubernetes 有基本的認識,知道怎麼用 kubectl。Pod、ReplicaSet、Service,甚至是 Namespace 其實都是一種 API Resource。

可以用 kubectl api-resources 來查看現在 Kubernetes 裡面存在的所有 API Resources。

$ kubectl api-resources
NAME                     SHORTNAMES   APIVERSION   NAMESPACED   KIND
bindings                              v1           true         Binding
componentstatuses        cs           v1           false        ComponentStatus
configmaps               cm           v1           true         ConfigMap
endpoints                ep           v1           true         Endpoints
events                   ev           v1           true         Event
limitranges              limits       v1           true         LimitRange
namespaces               ns           v1           false        Namespace
nodes                    no           v1           false        Node
persistentvolumeclaims   pvc          v1           true         PersistentVolumeClaim
persistentvolumes        pv           v1           false        PersistentVolume
pods                     po           v1           true         Pod
podtemplates                          v1           true         PodTemplate
replicationcontrollers   rc           v1           true         ReplicationController
resourcequotas           quota        v1           true         ResourceQuota
secrets                               v1           true         Secret
serviceaccounts          sa           v1           true         ServiceAccount
services                 svc          v1           true         Service
...

Kubernetes Custom Resources

Custom Resources,顧名思義是指我們可以創造自定義的 API Resources 安裝到 Kubernetes 裡面來擴充它。

根據官方文件,創造 Custom Resources 有兩種方式,但最常用的是使用 Custom Resource Definition (CRD),因此這邊只討論 CRD。

其實 CRD 自己本身也是一種 API Resource,藉由以下指令便可以很清楚看到:

$ kubectl api-resources | grep -i custom
customresourcedefinitions   crd,crds   apiextensions.k8s.io/v1   false   CustomResourceDefinition

想想我們平常是怎麼創建 Resources 的,通常是直接寫一個 YAML 檔,然後直接用 kubectl apply 去創建,所以其實創建 CRD 的步驟也一樣。

首先創建一個檔案叫做 chishengliu-crd.yaml,內容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: chishenglius.chishengliu.com
spec:
  group: chishengliu.com
  scope: Namespaced
  names:
    plural: chishenglius
    singular: chishengliu
    kind: ChiShengLiu
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                mood:
                  type: string

之後執行以下指令

$ kubectl apply -f chishengliu-crd.yaml
customresourcedefinition.apiextensions.k8s.io/chishenglius.chishengliu.com created

$ kubectl api-resources | grep -i chishengliu
chishenglius   chishengliu.com/v1   true   ChiShengLiu

可以發現現在叢集裡面就多一個新的 Resouce 叫做 ChiShengLiu 了。

然後要創建 ChiShengLiu 這種 Resource 的話,一樣是寫一個 YAML 檔然後 kubectl apply。創一個檔案叫做 happy-chishengliu.yaml,內容如下:

1
2
3
4
5
6
apiVersion: chishengliu.com/v1
kind: ChiShengLiu
metadata:
  name: happy-chishengliu
spec:
  mood: "happy"

然後執行以下指令:

$ kubectl apply -f happy-chishengliu.yaml
chishengliu.chishengliu.com/happy-chishengliu created

$ kubectl describe chishengliu happy-chishengliu
Name:         happy-chishengliu
Namespace:    default
Labels:       <none>
Annotations:  <none>
API Version:  chishengliu.com/v1
Kind:         ChiShengLiu
Metadata:
  Creation Timestamp:  2024-08-28T17:37:57Z
  Generation:          1
  Resource Version:    1609
  UID:                 3cbc6964-2c7b-4e60-b113-4fa5f4dd0b3c
Spec:
  Mood:  happy
Events:  <none>

可以看到我們創了一個 ChiShengLiu 的 Resource,名字是 happy-chishengliu

Kubernetes Operator

空有 Custom Resource 並沒有任何用處,可以發現我們創了這個 ChiShengLiu 的 Resource 之後,Kubernetes 叢集並沒有發生任何變化,與內建的 Resources 非常不同。

內建的 Resources 之所以會有功能,是因為叢集裡面有對應的 Controller 在運作,Controller 的工作是負責監聽叢集內的某些 Resources,然後把叢集調整成該 Resource 在 spec 裡面宣告的狀態。例如 Replication Controller 就是會監聽所有叢集內的 ReplicaSet,當有任何 ReplicaSet 被創建、更新、刪除時,把叢集調整成對應的狀態,也就是創出正確數量的 Pods。

因此,如果要讓我們先前創的這個 ChiShengLiu 的 Resource 有作用,我們必須安裝一個 ChiShengLiu 的 Controller 到叢集裡面,這個 Controller 當然沒有內建,必須自己寫,所以叫做 Custom Controller,也稱作 Kubernetes Operator,官方文件稱這個模式為 Operator Pattern。

Kubernetes Operator 最常見的用途是封裝底層邏輯,尤其是框架或工具的開發者,讓使用者可以用 kubectl apply 一個 YAML 檔便可以安裝完畢,其餘的事情 Operator 會幫你處理。

那要怎麼寫 Kubernetes Operator 呢?歡迎關注本系列文的後續更新。

參考資料