Библиотека для быстрого создания Kubernetes-операторов на базе controller-runtime. Убирает бойлерплейт из main.go, предоставляя готовые строительные блоки: парсинг флагов, настройка TLS, кэш с label-фильтрацией, readiness-пробы и раздельный запуск webhooks/controllers.
Типичный оператор на controller-runtime требует ~100 строк бойлерплейта в main.go: парсинг флагов, настройка менеджера, TLS, метрики, пробы. Эта библиотека сводит всё к ~30 строкам с functional options.
go get github.com/kazaych/codefestlibsample@latestСоздание ctrl.Manager через цепочку опций вместо ручной сборки ctrl.Options:
mgr, err := mb.NewManager(
mb.WithScheme(scheme),
mb.WithFlags(flags),
mb.WithTLSOptions(tlsOpts),
mb.WithLeaderElectionID("my-operator"),
mb.WithReaderFailOnMissingInformer(),
mb.WithLabeledCacheObjects(objects, "app.kubernetes.io/managed-by", "my-operator"),
)Доступные опции:
| Опция | Описание |
|---|---|
WithScheme(s) |
Устанавливает runtime.Scheme (обязательно) |
WithConfig(cfg) |
Kubernetes rest.Config (по умолчанию — in-cluster) |
WithFlags(f) |
Применяет CLI-флаги к конфигурации |
WithTLSOptions(opts) |
TLS-настройки для webhook и metrics серверов |
WithLeaderElectionID(id) |
ID для leader election |
WithLabeledCacheObjects(objs, key, val) |
Фильтрация кэша по лейблу |
WithReaderFailOnMissingInformer() |
Ошибка при запросе типа без informer |
ParseFlags() регистрирует все типичные флаги оператора одним вызовом:
flags := mb.ParseFlags()Флаги: --metrics-bind-address, --health-probe-bind-address, --leader-elect, --metrics-secure, --webhook-cert-path/name/key, --metrics-cert-path/name/key, --enable-http2, --start-in-webhook-mode-only.
RegisterComponents запускает webhooks или controllers в зависимости от флага --start-in-webhook-mode-only. Это позволяет деплоить webhooks и controllers отдельными подами:
err := mb.RegisterComponents(ctx, mgr, flags, registerWebhooks, registerControllers)Fluent builder для сборки списка типов, чьи informers нужно прогреть до старта менеджера:
types := mb.NewInformerTypesBuilder().
WithUserTypes(&appsv1.StatefulSet{}, &batchv1.Job{}).
Build()
err := mb.SetupInformersWithManager(ctx, mgr, types)Библиотечные дефолты (Pod, Secret, Service, PVC) включаются автоматически.
err := mb.AddInformerCacheReadyzCheck(mgr)Добавляет /readyz/informer-cache, которая отвечает 200 только после полной синхронизации всех informers.
tlsOpts := mb.ManagerTLSOptions(flags.EnableHTTP2)По умолчанию отключает HTTP/2 для webhook и metrics серверов (рекомендация безопасности).
package main
import (
"context"
"os"
mb "github.com/kazaych/codefestlibsample/pkg/managerbuilder"
appsv1 "k8s.io/api/apps/v1"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"sigs.k8s.io/controller-runtime/pkg/manager"
)
var scheme = runtime.NewScheme()
func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
// utilruntime.Must(myapiv1.AddToScheme(scheme))
}
func main() {
ctx := context.Background()
ctrl.SetLogger(zap.New())
flags := mb.ParseFlags()
tlsOpts := mb.ManagerTLSOptions(flags.EnableHTTP2)
mgr, err := mb.NewManager(
mb.WithScheme(scheme),
mb.WithFlags(flags),
mb.WithTLSOptions(tlsOpts),
mb.WithReaderFailOnMissingInformer(),
mb.WithLabeledCacheObjects(
mb.DefaultLibraryInformerTypes(),
"app.kubernetes.io/managed-by", "my-operator",
),
)
if err != nil {
panic(err)
}
if err := mb.RegisterComponents(ctx, mgr, flags,
registerWebhooks,
registerControllers,
); err != nil {
panic(err)
}
mgr.AddHealthzCheck("healthz", healthz.Ping)
mb.AddInformerCacheReadyzCheck(mgr)
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
os.Exit(1)
}
}
func registerWebhooks(ctx context.Context, mgr manager.Manager) error {
// Регистрация ваших webhooks
return nil
}
func registerControllers(ctx context.Context, mgr manager.Manager) error {
// Регистрация ваших reconcilers
// + прогрев дополнительных informers:
types := mb.NewInformerTypesBuilder().
WithUserTypes(&appsv1.StatefulSet{}).
Build()
return mb.SetupInformersWithManager(ctx, mgr, types)
}ParseFlags() ──► ManagerFlags
│
▼
┌─── NewManager() ◄── WithScheme, WithConfig, WithTLSOptions, ...
│ │
│ ▼
│ ctrl.Manager
│ │
▼ ▼
ManagerTLSOptions() RegisterComponents(webhooks, controllers)
│
┌─────────┴──────────┐
▼ ▼
WebhookSetup ControllerSetup
+ SetupInformersWithManager()
+ AddInformerCacheReadyzCheck()
Apache License 2.0