Kubernetes Custom Resource Deployment

Share on:

2020 It邦幫忙鐵人賽 系列文章

這邊改了一些大綱,原本的內容還有一些 kubernetes 的設定,以及 GCP 相關服務的介紹。但既然我們的主題是把東西搬上 k8s 的踩雷旅程,那我們就繼續搬,繼續踩。剩下的時間大概會有四個題目。

由於我比較熟悉 GCP / GKE 的服務,這篇的操作過程都會以 GCP 平台作為範例,不過操作過程大體上是跨平台通用的。

寫文章真的是體力活,覺得我的文章還有參考價值,請左邊幫我點讚按個喜歡,右上角幫我按個追縱,底下歡迎留言討論。給我一點繼續走下去的動力。

對我的文章有興趣,歡迎到我的網站上 https://chechia.net 閱讀其他技術文章,有任何謬誤也請各方大德直接聯繫我,感激不盡。

Exausted Cat Face


摘要

  • CRD 內容
  • Deploy CRD
  • Use custom resource

Recap

在上次的 cert-manager 內容中我們走過 cert-manager 的安裝步驟,其中有一個步驟是 apply cert-manager 的 manigests 檔案 *.yaml)

https://github.com/jetstack/cert-manager/tree/release-0.11/deploy/manifests

1$ git clone https://github.com/jetstack/cert-manager
2$ git checkout release-0.11
3$ ls deploy/manifest
4
500-crds.yaml
601-namespace.yaml
7BUILD.bazel	
8README.md	
9helm-values.yaml

我們快速看一下這個 00-crds.yaml,這個 yaml 非常長,直接跳到 certificates.certmanager.k8s.io

希望看 golang 源碼文件的話,可以搭配godoc.org/k8s.io/apiextensions 來閱讀,更能理解 definition。

在看之前先注意幾件事,CRD 內除了 schema 外,還定義了許多不同情境的使用資料。

  • CRD 內定義了 custom resource 的資料儲存 .spec.validation.openAPIV3Schema,使用 custom resource 會透過 validator 驗證
  • .openAPIV3Schema 內定義了 .spec,以及 rumtime 中紀錄 .status 的資料
    • controller 可以把狀態 sync 到 custom resource 的 .status 中紀錄
    • controller 可以比對 .spec 與 .status 來決定是否要 sync 以及如何 sync
  • CRD 內定義了與 server 以及 client 互動的方式,
    • names 中定義各種使用情境的 custom resource 名稱
    • additionalPrinterColumns 中添加 kubectl 中的顯示內容
 1// 這邊使用的是 v1beta1 的 API (deprecated at v1.16) ,新版開發建議使用 apiextension.k8s.io/v1 的 api
 2apiVersion: apiextensions.k8s.io/v1beta1
 3kind: CustomResourceDefinition
 4metadata:
 5  creationTimestamp: null
 6  name: certificates.cert-manager.io
 7spec:
 8  // 使用 kubectl 會額外顯示的資訊內容,透過 jsonpath 去 parse 顯示
 9  additionalPrinterColumns:
10  - JSONPath: .status.conditions[?(@.type=="Ready")].status
11    name: Ready
12    type: string
13  - JSONPath: .spec.secretName
14    name: Secret
15    type: string
16  - JSONPath: .spec.issuerRef.name
17    name: Issuer
18    priority: 1
19    type: string
20  - JSONPath: .status.conditions[?(@.type=="Ready")].message
21    name: Status
22    priority: 1
23    type: string
24  - JSONPath: .metadata.creationTimestamp
25    description: CreationTimestamp is a timestamp representing the server time when
26      this object was created. It is not guaranteed to be set in happens-before order
27      across separate operations. Clients may not set this value. It is represented
28      in RFC3339 form and is in UTC.
29    name: Age
30    type: date
31  group: cert-manager.io
32  // 定義 CRD 在不同情境下使用的名稱
33  names:
34    kind: Certificate
35    listKind: CertificateList
36    plural: certificates
37    shortNames:
38    - cert
39    - certs
40    singular: certificate
41  scope: Namespaced
42  subresources:
43    status: {}
44  validation:
45    // openAPIV3Schema 中是 custom resource 實際操作會使用的內容
46    // properties 使用 . .description .type ,分別定義名稱,描述,檢查型別
47    openAPIV3Schema:
48      description: Certificate is a type to represent a Certificate from ACME
49      properties:
50        apiVersion:
51          description: 'APIVersion defines the versioned schema of this representation
52            of an object. Servers should convert recognized schemas to the latest
53            internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
54          type: string
55        kind:
56          description: 'Kind is a string value representing the REST resource this
57            object represents. Servers may infer this from the endpoint the client
58            submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
59          type: string
60        // custom resource runtime 中的 metadata
61        metadata:
62          type: object
63        // custom resource 使用時的 spec,定義 custom resoure 的 desired status
64        spec:
65          ...
66        // custom controller 監測 custom resource 的 current status,這邊的資料完全視 controller 實作來產生,如果沒有實作 sync status,也可以沒有資料
67        status:
68          ...
69      type: object
70  // 這個是 CRD 物件的 version,可以定義多個不同 version 的 CRD,調用時需要註明版本
71  version: v1alpha2
72  versions:
73  - name: v1alpha2
74    served: true
75    storage: true
76// 這個是 CRD 物件的 status,描述 CRD 部署到 API server 的狀態,例如 CRD 儲存適用 configmap 的儲存空間,這邊顯示在 API server 上的儲存狀態。不要跟 custom resource 的 status 弄混了
77status:
78  acceptedNames:
79    kind: ""
80    plural: ""
81  conditions: []
82  storedVersions: []

