Skip to content

Upgrading Kollect

Production upgrade path for Kollect when moving between chart or image versions. For first-time install, see Install in the operator manual.

Assumptions

This guide assumes Helm 3, kubectl, and an existing Kollect release. New to CRD lifecycle or the two-artifact install model? Read Understand the basics and ADR-0704: Helm chart and CRD lifecycle first.

Pre-beta API

v1alpha1 fields and defaults may change until the first release candidate. Check ROADMAP before production rollout.

Why two steps

Helm installs CRDs from charts/kollect/crds/ on first install but does not upgrade or delete them on helm upgrade. Kollect accepts this deliberately (ADR-0704):

Artifact Lifecycle Tooling
CRD schema Apply-only, never deleted kubectl apply -f dist/install-crds.yaml
Operator (Deployment, RBAC, webhooks) Helm-managed helm upgrade

Never delete CRDs

Deleting a CRD garbage-collects all custom resources of that kind. CRD upgrades are apply-only; release tooling and runbooks must never remove them.

Two install artifacts

Each GitHub Release publishes install-crds.yaml (schema) and install.yaml (full operator manifest) plus the OCI Helm chart — see Release process.

Standard upgrade procedure

Apply CRD schema before upgrading the operator Deployment so the manager and apiserver agree on stored object shape.

1. Fetch release assets

Download install-crds.yaml from the target GitHub Release or build locally:

VERSION=0.1.0 task release-dry-run

Verify image digest or tag with cosign when adopting from GHCR (ADR-0705).

2. Apply CRD schema

kubectl apply -f install-crds.yaml

kubectl apply is idempotent. Review server-side apply conflicts if you customized CRD annotations.

Cluster-scoped CRD changes

Schema changes that affect stored versions may require apiserver conversion webhooks or manual field migration. Read release notes and ADR-0206 before skipping minor bumps.

3. Upgrade the operator

Chart from repository:

helm upgrade kollect ./charts/kollect -n kollect-system -f values.yaml

OCI chart (GHCR):

# pin the target release version, e.g. --version 0.5.0
helm upgrade kollect oci://ghcr.io/platformrelay/kollect \
  --version <chart-version> \
  -n kollect-system \
  -f values.yaml

Raw manifests:

kubectl apply -f install.yaml

Pin image.tag to a specific release (or use the release-pinned install.yaml) in production. The chart default resolves to v<appVersion> — the image shipped with that chart version — rather than a floating latest tag.

Upgrade chart and image together

RBAC is Helm-managed, so a pinned image.tag newer than the installed chart runs against the older ClusterRole. Releases after v0.18.0 add kollectclusterscopes get/list/watch to the manager ClusterRole and make the controller watch that type. A manager that cannot watch a type it registered fails its cache sync and exits, so pairing the new image with the old ClusterRole crash-loops the operator instead of degrading one controller. Bump the chart in the same change as the image — or, on the raw-manifest path, re-apply install.yaml from the same release.

4. Wait for rollout

kubectl -n kollect-system rollout status deployment/kollect-controller-manager --timeout=300s

Confirm validating webhooks are Ready if webhooks.enabled: true (default). cert-manager must have issued or rotated the serving certificate (ADR-0105).

Values and behaviour changes

Review Helm values and the chart README when bumping versions. Common upgrade touchpoints:

Area Check
tenantMode / watchNamespaces RBAC shape changes require reconciling Role vs ClusterRole
mode Single-cluster only; remove legacy hub/spoke values from overlays
featureGates.* New gates default off; dev overlays may differ from production values
webhooks.certManager.create false requires an operator-provided serving Secret and webhook CA trust; the chart does not generate either

Export debouncing

Debounce interval is per KollectInventory.spec.exportMinInterval (CRD default 30s).

Cluster-scope GVK enforcement (after v0.18.0)

Releases after v0.18.0 enforce KollectClusterScope allowedGVKs during reconcile, not only at admission — the backstop ADR-0207 always specified.

Existing cluster targets can stop collecting

A KollectClusterTarget whose profile targetGVK or resourceRules GVK sits outside a non-empty allowedGVKs now unregisters its informers and goes Degraded=True / reason=ScopeGVKDenied on the first reconcile after upgrade. Targets admitted before the ceiling was created or tightened are the affected set — admission only ran when they were last written.

Audit before upgrading, on each cluster that has a KollectClusterScope:

kubectl get kollectclusterscopes.kollect.dev -o yaml | grep -A4 allowedGVKs
kubectl get kollectclustertargets.kollect.dev \
  -o custom-columns='NAME:.metadata.name,PROFILE:.spec.profileRef.name,PROFILE_NS:.spec.profileRef.namespace'

Cross-check each target's profile targetGVK (plus any spec.resourceRules[].gvk) against allowedGVKs. Remediate by widening allowedGVKs, repointing profileRef, or retiring the target. After upgrading, the affected targets are listed by:

kubectl get kollectclustertargets.kollect.dev -o custom-columns=\
'NAME:.metadata.name,DEGRADED:.status.conditions[?(@.type=="Degraded")].status,REASON:.status.conditions[?(@.type=="Degraded")].reason'

Widening the ceiling clears the condition on the next reconcile; nothing needs to be recreated.

GitOps and CI/CD

For Argo CD, Flux, or similar:

  1. Commit or sync install-crds.yaml in a separate wave or Job before the Helm release.
  2. Keep CRD manifests out of the same Helm hook that upgrades the Deployment unless you accept Helm's CRD non-upgrade semantics.
  3. Pin chart version and image digest in values; use OCI oci://ghcr.io/platformrelay/kollect with an immutable tag.

Open question

A guarded upgradeCRDs Helm value remains undecided (ADR-0704). Default stays out-of-band install-crds.yaml for explicit operator control.

Rollback

Layer Action
Operator Deployment helm rollback kollect <revision> or re-apply prior install.yaml
CRD schema Do not downgrade CRDs if new fields were persisted — restore etcd backup or migrate data
Custom resources Unaffected by operator rollback if CRD schema is backward compatible

If a bad operator image breaks reconciliation, roll back the Deployment first. CRD schema rollback is a last resort and may require maintenance windows.

Verify after upgrade

kubectl get crd | grep kollect.dev
kubectl -n kollect-system get deploy,pod
kubectl get kollectinventories.kollect.dev -A

Check Ready conditions on sample KollectInventory objects and sink export timestamps. In a multi-cluster fleet, repeat per cluster and confirm rows land in the shared sink under each spec.cluster partition.

See also