Fundamentos de Operadores de Kubernetes
10 ejemplos para empezar con Operadores de K8s - 7 básicos y 3 intermedios.
Busca en todas las páginas de la documentación
10 ejemplos para empezar con Operadores de K8s - 7 básicos y 3 intermedios.
kubectl y un clúster local (kind, minikube o Docker Desktop Kubernetes).kustomize (incluido con kubectl reciente) para make deploy.go version, kubebuilder version, kubectl cluster-info.Crea un módulo con el grupo de API webapp.example.com y un kind Guestbook.
mkdir guestbook-operator && cd guestbook-operator
kubebuilder init --domain example.com --repo example.com/guestbook-operator
kubebuilder create api --group webapp --version v1 --kind Guestbook --resource --controllerinit genera la estructura de main.go, Makefile y Dockerfile.create api añade api/v1/guestbook_types.go y internal/controller/guestbook_controller.go.go mod tidy después de estructurar para resolver los módulos de controller-runtime.Relacionado: Diseño de CRD y Estructuración con Kubebuilder - Marcadores de API y generación de código
Usa controller-gen a través del Makefile del proyecto para emitir YAML de instalación.
make manifests
ls config/crd/bases/make manifests ejecuta controller-gen con marcadores +kubebuilder de los tipos Go.config/crd/bases/ y config/rbac/.kubectl apply.Relacionado: Diseño de CRD y Estructuración con Kubebuilder - marcadores de validación
Aplica CRDs y RBAC generados a kind o minikube.
make install
kubectl get crd | grep webappmake install aplica las bases de CRD desde config/crd.guestbooks.webapp.example.com aparece antes de iniciar el gestor.Relacionado: Gestor de controller-runtime, Cliente y Esquema - Registro de Esquema
El controlador generado implementa Reconcile con un cliente tipado.
func (r *GuestbookReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
var gb webappv1.Guestbook
if err := r.Get(ctx, req.NamespacedName, &gb); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
// TODO: asegurar que los recursos hijos deseados existan
return ctrl.Result{}, nil
}req.NamespacedName identifica el objeto que activó el trabajo.client.IgnoreNotFound(err) cuando el CR fue eliminado.ctrl.Result{} vacío significa éxito sin reintentos forzados.Relacionado: Escribiendo un Reconciliador: Bucle ctrl.Request & Reconcile - reintentos y errores
Conecta el reconciliador en main.go con el cliente y el esquema del Gestor.
if err = (&controller.GuestbookReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Guestbook")
os.Exit(1)
}mgr.GetClient() es un cliente con caché seguro para lecturas dentro de la reconciliación.SetupWithManager registra watches y conecta la cola de trabajo (workqueue).Relacionado: Gestor de controller-runtime, Cliente y Esquema - ciclo de vida del Gestor
Inicia el operador contra tu kubeconfig con la elección de líder deshabilitada para desarrollo.
make runmake run ejecuta go run ./cmd/main.go con acceso al clúster sin envtest.kubectl apply -f config/samples/.Relacionado: Elección de Líder, Métricas y Observabilidad del Operador - puntos finales de salud y métricas
Usa el manifiesto de ejemplo generado para activar la reconciliación.
apiVersion: webapp.example.com/v1
kind: Guestbook
metadata:
name: guestbook-sample
namespace: default
spec:
frontendSize: 2kubectl apply -f config/samples/webapp_v1_guestbook.yaml
kubectl get guestbook guestbook-sample -o yamlconfig/samples/ después de create api..status una vez que las implementes.spec y confirma que el reconciliador se ejecuta de nuevo (basado en nivel).Relacionado: Watches, Predicates, Owner References & Finalizers - filtrado de eventos
Vincula el ciclo de vida de un Deployment hijo al CR Guestbook padre.
dep := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{
Name: gb.Name + "-frontend", Namespace: gb.Namespace,
}}
if err := controllerutil.SetControllerReference(&gb, dep, r.Scheme); err != nil {
return ctrl.Result{}, err
}SetControllerReference requiere que el padre tenga establecido un indicador de controlador.Relacionado: Watches, Predicates, Owner References & Finalizers - GC y watches
Bloquea la eliminación del CR hasta que la limpieza externa finalice.
if !controllerutil.ContainsFinalizer(&gb, finalizerName) {
controllerutil.AddFinalizer(&gb, finalizerName)
return ctrl.Result{}, r.Update(ctx, &gb)
}
if !gb.DeletionTimestamp.IsZero() {
// limpiar recursos externos, luego:
controllerutil.RemoveFinalizer(&gb, finalizerName)
return ctrl.Result{}, r.Update(ctx, &gb)
}Update.Relacionado: Watches, Predicates, Owner References & Finalizers - seguridad de limpieza
Prueba la lógica de reconciliación sin un clúster real usando envtest.
make testtestEnv := &envtest.Environment{
CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")},
}
cfg, err := testEnv.Start()suite_test.go.make test ejecuta go test con CRDs cargados en un plano de control local.Relacionado: Pruebas de Operadores con envtest y Cliente Falso - patrones de cliente falso
Versiones de Stack: Esta página fue escrita para Go 1.26.x (predeterminado de GC Green Tea, modernizadores de go fix - verifica el parche en la compilación), chi (última versión - verifica en la compilación), gin (última versión - verifica en la compilación), echo (última versión - verifica en la compilación), google.golang.org/grpc (última versión - verifica en la compilación), sigs.k8s.io/controller-runtime (última versión - verifica en la compilación), kubebuilder (última versión - verifica en la compilación), tinygo (última versión - verifica los objetivos de placa en la compilación), wazero (última versión - verifica en la compilación) y golangci-lint (última versión - verifica el conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 18 jul 2026