Getting Started
In this short tutorial you will learn how to scaffold a Kubernetes component operator using component-operator-runtime, and how to start with the implementation of the operator.
First of all, you have to download the component-operator-runtime scaffolding tool from the releases page. In the following we assume that the downloaded scaffold
executable
is somehwere in your path (for example, as /usr/local/bin/scaffold-component-operator).
Then, a git repository for the operator code is needed; in this example, we call it github.com/myorg/mycomponent-operator. We assume that you have cloned the empty repository to your local desktop, and have changed the current directory to the checked out repository.
We assume here that you are implementing a Kyma module operator, and that
the managed component shall be represented by a Kubernetes type called MyComponent
. Then run:
scaffold-component-operator \
--group-name operator.kyma-project.io \
--group-version v1alpha1 \
--kind MyComponent \
--operator-name mycomponent-operator.kyma-project.io \
--go-module github.com/myorg/mycomponent-operator \
--image mycomponent-operator:latest \
.
This will give you a syntactically correct Go module. In order to start the operator, you first have to apply the custom resource definition into your development (e.g. kind) cluster:
kubectl apply -f crds/operator.kyma-project.io_mycomponents.yaml
Then, after copying or linking the cluster’s kubeconfig to ./tmp/kubeconfig
(no worries, it will not submitted to git because ./tmp
is excluded by .gitignore
), you can use the generated ./vscode/launch.json
to start the
operator against your cluster with your Visual Studio Code. Now you are ready to instantiate your component:
kubectl apply -f - <<END
apiVersion: operator.kyma-project.io/v1alpha1
kind: MyComponent
metadata:
namespace: default
name: test
END
Now, after having the skeleton generated, we have to breathe life into the controller.
The first step is to enhance the spec of the generated custom resource type MyComponentSpec
in api/v1alpha1/types.go
.
In principle, all the attributes parameterizing the deployment of the managed commponent should be modeled there.
Whenever you change the runtime type, you should invoke make generate
and make manifests
in order to
update the generated code artifacts and the custom resource definition; afterwards you should re-apply the
custom resource definition to the cluster.
The next step is to implement a meaningful resource generator (the scaffolding just puts a dummy implementation called DummyGenerator
into main.go
). Writing such a resource generator means to implement the interface
type Generator interface {
Generate(ctx context.Context, namespace string, name string, parameters types.Unstructurable) ([]client.Object, error)
}
When called by the framework, the namespace
and name
arguments of the Generate()
method will be assigned the component’s namespace and name or, if the component or its spec implements the PlacementConfiguration
interface, they will match the return values
of the respective GetDeploymentNamespace()
, GetDeploymentName()
methods. The parameter
argument will be set to the return value of the component’s GetSpec()
method.
In simplistic words, the spec of the component resource will be fed into the resource generator, which will return the
concrete manifests of the dependent objects, which will then be applied to the cluster.
In some cases, the best option is to implement your own resource generator from scratch. When doing so, the returned resources []client.Object
either have to be of type *unstructured.Unstructured
, or the according type must be known to the used scheme.
In many other cases however, it makes more sense to just reuse one of the generic generators shipped with this repository.