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 リースと分散リーダー選出

推薦する

Baidu K Station の裏にある真実: ウェブマスターが宣戦布告する無駄なものにとらわれないようにしましょう

6月28日のBaidu Kステーション事件は、2012年にインターネットに影響を与えた最もホットな出...

企業のウェブサイトを最適化するためのキーワードの配置方法を巧みに解釈する

インターネットの発展は企業にますます大きな影響をもたらしています。インターネット販売プラットフォーム...

オープンソースの Apache Cassandra、Kafka、Spark、ES はいつ使用すべきで、いつ使用すべきではないのでしょうか?

[51CTO.com クイック翻訳] ほぼすべてのテクノロジーに関する決定は、企業がビジネス目標を達...

低学歴のギャングが百度のプロモーションアカウントに簡単に侵入し、100件以上の詐欺行為を行った

原題:百度のプロモーションアカウントへのハッキングによる詐欺事件が100件以上発生北京ニュース(記者...

ケース分析: オンライン旅行電子商取引はどのようにマーケティングを行うのか?

国内の旅行会社でECに取り組み始めたばかりの企業の多くは、臨時でチームを立ち上げるケースが多く、マー...

ウェブサイトの内部ページで記事の収集を高速化する方法についての簡単な説明

草の根ウェブマスターにとって、検索エンジンでの自社ウェブサイトのパフォーマンスは特に重要です。資金力...

宝月中新小売フォーラム - 企業はどのように新しいマーケティングモデルに変革できるか?

月収10万元の起業の夢を実現するミニプログラム起業支援プラン要約:新しい消費時代と新しいモバイル イ...

Amazon Elasticsearch Service が Amazon OpenSearch Service に

AWSは、クラウドサービス製品「Amazon Elasticsearch Service」の名称を「...

UCloudのコアセキュリティ製品は公安省から販売ライセンスを取得しました

最近、UCloudのYoudunシリーズの5つのコアセキュリティ製品は、公安部コンピュータ情報システ...

SEOテクノロジーの簡単な分析

私の論理的思考は非常に混乱しているため、テクノロジーに関する記事を書くことはほとんどありません。昨夜...

Douyu Liveは本当に停滞しているのか?

ゲームライブストリーミング分野での長年にわたる深い開拓を経て、2大ゲームライブストリーミングプラット...

Weiboプロモーションをうまく行うにはどうすればいいでしょうか?

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービス現在、ほぼすべての人が ...

Kubernetes以降の時代におけるK8Sの12の主要機能を紹介します

導入: Kubernetes は最近大流行しており、すべての主要なクラウド サービス プロバイダーが...

過去1年間のアリババクラウドハイブリッドクラウド:18の省政府クラウドにサービスを提供

2020 年を振り返ると、この流行はクラウド コンピューティングの発展に大きな影響を与えました。調査...