自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Kubernetes CRD & Operator 簡介

開發(fā) 云原生
Kubernetes 的 CRD? 和 Operator? 機(jī)制為用戶提供了強(qiáng)大的擴(kuò)展性。CRD? 允許用戶自定義資源,而 Operators 則可以管理這些資源。

Kubernetes CRD

在 kubernetes 中有一系列內(nèi)置的資源,諸如:pod、deployment、configmap、service …… 等等,它們由 k8s 的內(nèi)部組件管理。而除了這些內(nèi)置資源之外,k8s 還提供了另外一種方式讓用戶可以隨意地自定義資源,這就是 CRD (全稱 CustomResourceDefinitions) 。

例如,我可以通過 CRD 去定義一個(gè) mypod、myjob、myanything 等等資源,一旦注冊(cè)成功,那么這些自定義資源便會(huì)享受與內(nèi)置資源相同的待遇。具體而言就是:

  • 我們可以像使用 kubectl 增刪改查 deployment 一樣去操作這些 CRD 自定義資源。
  • CRD 自定義資源的數(shù)據(jù)跟 pod 等內(nèi)置資源一樣會(huì)存儲(chǔ)到 k8s 控制平面的 etcd 中。

需要注意的是,CRD 在不同的語境下有不同的含義,有時(shí)候可能只是指 k8s 中的 CustomResourceDefinitions 這一種特定的資源,有時(shí)候也可能是指用戶通過 CRD 所創(chuàng)建出來的自定義資源。

狹義上的 CRD (全稱 CustomResourceDefinitions) 是 k8s 中的一種特殊的內(nèi)置資源,我們可以通過它去創(chuàng)建我們自定義的其它資源。例如,我們可以通過 CRD 去創(chuàng)建一個(gè)叫 CronTab 的資源:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  # 名稱必須匹配 <plural>.<group>
  name: crontabs.stable.example.com
spec:
  # group 名稱,用于 REST API: /apis/<group>/<version>
  group: stable.example.com
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            # 定義屬性
            spec:
              type: object
              properties:
                cronSpec:
                  type: string
                image:
                  type: string
  # 作用范圍可以是 Namespaced 或者 Cluster
  scope: Namespaced
  names:
    # 復(fù)數(shù)名稱,使用于 URL: /apis/<group>/<version>/<plural>
    plural: crontabs
    # 單數(shù)名稱,可用于 CLI
    singular: crontab
    # 駝峰單數(shù),用于資源清單
    kind: CronTab
    # 名字簡寫,可用于 CLI
    shortNames:
    - ct

一旦我們 apply 這個(gè) yaml 文件,那么我們的自定義資源 CronTab 也就注冊(cè)到 k8s 了。這個(gè)時(shí)候我們就可以任意操作這個(gè)自定義資源,比如 my-crontab.yaml:

apiVersion: "stable.example.com/v1"
kind: CronTab
metadata:
  name: my-new-cron-object
spec:
  cronSpec: "* * * * */5"
  image: my-awesome-cron-image

執(zhí)行 kubectl apply -f my-crontab.yaml 就可以創(chuàng)建我們自定義的 CronTab,執(zhí)行 kubectl get crontab 就可以查詢到我們自定義的 CronTab 列表。

通過 CRD 自定義資源的優(yōu)點(diǎn)是,我們無需操心自定義資源的數(shù)據(jù)存儲(chǔ),也無需再額外實(shí)現(xiàn)一個(gè) http server 去對(duì)外暴露操作這些自定義資源的 API 接口,因?yàn)檫@些 k8s 都幫我們做好了,我們只需要像其它內(nèi)置資源一樣使用自定義資源即可。

但是!只有 CRD 往往是不夠的,例如上文中我們執(zhí)行 kubectl apply -f my-crontab.yaml 創(chuàng)建了一個(gè) crontab 自定義資源,但是這個(gè) crontab 不會(huì)有任何執(zhí)行的內(nèi)容(不會(huì)跑任何程序),而很多場(chǎng)景下我們是希望自定義資源能夠執(zhí)行點(diǎn)什么。這個(gè)時(shí)候我們就需要 Operator 了。

Operator

Operator 其實(shí)就是 custom resource controller(自定義資源的控制器),它干的事情就是監(jiān)聽自定義資源的變更,然后針對(duì)性地做一些操作。例如,監(jiān)聽到某個(gè)自定義資源被創(chuàng)建后,Operator 可以讀取這個(gè)自定義資源的屬性然后創(chuàng)建一個(gè) pod 去運(yùn)行具體的程序,并將這個(gè) pod 綁定到自定義資源對(duì)象上。

那 Operator 以何種方式存在呢?其實(shí)它跟普通的服務(wù)一樣,可以是 deployment,也可以是 statefuleSet。

至于常說的 Operator pattern 其實(shí)就是 CRD + custom controller 這種模式。

Kubebuilder

