k8sのOperator Tutorial(Go版)をする
#k8s
以下
https://sdk.operatorframework.io/docs/building-operators/golang/tutorial/
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
引数について