Kubernetesのカスタムコントローラーで、監視対象のオブジェクトの状態を制御するための制御ループ処理(以下、Reconcile)を同時に複数回すことはできないか調べてみたので結果をメモとして残しておく。
結論から言うと、新しくコントローラーを作成する際に渡すcontroller-runtimeのオプションにMaxConcurrentReconcilesというフィールドがあって、フィールドの説明コメントに書いてあるように、これでReconcileの最大同時実行数を設定できる。
// Options are the arguments for creating a new Controller.
type Options struct {
// MaxConcurrentReconciles is the maximum number of concurrent Reconciles which can be run. Defaults to 1.
MaxConcurrentReconciles int
// Reconciler reconciles an object
Reconciler reconcile.Reconciler
// RateLimiter is used to limit how frequently requests may be queued.
// Defaults to MaxOfRateLimiter which has both overall and per-item rate limiting.
// The overall is a token bucket and the per-item is exponential.
RateLimiter ratelimiter.RateLimiter
// Log is the logger used for this controller and passed to each reconciliation
// request via the context field.
Log logr.Logger
// CacheSyncTimeout refers to the time limit set to wait for syncing caches.
// Defaults to 2 minutes if not set.
CacheSyncTimeout time.Duration
// RecoverPanic indicates whether the panic caused by reconcile should be recovered.
RecoverPanic bool
}
MaxConcurrentReconcilesは複数のループで並列処理を可能にするため、単一のループで処理するのに比べて遥かに早くキューに積まれたリクエストを排出できるようになる。コントローラーの監視対象のオブジェクトが頻繁に変化して、大量のReconcileリクエストがキューに送られてしまうような状況において有効である。
以下、MaxConcurrentReconcilesオプションを設定の設定例になるが、SetupWithManagerにおいてWithOptionsでカスタムコントローラーにMaxConcurrentReconcilesを3で設定している。オプションを指定しない場合はデフォルトの1で設定される。
// SetupWithManager sets up the controller with the Manager.
func (r *GatlingReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&gatlingv1alpha1.Gatling{}).
WithEventFilter(predicate.Funcs{
DeleteFunc: func(e event.DeleteEvent) bool {
return false
},
}).
WithOptions(controller.Options{MaxConcurrentReconciles: 3}).
Complete(r)
}
最後に、MaxConcurrentReconcileに関して、OpenKruiseのLearning Concurrent Reconciling記事が超絶参考になる。なお、記事中に書かれているが、複数のReconcileが同じオブジェクトを同時に処理することはないとのこと。安心。