我們?cè)跇?gòu)建項(xiàng)目時(shí)常常希望有一個(gè)好用的框架,能夠提供一系列工具幫助開發(fā)者更輕松地進(jìn)行創(chuàng)建、測(cè)試和部署。而針對(duì) CRD 和 Operator 的場(chǎng)景就有這么一個(gè)框架 Kubebuilder。

接下來我將會(huì)使用 Kubebuilder 創(chuàng)建一個(gè)小項(xiàng)目,其中會(huì)創(chuàng)建一個(gè)自定義資源 Foo ,并在 controller 中監(jiān)聽這個(gè)資源的變更并把它打印出來。

1. 安裝

# download kubebuilder and install locally.
curl -L -o kubebuilder "https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)"
chmod +x kubebuilder && mv kubebuilder /usr/local/bin/

2. 創(chuàng)建一個(gè)測(cè)試目錄

mkdir kubebuilder-test
cd kubebuilder-test

3. 初始化項(xiàng)目

kubebuilder init --domain mytest.domain --repo mytest.domain/foo

4. 定義 CRD

假設(shè)我們想要定義一個(gè)如下格式的 CRD:

apiVersion: "mygroup.mytest.domain/v1"
kind: Foo
metadata:
  name: xxx
spec:
  image: image
  msg: message

那么我們需要?jiǎng)?chuàng)建一個(gè) CRD(本質(zhì)上也是創(chuàng)建一個(gè) API ):

kubebuilder create api --group mygroup --version v1 --kind Foo

執(zhí)行之后輸入 y 確認(rèn)生成,然后 kubebuilder 會(huì)幫我們自動(dòng)創(chuàng)建一些目錄和文件,其中:

  • api/v1/foo_types.go 文件中定義了這個(gè) CRD(也是 API)。
  • internal/controllers/foo_controller.go 文件則是控制 CRD 的業(yè)務(wù)邏輯。

由于自動(dòng)生成的文件只是一個(gè)基本框架,我們需要按照自己的需求進(jìn)行相應(yīng)的修改。

a. 在代碼中修改 CRD 的結(jié)構(gòu)

首先,修改 api/v1/foo_types.go 調(diào)整 CRD 的結(jié)構(gòu)(注意不要?jiǎng)h除 //+kubebuilder 這種注釋):

// FooSpec defines the desired state of Foo
type FooSpec struct {
    Image string `json:"image"`
    Msg   string `json:"msg"`
}

// FooStatus defines the observed state of Foo
type FooStatus struct {
    PodName string `json:"podName"`
}

b. 通過命令自動(dòng)生成 CRD yaml

執(zhí)行 make manifests 命令之后,kubebuilder 就會(huì)在 config/crd/bases 目錄下生成一個(gè) mygroup.mytest.domain_foos.yaml 文件,這個(gè)文件就是我們定義 CRD 的 yaml 文件:

---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  annotations:
    controller-gen.kubebuilder.io/version: v0.13.0
  name: foos.mygroup.mytest.domain
spec:
  group: mygroup.mytest.domain
  names:
    kind: Foo
    listKind: FooList
    plural: foos
    singular: foo
  scope: Namespaced
  versions:
  - name: v1
    schema:
      openAPIV3Schema:
        description: Foo is the Schema for the foos API
        properties:
          apiVersion:
            description: 'APIVersion defines the versioned schema of this representation
              of an object. Servers should convert recognized schemas to the latest
              internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
            type: string
          kind:
            description: 'Kind is a string value representing the REST resource this
              object represents. Servers may infer this from the endpoint the client
              submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
            type: string
          metadata:
            type: object
          spec:
            description: FooSpec defines the desired state of Foo
            properties:
              image:
                type: string
              msg:
                type: string
            required:
            - image
            - msg
            type: object
          status:
            description: FooStatus defines the observed state of Foo
            properties:
              podName:
                type: string
            required:
            - podName
            type: object
        type: object
    served: true
    storage: true
    subresources:
      status: {}

make manifests 指令執(zhí)行的具體內(nèi)容定義在了 Makefile 文件中:

