Upgrading KDBL Context Lake (K-Lake)¶
How to upgrade (Helm)¶
A production deployment is installed from the Helm chart, so an
upgrade is an in-place helm upgrade to a newer chart version:
helm upgrade kdbl oci://ghcr.io/kdbl-consulting/kdbl \
--version <NEW.X.Y.Z> \
--namespace kdbl \
--reset-then-reuse-values
-
--reset-then-reuse-valuescarries your existing tier, ingress, database, and licence settings forward — override just what's changing (e.g.--set tier=large) — while taking the new chart's own defaults for everything you never set yourself.Use this flag, not
--reuse-values--reuse-valuesalso replays the previous chart's defaults, which outrank the new chart's. On releases up to 0.1.18 those defaults included a pinned image tag per component, so an upgrade would report success, move the release to the new version, and leave every pod running the old images. Charts from 0.1.19 no longer pin tags, but--reuse-valueswill still carry the stale ones forward out of a release installed at 0.1.18 or earlier — so use--reset-then-reuse-valuesfor that first upgrade, and it stays the right flag afterwards. (Needs Helm 3.14 or newer; check withhelm version --short.)- Secrets are preserved. The master key and database passwords generated on first install are kept across upgrades, so pods never rotate them underneath a running deployment.
- The schema migrates itself. Each service applies any schema changes at boot; there's no separate migration step to run.
- Rolling and reversible. Pods roll one pool at a time (pod disruption budgets
keep all-but-one replica serving);
helm rollback kdblreturns to the previous release if needed. - Licence renewals don't need an upgrade — set a new blob live with
kdbl-control licence apply(orPOST /api/licence), or, to persist it in the release,helm upgrade … --set licence.blob='KDBLLIC1.<new>'.
Confirm the upgrade landed¶
Helm reports on the release, so check the pods — this is the one command that tells you what is actually running:
kubectl -n kdbl get deploy,statefulset \
-o jsonpath='{range .items[*]}{range .spec.template.spec.containers[*]}{.image}{"\n"}{end}{end}' \
| grep kdbl-consulting | sort -u
Every ghcr.io/kdbl-consulting/* image should carry the version you upgraded to.
The console shows the same thing under Admin → Fleet, and kdbl-control
versions prints it from the command line.
If some pods still show the old version, re-run the upgrade with
--reset-then-reuse-values (see the warning above).
Preview the chart's current options at any time with
helm show values oci://ghcr.io/kdbl-consulting/kdbl --version <X.Y.Z>.
Evaluation proof-of-concept stacks upgrade differently — re-run the single-command installer with the newer version; it reuses the existing environment.
Version-specific notes¶
Breaking or noteworthy changes per version. Newest first — check every entry between your current version and the target.
→ v0.1.2 — Licensing is now enforced (breaking)¶
K-Lake is now fail-closed: every K-Lake service container refuses to start without a valid licence. An existing v0.1.1 deployment that rolls the v0.1.2 images without a licence provisioned will fail to start (CrashLoop) with:
Error: no licence applied: set the kdbl-licence Secret (KDBL_LICENCE or
KDBL_LICENCE_FILE) — refusing to start
Before you upgrade¶
-
Obtain a licence. If you don't already have one, ask KDBL for a licence (evaluations get a 30-day one). It's a
KDBLLIC1.…blob. -
Provide the licence. On a Helm deployment, pass it as a chart value — the chart creates and wires the Secret for you:
helm upgrade kdbl oci://ghcr.io/kdbl-consulting/kdbl --reset-then-reuse-values \
--set licence.blob='KDBLLIC1.<...the blob...>'
On a manifest/POC deployment, create the kdbl-licence Secret directly:
kubectl -n kdbl create secret generic kdbl-licence \
--from-literal=licence='KDBLLIC1.<...the blob...>'
Verify it first if you like — kdbl-control licence inspect <file> prints the
terms and confirms ✓ signature valid.
- Then roll the images. Each pod reads
KDBL_LICENCEfrom that Secret at boot; the chart (or the standard deployment manifests) already wires it. Confirm each container logs that the licence was accepted at boot and staysRunning.
The standard install scripts now require $KDBL_LICENCE and refuse to run
without it, so fresh installs can't accidentally come up unlicensed.
What enforcement does (once running)¶
A running deployment is not killed when a licence lapses — it degrades
gracefully per the licence's grace/lockdown windows: full use → (expired) grace
→ new-ingestion blocked (reads still work) → fully blocked. The API always
stays up to serve /licence so you can apply a renewal live
(kdbl-control licence apply) without a restart. See
docs/licensing.md.
Notes¶
- The old
KDBL_LICENCE_REQUIREDenv flag is removed — enforcement is unconditional. Drop it from any manifests/overlays. - Renewals: update the
kdbl-licenceSecret (newest licence wins) + restart, or apply live viaPOST /api/licence.