Installation¶
The operator ships as a Helm chart and as a plain Kubernetes manifest. Every release publishes both, together with two container images: the controller manager (ghcr.io/konsole-is/camunda-operator) and a companion CLI (ghcr.io/konsole-is/camunda-operator-cli). The chart and both images are signed with cosign.
The manager never runs the CLI itself. The Jobs that the operator creates run it, for example the upload of a LogicalBackupRDBMS dump. Both install paths point the manager at the CLI image of the same release. If you mirror the manager image, mirror the CLI image too.
Requirements¶
- Kubernetes 1.34 or later. The Helm chart refuses to install on an earlier version.
- Helm 3.8 or later, for the OCI registry.
- The ECK operator, version 3.5 or later, if you use
ElasticsearchCluster. The manager looks for the ECK CRDs when it starts. If it does not find them, everyElasticsearchClusterreportsReady=Falsewith reasonECKNotInstalled. If you install ECK after the manager, restart the manager. - The CloudNativePG operator, version 1.29 or later, if you use
DatabaseServer. With an earlier version, the API server rejects the CloudNativePG cluster of aDatabaseServer, andClusterReadyreportsFalse. The manager looks for the CloudNativePG CRDs when it starts. If it does not find them, everyDatabaseServerreportsReady=Falsewith reasonCNPGNotInstalled. If you install CloudNativePG after the manager, restart the manager. - The Barman Cloud plugin, version 0.14 or later, and cert-manager, if you use
DatabaseServerwithspec.archive. Both install into the namespace of the CloudNativePG operator. Without the plugin, aDatabaseServerwith an archive reportsReady=Falsewith reasonBarmanPluginNotInstalled. If you install the plugin after the manager, restart the manager. - A PostgreSQL server that a
DatabaseServerConfigdescribes, if you useDatabasewithout aDatabaseServer. The operator runs PostgreSQL only throughDatabaseServer. - The Keycloak Operator, if you use
CamundaManagementClusterwithspec.identityProvider.keycloak. The other two identity provider modes do not need it. The manager looks for the Keycloak CRDs when it starts. If it does not find them, everyCamundaManagementClusterin that mode reportsReady=Falsewith reasonKeycloakOperatorNotInstalled. If you install the Keycloak Operator after the manager, restart the manager. Install the Keycloak Operator release that matchesspec.identityProvider.keycloak.version. With Camunda 8.9, keep that version below 26.7.0. The operator runs Keycloak gives the reason. Camunda documents the same prerequisite in Keycloak deployment.
The end-to-end suite of each release runs against ECK 3.5.0, CloudNativePG 1.30.1, the Barman Cloud plugin 0.14.0, and the Keycloak Operator 26.6.4.
Install CloudNativePG and the Barman Cloud plugin¶
Install cert-manager first. The plugin gets its certificates from cert-manager.
kubectl apply --server-side -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.30/releases/cnpg-1.30.1.yaml
kubectl apply --server-side -f https://github.com/cloudnative-pg/plugin-barman-cloud/releases/download/v0.14.0/manifest.yaml
kubectl rollout status deployment/cnpg-controller-manager -n cnpg-system
kubectl rollout status deployment/barman-cloud -n cnpg-system
Both manifests install into the namespace cnpg-system. Use --server-side: each manifest carries a CRD larger than the annotation that client-side apply writes.
Skip the plugin when no DatabaseServer uses spec.archive. A server without an archive runs on CloudNativePG alone, and no point-in-time restore can reach it.
Install with Helm¶
helm install camunda-operator \
oci://ghcr.io/konsole-is/charts/camunda-operator \
--version <version> \
--namespace camunda-operator-system \
--create-namespace
This installs the manager and every custom resource definition. Replace <version> with a released version without the v, for example 0.1.0 for the release v0.1.0. The chart version, the chart appVersion, and the image tag are always this version.
Values¶
The chart README documents every value. Helm stops with an error when you set a value that the chart does not know, or a value of the wrong type. The values you are most likely to set:
| Value | Default | Effect |
|---|---|---|
manager.replicas |
1 |
Number of manager replicas. Leader election is on. |
manager.cliImage.repository, manager.cliImage.tag |
the CLI image of the release | The image that the Jobs of the operator run. Point it at your mirror when you mirror the manager image. |
prometheus.enabled |
false |
Install a ServiceMonitor for the manager. Needs the prometheus-operator CRDs. The alert rules and dashboards are applied separately, see Observability. |
rbac.helpers.enabled |
false |
Install admin, editor, and viewer ClusterRoles for every custom resource. |
crd.enabled |
true |
Install the CRDs with the chart. Set false to manage them yourself (below). |
certManager.enabled |
false |
Make the ServiceMonitor verify the metrics endpoint with the certificate in the Secret metrics-server-cert. The chart does not create that Secret. |
To pull from a mirror, set manager.image.repository and manager.cliImage.repository, and put the pull Secret in manager.imagePullSecrets. That Secret applies to the manager Pod only, not to the Jobs that run the CLI image. Those Jobs and the Camunda pods run under the ServiceAccount of their CamundaCluster. Add the pull Secret to the imagePullSecrets of that ServiceAccount, see Workload identity. The chart README lists these values.
Example:
helm install camunda-operator \
oci://ghcr.io/konsole-is/charts/camunda-operator \
--version <version> \
--namespace camunda-operator-system --create-namespace \
--set manager.replicas=2 \
--set prometheus.enabled=true
Install without Helm¶
Every release attaches a rendered manifest:
kubectl apply --server-side -f https://github.com/konsole-is/camunda-operator/releases/download/v<version>/install.yaml
Use --server-side: the CamundaCluster CRD is larger than the annotation that client-side apply writes.
The manifest differs from the chart defaults in two ways. It creates the namespace camunda-operator-system. And it includes the admin, editor, and viewer ClusterRoles for every custom resource, the same set the chart renders with rbac.helpers.enabled=true.
The manifest pins the CLI image in the manager's CAMUNDA_OPERATOR_CLI_IMAGE environment variable. To use a mirror, edit that value and the image of the manager Deployment before you apply.
Install the CRDs separately¶
Install the CRDs yourself when you manage them outside Helm, for example with a GitOps tool. This also keeps them out of the Helm release Secret, which etcd limits to about 1 MB:
kubectl apply --server-side -f https://github.com/konsole-is/camunda-operator/releases/download/v<version>/crds.yaml
helm install camunda-operator \
oci://ghcr.io/konsole-is/charts/camunda-operator \
--version <version> \
--namespace camunda-operator-system --create-namespace \
--set crd.enabled=false
With crd.enabled=false you own the CRD lifecycle. Apply the new crds.yaml before you upgrade the chart.
Grace periods¶
A workload that is not ready reports Creating, Updating, Scaling, Failing, or Blocked until its grace period ends. After that, its condition reports Degraded or Down. The grace period starts when the condition first reports a not-ready reason, such as Creating or Blocked, or when it changes from True to False. Status conventions describes the reasons and the start of the grace period.
| Flag | Environment variable | Default | Applies to |
|---|---|---|---|
--workload-grace-period |
CAMUNDA_OPERATOR_WORKLOAD_GRACE_PERIOD |
30m |
The processes of a CamundaCluster. The webapp and importer of a CamundaOptimize. The Keycloak and the workloads of a CamundaManagementCluster. The exporter of an ElasticsearchCluster. |
--datastore-grace-period |
CAMUNDA_OPERATOR_DATASTORE_GRACE_PERIOD |
30m |
The Elasticsearch cluster of an ElasticsearchCluster and the PostgreSQL cluster of a DatabaseServer. |
A value is a Go duration, for example 20m or 1h. The flag wins over the environment variable. With 0, the condition keeps its progress reason and never reports Degraded or Down. The manager does not start with a negative value. It also does not start with a value that is not a duration, unless a flag overrides that environment variable.
Set a value that is longer than your slowest rollout. Keep the workload grace period at or above the datastore grace period. A cluster on Elasticsearch and its Optimize are not ready until that Elasticsearch is. A shorter workload period reports them Down while Elasticsearch still starts. A value that is too short reports Degraded or Down for a workload that starts slowly but correctly. A rolling update of many brokers, or the first start of a large Elasticsearch cluster, can take longer than the default.
With Helm, set the environment variables in manager.envOverrides:
helm install camunda-operator \
oci://ghcr.io/konsole-is/charts/camunda-operator \
--version <version> \
--namespace camunda-operator-system --create-namespace \
--set manager.envOverrides.CAMUNDA_OPERATOR_WORKLOAD_GRACE_PERIOD=60m \
--set manager.envOverrides.CAMUNDA_OPERATOR_DATASTORE_GRACE_PERIOD=45m
The section Manager settings of the chart README lists every flag and environment variable of the manager.
Without Helm, add the environment variables to the manager container of the Deployment camunda-operator-controller-manager in install.yaml, next to CAMUNDA_OPERATOR_CLI_IMAGE:
env:
- name: CAMUNDA_OPERATOR_WORKLOAD_GRACE_PERIOD
value: 60m
- name: CAMUNDA_OPERATOR_DATASTORE_GRACE_PERIOD
value: 45m
Verify the signatures¶
The chart and both images are signed with cosign keyless signatures. There is no public key. Verification checks the identity of the release workflow:
for artifact in \
ghcr.io/konsole-is/charts/camunda-operator:<version> \
ghcr.io/konsole-is/camunda-operator:<version> \
ghcr.io/konsole-is/camunda-operator-cli:<version>; do
cosign verify "$artifact" \
--certificate-identity-regexp '^https://github\.com/konsole-is/camunda-operator/\.github/workflows/release\.yml@refs/tags/.+$' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
done
A successful verification prints the certificate subject and the matched claims.
Upgrade¶
helm upgrade camunda-operator \
oci://ghcr.io/konsole-is/charts/camunda-operator \
--version <new-version> \
--namespace camunda-operator-system
Without --set or -f, Helm keeps the values of the last release. If you pass a value, Helm uses the chart defaults for all the values you do not pass. In that case, pass every value of the install again. Do not use --reuse-values, because it keeps the image tags of the old chart.
The CRDs carry the annotation helm.sh/resource-policy: keep. Helm updates them in place and never deletes them.
To upgrade a manifest install, apply the install.yaml of the new release with --server-side, as in Install without Helm. Make the same mirror edits again before you apply.
Uninstall¶
Because of the keep policy, the CRDs and every custom resource stored in them survive the uninstall. The Camunda workloads keep running, but nothing manages them.
To remove everything, do these steps in this order:
- Delete your custom resources while the manager runs. Some of them, for example a
CamundaClusteror a backup, wait for the manager before they go away. Without the manager, they stay in deletion, and the delete of their CRD does not finish. - Uninstall the chart.
- Delete the CRDs.
Caution: When you delete a backup resource, the operator deletes the snapshots or the dump of that backup from the bucket. If you delete the cluster or its
ObjectStorageConfigfirst, the backup goes and leaves its artifacts in the bucket. When you delete aCamundaCluster, the broker volumes followspec.zeebe.persistentVolumeClaimRetentionPolicy. The default deletes them.
Delete the CRDs by name. The CRD manifests carry no labels, so a label selector does not match them:
kubectl delete -f https://github.com/konsole-is/camunda-operator/releases/download/v<version>/crds.yaml
Without the release file, delete every CRD in the core.camunda.io group:
crds=$(kubectl get crd -o name | grep '\.core\.camunda\.io$')
if [ -n "$crds" ]; then kubectl delete $crds; fi
Install from source¶
git clone https://github.com/konsole-is/camunda-operator
cd camunda-operator
make docker-build docker-push IMG=<registry>/camunda-operator:<tag>
make docker-build-cli docker-push-cli CLI_IMG=<registry>/camunda-operator-cli:<tag>
make helm-generate IMG=<registry>/camunda-operator:<tag> CLI_IMG=<registry>/camunda-operator-cli:<tag>
make helm-deploy IMG=<registry>/camunda-operator:<tag> CLI_IMG=<registry>/camunda-operator-cli:<tag>
This needs Docker, Go, and the kubebuilder CLI. make helm-generate renders dist/chart/values.yaml, dist/chart/values.schema.json, and dist/chart/templates/ from config/. The repository holds only Chart.yaml and README.md of the chart. IMG and CLI_IMG set the two images for make deploy, make build-installer, and make helm-deploy in the same way.