Project blueprint — config/project-config.yaml
Openconfig/project-config.yaml. This file is the project blueprint that records domain, repo path, project name, layout, and the API resources Kubebuilder added. Typically you do not edit this file by hand because Kubebuilder updates it when you add APIs or webhooks.
API shape — api/v1/webapp_types.go
Openapi/v1/webapp_types.go. This drawer defines the API surface for your custom resource.
WebAppSpecrepresents the user-requested (desired) state.WebAppStatusrepresents the operator-reported (observed) state.
Foo field as an example. In the next implementation steps, replace it with fields such as image and replicas. The controller will then create child resources (Deployment, Service, ConfigMap, etc.) using either defaults or values from the spec.
Markers beginning with +kubebuilder: are directives for controller-gen and other code generators. They generate CRD YAML, print columns, status subresource support, and validation rules. Generated files such as zz_generated.deepcopy.go live next to these types — do not edit generated files manually; use make generate instead.
Reconciliation logic — internal/controller/webapp_controller.go
Openinternal/controller/webapp_controller.go. This is the controller/reconciler drawer — the place to implement operator behavior.
The Reconcile function is the reconciliation loop that Kubernetes calls whenever a WebApp object (or an owned object) changes. In your implementation, the reconciler should:
- Read the WebApp instance from the API server.
- Compare the requested state (
Spec) with the current cluster state. - Create, update, or delete child resources (Deployment, Service, ConfigMap, etc.) to converge to the desired state.
- Update
WebApp.Statuswith observed conditions and requeue as required.
Reconcile currently returns with no work done — implement the steps above and manage errors/requeue behavior as appropriate.
Manager and wiring — cmd/main.go
Opencmd/main.go. This file wires the manager process that runs the controller(s). The manager owns the shared client, cache, metrics endpoint, webhook server, health/readiness probes, leader election, and controller registration. You typically modify this file only when adding new controllers, changing leader election, or altering probe/metrics settings.
Example: creating the manager instance.
Deployment YAML — config/
Theconfig/ directory holds Kubernetes manifests used for deploying and testing the operator:
config/crd/— generated CRD YAML for your APIs.config/rbac/— generated RBAC manifests derived from+kubebuilder:rbacmarkers.config/manager/— the operator Deployment manifest and related files.config/default/— kustomize overlay tying deployment pieces together formake deploy.config/samples/— exampleWebAppCR instances for testing.
Development tasks — Makefile
Open theMakefile. It contains standard targets for day-to-day work: generating code, building images, running locally, and deploying.
Key variables and snippet:
make generate— refreshes generated Go code (DeepCopy methods, etc.).make manifests— regenerates CRDs and RBAC YAML via controller-gen.make run— runs the operator locally against your kubeconfig.make deploy— builds and applies manifests to the cluster (kustomize overlay sets the image).
Keep generated and scaffolded files in mind: update
+kubebuilder:rbac markers and your api types as you add real resources. Use make generate and make manifests to refresh generated code and YAML so the on-disk artifacts match your source.Quick lookup — where to change what
Once you have this map, the generated project becomes a set of predictable drawers rather than a wall of files. Next, use this map to implement the reconciliation logic that ensures WebApp instances are translated into the proper cluster resources.
Links and references
- Kubebuilder book — Project layout and concepts
- Controller Runtime (controller-runtime)
- Kubernetes API conventions
- Kustomize
- controller-gen (controller-tools)
- Go module docs