Kubernetes CRD とオペレーターの紹介

Kubernetes CRD とオペレーターの紹介

Kubernetes の CRD

Kubernetes には、pod、deployment、configmap、service など、k8s の内部コンポーネントによって管理される一連の組み込みリソースがあります。これらの組み込みリソースに加えて、k8s では、ユーザーが自由にリソースをカスタマイズできる別の方法、CRD (フルネーム CustomResourceDefinitions) も提供されています。

たとえば、CRD を使用して、mypod、myjob、myanything などのリソースを定義できます。正常に登録されると、これらのカスタム リソースは組み込みリソースと同じように扱われます。具体的には:

  • kubectl を使用してデプロイメントを追加、削除、変更、クエリするのと同じように、これらの CRD カスタム リソースを操作できます。
  • CRD カスタム リソースのデータは、pod などの組み込みリソースと同様に、k8s コントロール プレーンの etcd に保存されます。

CRD は状況によって意味が異なることに注意してください。場合によっては、特定のリソース (k8s の CustomResourceDefinitions) を参照することもあれば、CRD を通じてユーザーが作成したカスタム リソースを参照することもあります。

狭義では、CRD (フルネーム CustomResourceDefinitions) は k8s の特別な組み込みリソースであり、これを使用して他のカスタマイズされたリソースを作成できます。たとえば、CRD を通じて 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: # 复数名称,使用于URL: /apis/<group>/<version>/<plural> plural: crontabs # 单数名称,可用于CLI singular: crontab # 驼峰单数,用于资源清单kind: CronTab # 名字简写,可用于CLI shortNames: - ct

この yaml ファイルを適用すると、カスタム リソース CronTab が k8s に登録されます。現時点では、my-crontab.yaml などのこのカスタム リソースを任意に操作できます。

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

kubectl apply -f my-crontab.yaml を実行してカスタマイズされた CronTab を作成し、 kubectl get crontab を実行してカスタマイズされた CronTab リストを照会します。

CRD を通じてリソースをカスタマイズする利点は、カスタム リソースのデータ ストレージについて心配する必要がなく、これらのカスタム リソースを操作するための API インターフェイスを公開するために追加の http サーバーを実装する必要がないことです。これは、k8s がこれらすべてを実行してくれるためです。他の組み込みリソースと同様に、カスタム リソースのみを使用する必要があります。

しかし! CRD だけでは不十分な場合がよくあります。たとえば、上記の例では、kubectl apply -f my-crontab.yaml を実行して、crontab カスタム リソースを作成しました。ただし、この crontab には実行可能なコンテンツが含まれていません (プログラムは実行されません)。多くのシナリオでは、カスタム リソースで何かを実行できるようにする必要があります。このときにオペレーターが必要になります。

オペレーター

Operator は実際にはカスタム リソース コントローラーです。その役割は、カスタム リソースの変更を監視し、対象となる操作を実行することです。たとえば、カスタム リソースの作成を監視した後、Operator はカスタム リソースのプロパティを読み取り、特定のプログラムを実行するポッドを作成して、ポッドをカスタム リソース オブジェクトにバインドできます。

では、Operator はどのように存在するのでしょうか?実際のところ、通常のサービスと同じです。デプロイメントまたはステートフル セットにすることができます。

よく言われる Operator パターンは、実際には CRD + カスタム コントローラー モデルです。

キューブビルダー

プロジェクトを構築するとき、開発者がより簡単に作成、テスト、デプロイできるようにするための一連のツールを提供できる優れたフレームワークが欲しいと思うことがよくあります。 CRD および Operator シナリオには、Kubebuilder と呼ばれるフレームワークがあります。

次に、Kubebuilder を使用して小さなプロジェクトを作成します。このプロジェクトでは、カスタム リソース Foo を作成し、コントローラーでこのリソースの変更を監視して出力します。

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. テストディレクトリを作成する

mkdir kubebuilder-test cd kubebuilder-test

3. プロジェクトを初期化する

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

4. CRDを定義する

次の形式で CRD を定義するとします。

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

次に、CRD を作成する必要があります (基本的には API を作成します)。

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

実行後、生成を確認するために y を入力すると、kubebuilder によって次のようなディレクトリとファイルが自動的に作成されます。

  • この CRD (および API) は、api/v1/foo_types.go ファイルで定義されています。
  • internal/controllers/foo_controller.go ファイルは、CRD のビジネス ロジックを制御します。

自動的に生成されたファイルは単なる基本的なフレームワークなので、必要に応じて変更する必要があります。

a.コード内のCRD構造を変更する

