https://kubebuilder.io, notably https://kubebuilder.io/quick-start.html, and https://github.com/kubernetes-sigs/kubebuilder.
curl -L -o kubebuilder https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)
chmod +x kubebuilder && sudo mv kubebuilder /usr/local/bin/
kubebuilder
kubebuilder init --help
mkdir learning-kubebuilder && cd learning-kubebuilder
kubebuilder init --domain vorburger.ch --repo github.com/vorburger/learning-kubebuilder --project-name learning-kubebuilder --owner "Michael Vorburger" --component-config true
kubebuilder create api --group learning --kind Foo --version v1
make install
k api-resources | grep foo
make run
cat config/samples/*
k apply -f config/samples/
k get foo foo-sample -o yaml
Stop (Ctrl-C) the make run
to clean-up.
You may want to use your favourite Go IDE of choice instead of a text editor for the following code changes. The web-based Google Cloud Code, or Gitpod, both based on Eclipse Theia, are a great choice. Alternatives include e.g. VS Code, or your favourite TUI editor with LSP support.
-
edit the
controllers/foo_controller.go
and change theReconcile
function to look like this:log := log.FromContext(ctx) var foo model.Foo if err := r.Get(ctx, req.NamespacedName, &foo); err != nil { log.Error(err, "Get failed") return ctrl.Result{}, client.IgnoreNotFound(err) } log.Info("Reconciled") return ctrl.Result{}, nil
-
re-run the controller with
make run
-
edit the
Foo
resource and change itsspec.foo
frombar
tobaz
(just to "touch" it)k edit foo foo-sample
-
observe how "Reconciled" is logged again
-
make a backup of the initial CRD YAML (or use git diff in the step after the next):
cp config/crd/bases/learning.vorburger.ch_foos.yaml config/crd/bases/learning.vorburger.ch_foos.original.yaml
-
edit the
api/v1/foo_types.go
and change thetype FooStatus struct
to look like this:type FooStatus struct { Bar string `json:"bar,omitempty"` }
-
re-generate the generated CRD YAML, and note how
bar
got added tostatus
:make install diff config/crd/bases/learning.vorburger.ch_foos.yaml config/crd/bases/learning.vorburger.ch_foos.original.yaml
-
edit the
controllers/foo_controller.go
and change theReconcile
function to look like this:log := log.FromContext(ctx) var foo model.Foo if err := r.Get(ctx, req.NamespacedName, &foo); err != nil { log.Error(err, "Get failed") return ctrl.Result{}, client.IgnoreNotFound(err) } foo.Status.Bar = "hello, " + foo.GetName() + " with spec " + foo.Spec.Foo if err := r.Status().Update(ctx, &foo); err != nil { log.Error(err, "Update failed") return ctrl.Result{}, err } log.Info("Reconciled") return ctrl.Result{}, nil
-
re-run the controller with
make run
-
run
k get foo foo-sample -o yaml
and notice the newstatus
-
edit the
Foo
resource and change itsspec.foo
back frombaz
tobar
(just to "touch" it)k edit foo foo-sample
-
re-run
k get foo foo-sample -o yaml
and notice the updatedstatus