helm-values.yaml 與 01-namespace.yaml 很單純,前者是使用 helm 部署的可設定參數,預設只有 kubernetes resources,後者則是為之後的 cert-manager 元件新增一個 kubernetes namespace。

小結 CRD 內容 (apiextensions/v1beta1)

  • CRD 顯示名稱,內容
  • CRD spec 驗證
    • custom resource
    • custom resource schema
  • CRD 自身部署狀態

部署

部署相較定義本身就非常簡單,直接 kubectl apply 到 kubernetes 上

使用 custom resource

有了 CRD,我們便可以使用 CRUD API,互動模式與其他 build-in kubernetes resources 相同,只是內容會照 CRD 上的定義調整

1kubectl get certificates.certmanager.k8s.io
2kubectl get certificates
3kubectl get certs --all-namespaces
4kubectl get cert -n cert-manager
5
6NAMESPACE          NAME                READY   SECRET              AGE
7cert-manager       ingress-nginx-tls   True    ingress-nginx-tls   221d

這邊看到的內容可能會有些落差,因為我當初用的版本比較舊,但內容大同小異。

底下的 describe 內容已經跟上面的 CRD 版本差太多,對不起來了。但我也懶得再佈一組,還要重做 dnsName 與 authotization challenge

直接讓大家感受一下舊版的內容XD

 1$ kubectl describe cert ingress-nginx-tls
 2
 3Name:         ingress-nginx-tls
 4Namespace:    cert-manager
 5API Version:  certmanager.k8s.io/v1alpha1
 6Kind:         Certificate
 7Metadata:
 8  Creation Timestamp:  2019-03-06T06:48:26Z
 9  Generation:          4
10  Owner References:
11    API Version:           extensions/v1beta1
12    Block Owner Deletion:  true
13    Controller:            true
14    Kind:                  Ingress
15    Name:                  ingress-nginx
16  Self Link:               /apis/certmanager.k8s.io/v1alpha1/namespaces/default/certificates/ingress-nginx-tls
17Spec:
18  Acme:
19    Config:
20      Domains:
21        chechiachang.com
22      Http 01:
23        Ingress:
24        Ingress Class:  nginx
25  Dns Names:
26    chechiachang.com
27  Issuer Ref:
28    Kind:       ClusterIssuer
29    Name:       letsencrypt-prod
30  Secret Name:  ingress-nginx-tls
31// 當前的 status,controller sync 上來
32// controller 會比對 .spec 與 .status,判斷是否需要做事,ex. renew
33Status:
34  Acme:
35    Order:
36      URL:  https://acme-v02.api.letsencrypt.org/acme/order/*
37  Conditions:
38    Last Transition Time:  2019-09-02T03:52:03Z
39    Message:               Certificate renewed successfully
40    Reason:                CertRenewed
41    Status:                True
42    Type:                  Ready
43    Last Transition Time:  2019-09-02T03:52:01Z
44    Message:               Order validated
45    Reason:                OrderValidated
46    Status:                False
47    Type:                  ValidateFailed
48Events:                    <none>

想要新增,可以回去看 cert-manager tutorial,這個是新版的文件

當然,不爽這個 cert resource 也可以幹掉

1$ kubectl delete cert ingress-nginx-tls -n cert-manager

以上

小結

  • 簡介 CRD 與 CRD 內容
  • 操作 custom resource