まず、api/v1/foo_types.go を変更して CRD の構造を調整します (//+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.コマンドを使用してCRD yamlを自動的に生成する

make manifests コマンドを実行すると、kubebuilder は config/crd/bases ディレクトリに mygroup.mytest.domain_foos.yaml ファイルを生成します。このファイルは、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 コマンドによって実行される具体的な内容は、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

このことから、kubebuilder は controller-gen ツールを使用して、コード内の特定の形式 (//+kubebuilder:... など) のコメントをスキャンし、CRD yaml ファイルを生成していることがわかります。

5. コントローラーロジックを追加する

ユーザーが作成したカスタム リソース Foo を監視し、そのプロパティを出力したいとします。

a.コントローラーを変更してビジネスロジックを追加する

次のように、internal/controllers/foo_controller.go ファイルを変更して、独自のビジネス ロジックを追加します。

 func (r *FooReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { l := log.FromContext(ctx) // 补充业务逻辑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.テストを実施する

注: テストにはローカルまたはリモートの k8s クラスター環境が必要です。デフォルトでは、現在の kubectl と同じ環境が使用されます。

CRD を登録するには、make install を実行します。 Makefile から、実際に次の命令が実行されていることがわかります。

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

コントローラーを実行するには、make run を実行します。 Makefile から、実際に次の命令が実行されていることがわかります。

 .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}

foo.yaml を送信して試してみましょう:

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

kubectl apply -f foo.yaml を実行すると、コントローラーの出力に 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 を使用する簡単な例です。

要約する

Kubernetes の CRD および Operator メカニズムは、ユーザーに強力なスケーラビリティを提供します。 CRD を使用すると、ユーザーはリソースをカスタマイズでき、オペレーターはこれらのリソースを管理できます。この拡張メカニズムにより、Kubernetes エコシステムに優れた柔軟性と可塑性が提供され、さまざまなシナリオでより広く使用できるようになります。

参考文献:

  • 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-settings/
  • https://book.kubebuilder.io/introduction

<<:  これらのKubernetes Podスキルを習得し、企業にとって必須のスキルになりましょう

>>:  Kubernetes リースと分散リーダー選出

推薦する

インターネット製品モデル = 優れた遺伝子 + 資本グループ

まもなく完了するPPTVへの投資について、皆さんはどう思っているか分かりません。最近のウェブサイトの...

BaiduとGoogleの違い

Baidu と Google の違いについて議論し、Baidu と Google の違いについて良い...

ウェブサイトのトラフィックを効果的に増やすために私がまとめたいくつかの方法

交通の重要性ウェブサイトが人気があるかどうかを評価するには、ウェブサイトのトラフィックの量から大体の...

大銀希生はGoogleとBaiduのホームページからウェブサイトのプロモーションを見る

春節までまだ1週間ありますが、春節のウェブサイトのメンテナンスとマーケティングはすでに一部のウェブサ...

インターネット大手企業間の「内紛」戦争

新年に入ってわずか半月で、インターネット大手は頻繁に「戦い」始めた。まず、テンセントのゲームがファー...

Douban の興味関心マーケティングへの道: 忍耐が明るい未来につながる

興味関心マーケティング。ソーシャルメディアの発展は、現在、盛んな状況を示しています。さまざまなユーザ...

顧客の視点からBaiduのレコメンデーションエンジンについて語る

今日、たまたまフォーラムを訪れて、いつものように外部リンクを投稿しました。今は必要がないので、他の人...

Google の最新 PR アルゴリズムの解釈: 新規サイトの PR がわずか 8 か月で 0 から 5 に増加

Google の最新 PR アルゴリズムの解釈: 新規サイトの PR がわずか 8 か月で 0 から...

クラウドコンピューティングの時代において、マルチクラウド環境のコストをどのように配分し、管理すればよいのでしょうか?

マルチクラウド環境は企業にとって多くのメリットをもたらしますが、適切な管理がなければコストの配分が難...

Weiboマーケティングは、競争の激しいケータリング業界で目立つことを可能にします

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービス飲食業界は、あらゆる業界...

初心者ウェブマスターがSEOトレーニングの経験をシェア

正直に言うと、私がウェブマスター業界に関わるようになったのはごく最近のことです。周りの同僚のほとんど...

2018 年のクラウド コンピューティング: ハイブリッド、エッジ、AI

時が経ち、2018 年半ばには、クラウド コンピューティングに対する企業の姿勢も変化しています。 I...

SEO統合マーケティング最適化プロセスの簡単な分析

SEO という言葉は、インターネット業界で働く個人や上司にとって、馴染みのある言葉です。聞けば聞くほ...