.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
    $(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases

從中可以看到其實(shí) kubebuilder 使用了 controller-gen 工具去掃描代碼中特定格式的注釋(如 //+kubebuilder:...)進(jìn)而生成的 CRD yaml 文件。

5. 補(bǔ)充 controller 邏輯

假設(shè)我們要監(jiān)聽用戶創(chuàng)建的自定義資源 Foo 然后把它的屬性打印出來。

a. 修改 controller 補(bǔ)充業(yè)務(wù)邏輯

修改 internal/controllers/foo_controller.go 文件補(bǔ)充我們自己的業(yè)務(wù)邏輯,如下:

func (r *FooReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    l := log.FromContext(ctx)

    // 補(bǔ)充業(yè)務(wù)邏輯
    foo := &mygroupv1.Foo{}
    if err := r.Get(ctx, req.NamespacedName, foo); err != nil {
        l.Error(err, "unable to fetch Foo")
        return ctrl.Result{}, client.IgnoreNotFound(err)
    }

    // 打印 Foo 屬性
    l.Info("Received Foo", "Image", foo.Spec.Image, "Msg", foo.Spec.Msg)

    return ctrl.Result{}, nil
}

// SetupWithManager sets up the controller with the Manager.
func (r *FooReconciler) SetupWithManager(mgr ctrl.Manager) error {
    return ctrl.NewControllerManagedBy(mgr).
        For(&mygroupv1.Foo{}).
        Complete(r)
}

b. 進(jìn)行測(cè)試

注意:測(cè)試需要有本地或遠(yuǎn)程的 k8s 集群環(huán)境,其將會(huì)默認(rèn)使用跟當(dāng)前 kubectl 一致的環(huán)境。

執(zhí)行 make install 注冊(cè) CRD ,從 Makefile 中可以看到其實(shí)際執(zhí)行了如下指令:

.PHONY: install
install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
    $(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f -

執(zhí)行 make run 運(yùn)行 controller,從 Makefile 中可以看到其實(shí)際執(zhí)行了如下指令:

.PHONY: run
run: manifests generate fmt vet ## Run a controller from your host.
    go run ./cmd/main.go

然后可以看到如下輸出:

...
go fmt ./...
go vet ./...
go run ./cmd/main.go
2023-12-19T15:14:18+08:00       INFO    setup   starting manager
2023-12-19T15:14:18+08:00       INFO    controller-runtime.metrics      Starting metrics server
2023-12-19T15:14:18+08:00       INFO    starting server {"kind": "health probe", "addr": "[::]:8081"}
2023-12-19T15:14:18+08:00       INFO    controller-runtime.metrics      Serving metrics server  {"bindAddress": ":8080", "secure": false}
2023-12-19T15:14:18+08:00       INFO    Starting EventSource    {"controller": "foo", "controllerGroup": "mygroup.mytest.domain", "controllerKind": "Foo", "source": "kind source: *v1.Foo"}
2023-12-19T15:14:18+08:00       INFO    Starting Controller     {"controller": "foo", "controllerGroup": "mygroup.mytest.domain", "controllerKind": "Foo"}
2023-12-19T15:14:19+08:00       INFO    Starting workers        {"controller": "foo", "controllerGroup": "mygroup.mytest.domain", "controllerKind": "Foo", "worker count": 1}

我們提交一個(gè) foo.yaml 試試:

apiVersion: "mygroup.mytest.domain/v1"
kind: Foo
metadata:
  name: test-foo
spec:
  image: test-image
  msg: test-message

執(zhí)行 kubectl apply -f foo.yaml 之后我們就會(huì)在 controller 的輸出中看到 foo 被打印了出來:

2023-12-19T15:16:00+08:00       INFO    Received Foo    {"controller": "foo", "controllerGroup": "mygroup.mytest.domain", "controllerKind": "Foo", "Foo": {"name":"test-foo","namespace":"aries"}, "namespace": "aries", "name": "test-foo", "reconcileID": "8dfd629e-3081-4d40-8fc6-bcc3e81bbb39", "Image": "test-image", "Msg": "test-message"}

這就是使用 kubebuilder 的一個(gè)簡單示例。

總結(jié)

Kubernetes 的 CRD 和 Operator 機(jī)制為用戶提供了強(qiáng)大的擴(kuò)展性。CRD 允許用戶自定義資源,而 Operators 則可以管理這些資源。正是這種擴(kuò)展機(jī)制為 Kubernetes 生態(tài)系統(tǒng)提供了極大的靈活性和可塑性,使得它可以更廣泛的應(yīng)用于各種場(chǎng)景中。

參考資料:

  • https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/
  • https://kubernetes.io/docs/concepts/extend-kubernetes/operator/
  • https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/
  • https://book.kubebuilder.io/introduction
責(zé)任編輯:趙寧寧 來源: 系統(tǒng)架構(gòu)師Go
相關(guān)推薦

2023-11-10 15:05:08

Kubernetes云計(jì)算

2023-05-06 08:00:00

KubernetesK8s數(shù)據(jù)服務(wù)自動(dòng)化

2023-02-10 07:39:58

云原生KubernetesCRD

2021-05-06 09:33:32

OperatorKubernetes開源

2022-05-18 07:30:51

OperatorprometheusVM 集群

2022-08-04 08:00:54

安全管理服務(wù)器

2022-09-07 15:57:41

KubernetesCRD

2024-07-08 08:11:15

2022-12-26 16:34:51

開源云原生

2023-05-03 21:54:05

Kubernetes自動(dòng)化診斷工具

2024-05-06 08:08:31

2024-05-10 08:00:48

K8soperatorGitHub

2023-12-18 09:08:40

IstioSidecar代理服務(wù)

2011-08-24 14:35:33

DROP OPERAT中文man

2011-08-24 11:23:20

CREATE OPER中文man

2021-11-08 09:00:00

PrometheusKubernetes集群

2020-01-06 09:00:34

容器CRD安全

2023-12-07 07:23:39

APIsSDKs

2019-04-23 09:48:21

KubernetesPostgreSQL

2022-03-14 08:00:00

KoolKits工具開發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)