Build
Build Quarks-operator from source
The quarks-* operators share some common scripts, that are in the quarks-utils project. You can run bin/tools to download them. Or download them manually from quarks-utils.
Some scripts require the PROJECT env var to be set, e.g. PROJECT=quarks-secret.
make toolsKubernetes allows developers to extend the objects its APIs process and store using Custom Resource Definitions (CRDs). We are creating four CRDs (see Controllers):
The CRDs are also defined in code and applied automatically when quarks-operator starts. If you are editing CRDs, you should update changes to this YAML files in sync.
create a new directory: ./pkg/kube/apis/<group_name>/<version>
in that directory, create the following files:
types.goregister.godoc.goYou can safely use the implementation from another controller as inspiration. You can also copy the files and modify them.
The types.go file contains the definition of your resource. This is the file you care about. Make sure to run make generate every time you make a change. You can also check to see what changes would be done by running make verify-gen-kube.
The register.go file contains some code that registers your new types.
This file looks almost the same for all API resources.
The doc.go (deep object copy) is required to make the deepcopy generator work.
It’s safe to copy this file from another controller.
in bin/gen-kube, add your resource to the GROUP_VERSIONS variable (separated by a space " "):
|
|
regenerate code
|
|
create a directory structure like this for your actual controller code:
|
|
controller.go is your controller implementation; this is where you should implement an Add function where register the controller with the Manager, and you watch for changes for resources that you care about.reconciler.go contains the code that takes action and reconciles actual state with desired state.Simple implementation to get you started below. As always, use the other implementations to get you started.
Controller:
|
|
Reconciler:
|
|
add the new resource to addToSchemes in pkg/controllers/controller.go.
add the new controller to addToManagerFuncs in the same file.
create a custom resource definition and add docs to docs/crds.
|
|
env/machineenv/catalogA pattern that comes up quite often is that an object needs to be updated if it already exists or created if it doesn’t. controller-runtime provides the controller-util package which has a CreateOrUpdate function that can help with that. The object’s desired state must be reconciled with the existing state inside the passed in callback MutateFn - type MutateFn func() error. The MutateFn is called regardless of creating or updating an object.
|
|
CreateOrUpdates should not use blindly DeepCopyInto or DeepCopy all the time, but make more precise changes.We start with a single context and pass that down via controllers into
reconcilers. Reconcilers will create a context with timeout from the inherited
context and linting will check if the cancel() function of that context is
being handled.
The ctxlog module provides a context with a named zap logger and an event recorder to the reconcilers.
This is how it’s set up for reconcilers:
|
|
The ctxlog package provides several logging functions. Infof, Errorf, Error and such wrap the corresponding zap log methods.
The logging functions are also implemented on struct, to add event generation to the logging:
|
|
The reason should be camel-case, so switch statements could match it.
Error funcs like WithEvent().Errorf() also return an error, with the same message as the log message and event that were generated.
Calling WarningEvent just creates a warning event, without logging.
The quarks-operator uses quarks-job as an external component. The quarks-job operator is run in a separate process.
When using jobs that capture output, quarks-job needs to know its docker image, to run the persist-output command in a container.
References to quarks job:
go.mod:
‘b5dc240’QUARKS_JOB_IMAGE_TAG:
‘v0.0.0-0.gb5dc240’bin/build-helm, which uses the QUARKS_JOB_HELM_VERSION variable:
‘0.0.0-0.gb5dc240’Both variables are set in bin/include/dependencies.
To update a dependency in a project use go get, e.g.:
go get -t -u code.cloudfoundry.org/quarks-job@aad515c
Using the git commit sha prevents caching problems, which might occur with branch names.
When working locally with multiple repositories it’s helpful to replace github dependencies with local directories. The go mod edit -replace will modify the go.mod file to point to a local dir, e.g. ‘../quarks-job’ instead:
go mod edit -replace code.cloudfoundry.org/quarks-utils=../quarks-utils
go mod edit -replace code.cloudfoundry.org/quarks-job=../quarks-job
The modified libraries are not visible to the container. As a workaround a vendor folder can be used, which is also faster:
GO111MODULE=on go mod vendor
GO111MODULE=off make build-image
rm -fr vendor
To use a local docker image export QUARKS_JOB_IMAGE_TAG and make sure the image is available to the cluster, e.g. for kind:
kind load docker-image cfcontainerization/quarks-operator:$DOCKER_IMAGE_TAG
kind load docker-image cfcontainerization/quarks-job:$QUARKS_JOB_IMAGE_TAG
To use a local docker image export QUARKS_JOB_IMAGE_TAG and make sure the image is available to the cluster, e.g. for kind:
docker tag <quarks-operator-tag> cfcontainerization/quarks-operator:$DOCKER_IMAGE_TAG
docker tag <quarks-job-tag> cfcontainerization/quarks-job:$QUARKS_JOB_IMAGE_TAG
APIs and types follow the upstream versioning scheme described at: https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-versioning
Copy the grc (generic colouriser grcat) config file zap.grc.conf to /usr/share/grc/conf.zap and pipe logs to grcat conf.zap:
# install the custom log config
cp docs/zap.grc.conf /usr/share/grc/conf.zap
# running operator
kubectl get pods -A -l name=quarks-operator --no-headers=true | tail -1 | read namespace name _
kubectl logs -f -n "$namespace" "$name" | grcat conf.zap
# integration tests example
grcat conf.zap < /tmp/quarks-operator-tests.log
Build Quarks-operator from source
Tools to simplify your development workflow
Useful links to Kubernetes operators implementations or patterns