Core concepts and components¶
Controller¶
Typically, it's deployed to Kubernetes cluster as a Deployment resource using pre-built Docker image. Its responsibility is to:
- Watch on custom resources (triggers, actions, sources) and hold a local resources' state (for performance purpose).
- Watch on changes of ScheduleTrigger and update schedules if it's changed.
- Periodically run tasks (according to triggers' schedules) to check for changes of ScheduleTriggers' sources.
- Run web server to handle webhook requests to check for changes of WebhookTriggers' sources.
- Create Kubernetes Job to apply configured action if a triggers' source is changed (or in some other circumstances depending on triggers' config).
- Watch on Jobs which controller has run to provide Jobs' final state into the logs.
- Run utility web server to handle requests for liveness and readiness probes, and to provide metrics.
- Watch on ConfigMap with dynamic controllers' config and reload dynamic configuration in case of changes.
- Hold leader lease and do leader election with respect to all pods of the controller.
- Watch on signals to shut down gracefully if termination was requested.
High availability¶
It's possible to run multiple instances of the controller. Moreover, such a config is preferred for production environments. Controller manages single instance where ScheduleTriggers should be executed, it uses Kubernetes Lease resource to ensure fast and reliable leaders' election.
If at least two controllers' instances are running, in case of failures (pod evicted, node crashed, etc.) there is a builtin mechanism to smoothly move triggers' scheduling to another available instance.
One more point to pay attention to is WebhookTriggers' availability. Since this kind of trigger is actually a web server running on all controllers' instances. Having at least two controllers' instances helps do workload balancing and provides a classic mechanism of failure protection because Kubernetes Service always forwards traffic to available pods only.
Custom resources¶
Detailed references to all resources is in the separate section Resources. But few aspects should be mentioned:
Active vs passive resources¶
ScheduleTrigger is the only active resource that has its own state outside the cluster and initiates periodic tasks for checking sources.
All other resources are either a passive WebhookTrigger (it waits for external http requests to do any activity) or supplementary for triggers (sources and actions - triggers use them to interact with repos or run jobs).
Namespaced vs. cluster-wide resources¶
Besides introduction, we have to know the following:
- ClusterGitRepo can refer secrets in any namespace, but allowing access to secrets outside of controller's namespace is the responsibility of the cluster administrator. Provided Helm chart may facilitate this.
- ClusterAction can override the source used in its Job (this is a feature of both actions resources), but it can use ClusterGitRepo only to avoid cross-namespace access to GitRepo in multi-tenant environments.
CRDs manifests¶
git-events-runner
Helm chart
contains the latest actual bundle of CRD manifests.
Besides that, it's possible to get CRDs right from the controllers binary. The easiest way is to run controller's Docker
image with crds
parameter:
docker run --rm ghcr.io/alex-karpenko/git-events-runner/git-events-runner:latest crds
Use any valid version/tag instead of latest
to get the specific version of manifests, if necessary.
Images and binaries¶
Git Events Runner uses three types of images to run:
- git-events-runner: pre-built image with single controller's binary, without shell, package managers, etc.;
- gitrepo-cloner: pre-built image with single binary of utility to safely clone git repositories, it's used in the init container of action Jobs, without shell, package managers, etc.;
- action-worker: Job's runtime image, which contains everything you need to do actual work with cloned code.
As for action-worker, you can use any image you need: existing one from any repository (bash
or ubuntu
for example),
anything built by yourself or default one provided in this project.
Anyway, what command to run on start you provide in actions' config.
There is default action-worker image built from this Dockerfile, it's based on Ubuntu 22.04 and includes the set of typically used CD tools: Python, AWS CLI, Helm, kubectl, curl.
All Dockerfiles of this project are there: https://github.com/alex-karpenko/git-events-runner/tree/main/docker-build
Action Job internals¶
When a trigger discovers that repo was changed, it creates a classic Kubernetes Job to run Action because action is a single-shot piece of work.
Action resources provide a way to slightly customize jobs, but in general configuration is:
- Single
initContainer
runsgitrepo-cloner
image to clone needed repo/commit to predefined volume. - Single
container
runsaction-worker
image to do actual work. - Both containers mount shared
emptyDir
volume with content of the git repo/commit, worker container uses it as a Pods' workdir. - Worker container has set of predefined environment variables with prefix in names (default is
ACTION_JOB_
) with some actual runtime parameters that can be useful in workers. Look into the detailed actions reference for the full list of variables with descriptions. - Job has a zero backoff limit and single parallelism to ensure running only once.
Jobs' environment variables¶
As mentioned above, ACTION_JOB_
is just default prefix and may be configured to anything else.
Variable name | Mandatory | Description |
---|---|---|
ACTION_JOB_WORKDIR | Yes | Worker container workdir (folder where source repo is cloned) |
ACTION_JOB_TRIGGER_KIND | Yes | Kind of the trigger (ScheduleTrigger, WebhookTrigger) |
ACTION_JOB_TRIGGER_NAME | Yes | Name of the trigger. |
ACTION_JOB_TRIGGER_SOURCE_KIND | Yes | Kind of the triggers' source (Gitrepo, ClusterGitRepo) |
ACTION_JOB_TRIGGER_SOURCE_NAME | Yes | Name of the triggers' source. |
ACTION_JOB_TRIGGER_SOURCE_NAMESPACE | No | Namespace of the triggers' source (for GitRepo only). |
ACTION_JOB_TRIGGER_SOURCE_COMMIT | Yes | Commit hash which is cloned into workdir. |
ACTION_JOB_TRIGGER_SOURCE_REF_TYPE | Yes | Type of the triggers' repo reference which is configured to watch on (branch, tag, commit) |
ACTION_JOB_TRIGGER_SOURCE_REF_NAME | Yes | Name of the triggers' repo reference. |
ACTION_JOB_ACTION_SOURCE_KIND | No | Kind of the actions' overridden source. |
ACTION_JOB_ACTION_SOURCE_NAME | No | Name of the actions' overridden source. |
ACTION_JOB_ACTION_SOURCE_NAMESPACE | No | Namespace on the actions' overridden source. |
ACTION_JOB_ACTION_SOURCE_REF_TYPE | No | Reference type of the actions' overridden source. |
ACTION_JOB_ACTION_SOURCE_REF_NAME | No | Name of the actions' overridden source. |
Details about source override
feature can be found in the detailed documentation.