k8sのOperator Tutorial(Go版)をする
以下
Create a new project
初期化
Appleシリコンなので--plugins=go/v4を忘れない
code:_
$ mkdir memcached-operator
$ cd memcached-operator
$ operator-sdk init --domain example.com --repo github.com/example/memcached-operator --plugins=go/v4
code:生成されるディレクトリ構造
) tree .
.
├── Dockerfile
├── Makefile
├── PROJECT
├── README.md
├── cmd
│ └── main.go
├── config
│ ├── default
│ │ ├── cert_metrics_manager_patch.yaml
│ │ ├── kustomization.yaml
│ │ ├── manager_metrics_patch.yaml
│ │ └── metrics_service.yaml
│ ├── manager
│ │ ├── kustomization.yaml
│ │ └── manager.yaml
│ ├── manifests
│ │ └── kustomization.yaml
│ ├── network-policy
│ │ ├── allow-metrics-traffic.yaml
│ │ └── kustomization.yaml
│ ├── prometheus
│ │ ├── kustomization.yaml
│ │ ├── monitor.yaml
│ │ └── monitor_tls_patch.yaml
│ ├── rbac
│ │ ├── kustomization.yaml
│ │ ├── leader_election_role.yaml
│ │ ├── leader_election_role_binding.yaml
│ │ ├── metrics_auth_role.yaml
│ │ ├── metrics_auth_role_binding.yaml
│ │ ├── metrics_reader_role.yaml
│ │ ├── role.yaml
│ │ ├── role_binding.yaml
│ │ └── service_account.yaml
│ └── scorecard
│ ├── bases
│ │ └── config.yaml
│ ├── kustomization.yaml
│ └── patches
│ ├── basic.config.yaml
│ └── olm.config.yaml
├── go.mod
├── go.sum
├── hack
│ └── boilerplate.go.txt
└── test
├── e2e
│ ├── e2e_suite_test.go
│ └── e2e_test.go
└── utils
└── utils.go
16 directories, 36 files
Manager
Create a new API and Controller
code:_
$ operator-sdk create api --group cache --version v1alpha1 --kind Memcached --resource --controller
オプションの意味(GVK)
以下3つをあわせてGVKで、リソースが一意に特定される
group
グループ。全体の大きなくくり
version
バージョン。k8sではv1alpha1のように開発中バージョンは命名するらしい
kind
グループ内の具体的なリソース
以下のようなレイアウトでできる
apiにgroupが明示的に現れてこないのはシングルグループ・レイアウト(デフォルト)だかららしい
operator-sdk edit --multigroup=trueで後から修正可能
code:_
) tree config/samples
config/samples
├── cache_v1alpha1_memcached.yaml
└── kustomization.yaml
1 directory, 2 files
) tree api
api
└── v1alpha1
├── groupversion_info.go
├── memcached_types.go
└── zz_generated.deepcopy.go
2 directories, 3 files
Define the API
原則として、作成したAPIごとにそれを管理するControllerを1つ設けることが推奨
以下構造体を作成する
type MemcachedSpec struct
Memcachedのdesired state用
type MemcachedStatus struct
Memcachedの観測値
type Memcached struct
上記のMemcachedSpecとMemcachedStatusをkindに紐付けるためのもの
kubectl applyでyamlを構造体にマッピングするために必要
コメントのマーカ+kubebuilder:subresource:statusも重要
statusをサブリソース化するという指示
サブリソースを有効にすると、KubernetesのRBAC(ロールベースアクセス制御)で「ユーザーは本体は更新できるが、/status は更新できない」「Operatorだけが /status を更新できる」といった権限分離が可能に
Generating CRD manifests
サンプルではmain.goとなっているが、編集対象はcmd/main.go
最新のOperator SDK(Kubebuilder v4レイアウト)でルート直下ではなくこちらに配置されるようになったらしい
編集箇所
サンプルのif err = (&controllers.MemcachedReconciler{で検索をかけて
Recorder: mgr.GetEventRecorderFor("memcached-controller"),を追記する
Resources watched by the Controller
internal/controller/memcached_controller.goを編集する
サンプルは例のごとく古いディレクトリ構成
importの修正およびSetupWithManagerにOwns(&appsv1.Deployment{}).を追加
Ownsは次の意味がある
Operatorが立ち上げたPod(Deployment)の変更があった際にReconcileループをトリガーできるように
これがないと子の変更があった場合のトリガーができない
Controller Configurations
SetupWithManager関数で設定可能なオプションについての解説
MaxConcurrentReconcilesはReconcileループのワーカー数を指定する
指定しない場合は1
1以外を指定する場合はスレッドセーフとなるように気をつける必要がある
Predicatesについて
サンプルはないが、Reconcileループをトリガーするためのイベントの叙述関数を追加することができる
特定ステータスは無視するなど
Reconcile loop
編集対象は引き続きinternal/controller/memcached_controller.go
引数について