コントローラーランタイムはオペレーター開発環境を構築します

目次

基本構造

CRDの挿入


基本構造

まず対応する go pkg をダウンロードします

go get -u sigs.k8s.io/controller-runtime

次に、コントローラーとマネージャーを作成する必要があります

Operator の本質は再入可能なキュー プログラミング モードですが、Manager はリソース オブジェクトにアクセスするためのクライアント、キャッシュ、スキームを含むコントローラーとアドミッション Webhook の管理に使用でき、シンプルな依存関係注入メカニズムと正常なシャットダウン待機のための信号処理メカニズムを提供します。

 公式ドキュメントのサンプルコードを参照してください

opsController.go

package kube

import (
	"context"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/reconcile"
)

type OpsController struct {
	client.Client
}

func NewOpsController() *OpsController {
	return &OpsController{}
}

func (a *OpsController) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {
	return reconcile.Result{}, nil
}

func (a *OpsController) InjectClient(c client.Client) error {
	a.Client = c
	return nil
}

まず、Ingress などの公式リソース (後でマネージャーで指定する必要があります) をリッスンするため、次のようにチューニング機能を完了します。

func (a *OpsController) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {
	resource := &v1.Ingress{}
	a.Client.Get(ctx, req.NamespacedName, resource)
	fmt.Println(resource)
	return reconcile.Result{}, nil
}

新しい Ingress オブジェクトが Apiserver に送信されると、構造全体がコンソールに表示されます。

package kube

import (
	v1 "k8s.io/api/networking/v1"
	"os"

	"sigs.k8s.io/controller-runtime/pkg/builder"
	"sigs.k8s.io/controller-runtime/pkg/client/config"

	logf "sigs.k8s.io/controller-runtime/pkg/log"
	"sigs.k8s.io/controller-runtime/pkg/log/zap"
	"sigs.k8s.io/controller-runtime/pkg/manager"
	"sigs.k8s.io/controller-runtime/pkg/manager/signals"
)

func InitManager() {
	logf.SetLogger(zap.New())

	var log = logf.Log.WithName("builder-examples")

	mgr, err := manager.New(config.GetConfigOrDie(), manager.Options{})
	if err != nil {
		log.Error(err, "could not create manager")
		os.Exit(1)
	}

	err = builder.
		ControllerManagedBy(mgr).  // Create the ControllerManagedBy
		For(&v1.Ingress{}). // ReplicaSet is the Application API
		Complete(NewOpsController())
	if err != nil {
		log.Error(err, "could not create controller")
		os.Exit(1)
	}

	if err := mgr.Start(signals.SetupSignalHandler()); err != nil {
		log.Error(err, "could not start manager")
		os.Exit(1)
	}
}

このコードでは、新しく作成したController(複数のControllerで同時に管理可能)にIngressのコマンド権限を割り当て、オペレータのエントリ機能であるManagerを起動しています。

Ingress オブジェクトを送信するだけで、コンソール出力が表示されて終了です。

ここまでで、オペレーターの最も基本的な呼び出しプロセスが完了しました。

CRDの挿入

オペレーター=CRD+コントローラー+Webhook

実際の環境では、複雑なプロセス制御と期待の方向付けを完了するために、高度にカスタマイズされたリソースが必要になることがよくあります。

したがって、このセクションでは CRD を生成し、CR の監視と制御を完了します。

ソース コードには、上記の実装のデモであるサンプル コードも含まれています。

このうち、CRD宣言、ディープコピー、外部公開登録機能が完成します。

Kubernetes によって正式にリリースされたコードジェネレーターには、このための実装コードもあります。

このデモによると、コントローラーが client-go を呼び出すときにマネージャー リスナー オブジェクトと逆シリアル化操作を作成するには、CRD のいくつかのプリセット フィールドに値を入力する必要があります。

Manager を起動する前に、CRD を Scheme に登録し、制御および割り当てコントローラーを CRD に追加する必要があります。

	err = v1.AddToScheme(mgr.GetScheme())
	if err != nil {
		log.Error(err, "could not register scheme")
	}

	err = builder.
		ControllerManagedBy(mgr). // Create the ControllerManagedBy
		For(&v1.Operation{}).     // ReplicaSet is the Application API
		Complete(NewOpsController())
	if err != nil {
		log.Error(err, "could not create controller")
		os.Exit(1)
	}

トリガーされたオブジェクトをコンソールに出力するようにチューニング関数を変更します。

func (a *OpsController) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) {
	resource := &v1.Operation{}
	err := a.Client.Get(ctx, req.NamespacedName, resource)
	if err != nil {
		return reconcile.Result{}, err
	}
	fmt.Println(resource)
	return reconcile.Result{}, nil
}

公式ドキュメント を参考に、yamlを編集して適用する必要がありますが、主にApiserverにオブジェクトを送信するためのフィールドの宣言も記載します。

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  # 名字必需与下面的 spec 字段匹配,并且格式为 '<名称的复数形式>.<组名>'
  name: operations.extensions.octoboy.com
spec:
  # 组名称,用于 REST API: /apis/<组>/<版本>
  group: extensions.octoboy.com
  # 列举此 CustomResourceDefinition 所支持的版本
  versions:
    - name: v1
      # 每个版本都可以通过 served 标志来独立启用或禁止
      served: true
      # 其中一个且只有一个版本必需被标记为存储版本
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                action:
                  type: string
  # 可以是 Namespaced 或 Cluster
  scope: Namespaced
  names:
    # 名称的复数形式,用于 URL:/apis/<组>/<版本>/<名称的复数形式>
    plural: operations
    # 名称的单数形式,作为命令行使用时和显示时的别名
    singular: operation
    # kind 通常是单数形式的驼峰命名(CamelCased)形式。你的资源清单会使用这一形式。
    kind: Operation
    # shortNames 允许你在命令行使用较短的字符串来匹配资源
    shortNames:
      - ops

 次に、Operator を起動し、オブジェクト yaml を書きます。

apiVersion: extensions.octoboy.com/v1
kind: Operation
metadata:
  name: myops
  namespace: default
spec:
  action: "restart"

 適用中にコンソール出力を観察します。

&{ {Operation extensions.octoboy.com/v1} {myops デフォルト 1344e481-4db4-461d-8d8d-b07713a76236 3927679 1 2023-03-07 14:21:09 +0800 CST <nil> <nil> マップ[] マップ[ kubectl.kubernetes.io/last-applied-configuration:{"apiVersion":"extensions.octoboy.com/v1","kind":"Operation","metadata":{"annotations":{},"name" :"myops","namespace":"default"},"spec":{"action":"restart"}} ] [] [] [{kubectl-client-side-apply Extensions.octoboy.com/v1 を更新し
ます2023-03-07 14:21:09 +0800 CST FieldsV1 {"f:metadata":{"f:annotations":{".":{},"f:kubectl.kubernetes.io/last-applied-configuration ":{}}},"f:spec":{".":{},"f:action":{}}} }]} {} {0001-01-01 00:00:00 +0000 UTC}}

これまでのところ、単純な Operator コントローラーがコントローラー ランタイムを通じて構築されています。

おすすめ

転載: blog.csdn.net/kingu_crimson/article/details/129366950