Diseño de CRD y Scaffolding con kubebuilder
Las Definiciones de Recursos Personalizados (Custom Resource Definitions) exponen el lenguaje de dominio de tu operador a los usuarios del clúster como YAML.
Busca en todas las páginas de la documentación
Las Definiciones de Recursos Personalizados (Custom Resource Definitions) exponen el lenguaje de dominio de tu operador a los usuarios del clúster como YAML.
kubebuilder convierte tipos de API Go y comentarios marcadores en manifiestos CRD, reglas RBAC y stubs de webhook a través de controller-gen.
Define tipos bajo api/v1/ (y versiones futuras) con campos de estructura etiquetados para JSON y validación.
Los comentarios marcadores como +kubebuilder:validation:Minimum=1 se convierten en restricciones OpenAPI en la CRD.
Ejecuta make manifests para regenerar YAML cada vez que cambien los tipos.
Planifica el versionado temprano: añade v2 como un nuevo paquete, marca una versión como de almacenamiento, implementa la conversión si los campos cambian de nombre.
Tarjeta de receta de referencia rápida - lista para copiar y pegar.
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:scope=Namespaced
// +kubebuilder:printcolumn:name="Replicas",type=integer,JSONPath=".spec.frontendSize"
// +kubebuilder:printcolumn:name="Ready",type=boolean,JSONPath=".status.ready"
type Guestbook struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec GuestbookSpec `json:"spec,omitempty"`
Status GuestbookStatus `json:"status,omitempty"`
}
type GuestbookSpec struct {
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=10
FrontendSize int32 `json:"frontendSize"`
}Cuándo usar esto:
kubebuilder create apikubectl get para ingenieros de soporte// api/v1/guestbook_types.go
package v1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// GuestbookSpec define el estado deseado de Guestbook.
type GuestbookSpec struct {
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=10
FrontendSize int32 `json:"frontendSize"`
// +kubebuilder:validation:Enum=small;medium;large
Tier string `json:"tier,omitempty"`
}
// GuestbookStatus define el estado observado de Guestbook.
type GuestbookStatus struct {
Ready bool `json:"ready,omitempty"`
Conditions []metav1.Condition `json:"conditions,omitempty"`
}
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:storageversion
// +kubebuilder:resource:shortName=gb
// +kubebuilder:printcolumn:name="Tier",type=string,JSONPath=".spec.tier"
// +kubebuilder:printcolumn:name="Ready",type=boolean,JSONPath=".status.ready"
type Guestbook struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec GuestbookSpec `json:"spec,omitempty"`
Status GuestbookStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
type GuestbookList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Guestbook `json:"items"`
}
func init() {
SchemeBuilder.Register(&Guestbook{}, &GuestbookList{})
}# Objetivo de Makefile (generado por kubebuilder)
controller-gen rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/basesLo que esto demuestra:
+kubebuilder:storageversion fija el almacenamiento etcd a esta versiónmake manifests alimenta config/crd/bases/webapp.example.com_guestbooks.yaml+kubebuilder: y emite YAML CRD, reglas ClusterRole y configuraciones de webhook.config/crd/bases/; las superposiciones de kustomize parchean nombres, namespaces y bundles de CA de webhook para la instalación.PROJECT + el flag create api --group (webapp.example.com/v1).subresources.status de la CRD como los permisos RBAC */status generados a partir de los marcadores +kubebuilder:rbac en los reconciliadores.| Patrón | Propósito |
|---|---|
v1alpha1 | Experimental, se permiten cambios disruptivos |
v1beta1 | Conjunto de campos estabilizándose, puede aparecer conversión |
v1 | Compatible con GA; preferir adiciones compatibles con versiones anteriores |
| Conversión hub-spoke | Mapea campos v1 y v2 a través de un tipo hub |
| Marcador | Efecto |
|---|---|
+kubebuilder:validation:Required | Campo requerido en OpenAPI |
+kubebuilder:default=value | Valor predeterminado inyectado por la CRD |
+kubebuilder:validation:Pattern | Expresión regular en cadenas |
+kubebuilder:rbac:groups=...,resources=...,verbs=... | Regla RBAC en config/rbac |
+kubebuilder:webhook:... | Configuración de webhook de validación o mutación |
// Marcadores RBAC del Reconciliador (en el archivo del controlador)
// +kubebuilder:rbac:groups=webapp.example.com,resources=guestbooks,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=webapp.example.com,resources=guestbooks/status,verbs=get;update;patchmake manifests sobrescribirá los cambios. Solución: cambia los tipos y marcadores de Go, luego regenera.v2, implementa la conversión, mantén v1 servido.GuestbookList con +kubebuilder:object:root=true.+kubebuilder:storageversion entre versiones.omitempty en escalares no puede distinguir cero de no establecido para validación. Solución: usa punteros para enteros opcionales o enums cuando cero sea válido.Status().Update devuelve 403. Solución: añade verbos guestbooks/status a los marcadores rbac.| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| kubebuilder + controller-gen | Operadores Go con APIs tipadas | La CRD es mantenida por un equipo separado en YAML crudo |
| YAML de CRD escrito a mano | Fuente de verdad del esquema independiente del lenguaje | Quieres generación de código RBAC y webhook desde Go |
| Solo validación declarativa de Kubebuilder | Restricciones de campo simples | Reglas complejas entre campos que necesitan CEL o webhooks |
| Webhooks de admisión para validación | Políticas más allá de OpenAPI | Cada regla simple de mínimo/máximo (preferir marcadores primero) |
controller-gen invocado por make manifests lee los tipos Go y los marcadores de kubebuilder.
La salida está bajo config/crd/bases/.
Ejecuta kubebuilder create api --group webapp --version v2 --kind Guestbook, implementa la conversión, marca la versión de almacenamiento en la versión canónica.
La versión de la CRD que etcd persiste como objetos.
Otras versiones servidas se convierten a y desde el almacenamiento en lectura/escritura.
Los marcadores son comentarios interpretados por controller-gen en tiempo de generación de código.
La sintaxis de marcador inválida falla make manifests, no go build.
Añaden columnas de kubectl get sin plugins personalizados.
JSONPath debe coincidir con los campos del esquema CRD publicados.
Cuando las reglas involucran múltiples campos (spec.end > spec.start) que los marcadores de OpenAPI por campo no pueden expresar.
Añade reglas +kubebuilder:validation:XValidation en versiones más recientes de kubebuilder o parchea el YAML de la CRD.
Dominio, ruta del repositorio y versión del diseño que kubebuilder utiliza para los comandos de scaffolding.
Mantenlo en control de versiones.
Usa +kubebuilder:resource:scope=Cluster en tipos con ámbito de clúster.
RBAC y el manejo de namespaces en los reconciliadores cambian en consecuencia.
+kubebuilder:resource:shortName=gb permite kubectl get gb.
Aún requiere que los usuarios conozcan el grupo de API para nombres cortos ambiguos.
Sí.
La convención de Kubernetes y la separación de RBAC requieren que spec sea escribible por el usuario y status escribible por el controlador.
make installVersiones de Stack: Esta página fue escrita para Go 1.26.x (GC por defecto Green Tea, go fix modernizers - verifica el parche en la compilación), chi (última - verifica en la compilación), gin (última - verifica en la compilación), echo (última - verifica en la compilación), google.golang.org/grpc (última - verifica en la compilación), sigs.k8s.io/controller-runtime (última - verifica en la compilación), kubebuilder (última - verifica en la compilación), tinygo (última - verifica objetivos de placa en la compilación), wazero (última - verifica en la compilación), y golangci-lint (última - verifica el conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 16 jul 2026