Kubebuilder で複数コントローラの RBAC をスマートに管理したい
kubebuilder で複数リソース、複数コントローラをモノリポ的に開発してる場合、コントローラ同士がそれぞれの CRD に依存していたりする。
そうすると RBAC のマーカーコメントを書き忘れたりしてデプロイ時にエラーで気づくということも多々ある。
なので最近は複数コントローラを一つのリポジトリで管理する場合は1つの Pod に全てのコントローラをまとめて起動して、RBAC も統合するという手法を取ってる。
自前で開発した以外のコントローラを混ぜると不要な権限を付与してしまう可能性があるのでおすすめしないが、全て自分で開発しているなら特に問題もないだろうと考えている。
まずリポジトリの構成としては下記のようなものを想定する。
vm コントローラは storage リソースと network リソースに依存している。
.
└── root/
├── controllers/
│ ├── vm/
│ │ ├── api/v1
│ │ ├── controller/
│ │ └── go.mod
│ ├── storage/
│ │ ├── api/v1
│ │ ├── controller/
│ │ └── go.mod
│ └── network/
│ ├── api/v1
│ └── go.mod
├── go.mod
└── go.work
普通であれば vm コントローラのどこかにマーカーコメントを書いて rbac を自動生成するわけだが、一つの Pod にまとめるなら vm コントローラと storage コントローラでマーカーコメントが重複して無駄になる。
そこでこのような場合は下記のように rbac 専用の go のファイルを作成し、そこに全てのマーカーコメントを記述し rbac マニフェストを生成する方式をとっている。
package rbac
// +kubebuilder:rbac:groups=compute.example.com,resources=vms,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=compute.example.com,resources=networks,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=compute.example.com,resources=storages,verbs=get;list;watch;create;update;patch;delete
このファイルは例えば次のようにそれぞれの go workspace とは独立した階層に配置する。
.
└── root/
├── controllers/
│ ├── vm/
│ │ ├── api/v1
│ │ ├── controller/
│ │ └── go.mod
│ ├── storage/
│ │ ├── api/v1
│ │ ├── controller/
│ │ └── go.mod
│ └── network/
│ ├── api/v1
│ └── go.mod
├── go.mod
├── go.work
└── deploy/
└── rbac/
└── base.go
この base.go から deploy/rbac/rbac.yaml を生成するコマンドは次のようになる。
controller-gen rbac:roleName=manager-role webhook paths="./deploy/rbac/..." output:rbac:artifacts:config=deploy/rbac
これで何か追加のリソースなどを定義した場合はとにかく base.go に権限を付与するだけでいい。
自分はそれぞれのコントローラの Reconcile関数の上にマーカーを分散させて記述するのがめんどうだったのでこの方法をとった。
Discussion