BKE Bahriya Kubernetes Engine Start a 14-day trial

Installing components

apply.sh installs and reconciles the components your config.yaml declares. It is cluster-scoped: run it once, from one control-plane node, not once per node.

# Reports what would change. Changes nothing.
curl -sL https://bke.maml.uk/apply.sh | sh -s -- --version 2.0.0

# Applies it.
curl -sL https://bke.maml.uk/apply.sh | sh -s -- --version 2.0.0 --commit

Nothing happens without --commit. The first command prints a report — which versions move, whether any node drains, whether it can be rolled back, and what changes in each of your values files — and touches neither the cluster nor a file on this node. Read it, then run the same command again with --commit.

--version names where this run takes the cluster, not where it is. The version you are on is recorded on the cluster and read from there; the report’s first line shows both sides, as BKE <current> -> <requested>. Running with the version you are already on applies your configuration at that version — which is the ordinary way to roll out a config.yaml change. Naming a newer version moves the components — read Upgrading first.

To see what you are on:

curl -sL https://bke.maml.uk/version.sh | sh

It needs no licence, calls no API and changes nothing. On a control-plane node it prints the cluster’s recorded BKE and Kubernetes versions and each component as last applied; on a worker it prints that node’s own record.

There is no confirmation prompt in between. This script is piped from curl, so its standard input is the script itself and a prompt would consume the script rather than your answer. Report, then commit, is also the more useful shape: the report can be read by someone who is not at the keyboard.

There is no --role, because a role is a property of a node and this is not a node script.

Option Effect
--version X.Y.Z required — the version this run applies: what the cluster is on when it completes, never a statement of what it runs now
--commit actually apply. Without it, nothing changes
--show-unchanged also print the components that change nothing. Affects the report only, never what happens

What it reads

Path Used for Transmitted?
/etc/bke/license the credential for everything below as the Authorization header only
/etc/bke/config.yaml checking your configuration and resolving what to install yes
/etc/bke/secrets.d/ creating Secrets in the cluster never
/etc/bke/values/ the Helm values each component runs with — yours yes

Credentials live in their own directory, and not in config.yaml, precisely so that one can be sent and the other cannot.

/etc/bke/values/ is sent so that your file and the new default can be merged where a YAML parser exists — see The values files are yours, below. Nothing about it is stored. BKE’s own files name Secrets and never contain their values; that file is yours to edit, so do not put a password in it — put it in secrets.d/ and refer to the Secret by name.

It installs no package, writes nothing outside the cluster, and leaves no file behind — including when it fails.

What happens, in order

  1. The plan. config.yaml and --version are sent to api.maml.uk, which returns the exact versions to install, the components your licence covers, and the Secrets each one needs.
  2. The endpoint is checked. The address on your licence is compared with the one this cluster reports for itself. A mismatch is refused — a licence covers one cluster, and this is how BKE knows it is still the same one.
  3. Secrets are resolved — all of them, before anything is applied. Every Secret reference must resolve, either to a directory under secrets.d/ or to a Secret already in the cluster if its name is in secrets.unmanaged. Every unresolved reference is reported, not just the first.
  4. Namespaces, then Secrets, then charts. The order is fixed, because Longhorn reads its backup credentials when it starts and netdata claims when it starts. A Secret that arrived after its component would mean restarting that component rather than simply configuring it.
  5. You are shown what would change, and asked. The report covers the versions, whether nodes drain, the difference between the values files you have and the ones BKE proposes, and which Kubernetes objects that difference actually moves — including when the answer is none. Without --commit, this is where it stops.
  6. Each component is installed or upgraded via Helm, in a fixed order — not the order your config.yaml lists them in.
  7. What was installed is recorded in the bke-state ConfigMap, with the versions, so a later run can tell what has changed.

Run it again

apply.sh is idempotent. Running it a second time with nothing changed makes no changes and exits 0. This is the normal way to reconcile after editing config.yaml.

It is also a step in an upgrade: run it after the control plane has moved, and again at the end.

What reconciliation does not touch

Anything BKE did not install. If you have your own Helm releases, your own namespaces, your own CRDs, they are not BKE’s to reconcile and it does not look at them.

Your workloads. Installing a component may roll that component’s own pods. It does not drain nodes and does not touch your applications.

Settings config.yaml does not expose

config.yaml covers the settings most clusters need. The charts underneath have hundreds more, and you can set any of them — not through config.yaml, but directly, in the values files.

The values files are yours

/etc/bke/values/longhorn.yaml        the file in force. YOURS. Edit it.
/etc/bke/values/longhorn.dist.yaml   what BKE rendered. OURS. Leave it alone.

apply.sh passes <component>.yaml to Helm. Anything the chart accepts, you can put in it, and it survives every subsequent run.

<component>.dist.yaml is BKE’s record of what it last gave you. It exists so that BKE can tell what you changed from what we changed — editing it makes that comparison wrong, which is the only reason it is off limits.

Both files are written before Helm runs, so they are on disk whatever happens next. The directory carries a README saying the same thing.

What happens to your edits on an upgrade

A new version of BKE ships new defaults. For each file, one of four things happens, and the report tells you which before anything is applied:

Your file What happens
you have not changed it it takes the new default, quietly
you changed it; BKE did not nothing. Your file is untouched
you changed one setting, BKE changed another both apply. You see the diff
you and BKE changed the same setting the run stops and shows you both values

BKE never silently overwrites an edit of yours. The last row is the whole point: a wrong automatic choice about a gateway’s configuration is worse than a halted upgrade, so BKE will not make one. You resolve it by editing the file — take the new default, keep your value, or write a third thing — and run apply.sh again.

Your comments, your key order and your blank lines survive. Only the settings that actually change are touched.

Keep them in source control

If you run more than one cluster, keep /etc/bke/values/ in a repository the way you keep everything else that decides what runs. Nothing in BKE needs to know you are doing it — they are ordinary files, and a checkout populates the directory.

Running Helm by hand

You can, and it will take effect. But the next apply.sh will notice: it compares what the release is actually running with what your file says, and if they disagree it stops rather than proceeding, because every other thing it was about to tell you would have been computed against a file the cluster is not using.

The fix is to put the change in <component>.yaml, where it belongs and where it will last.

One consequence to accept

This is a directory you can edit, so a YAML syntax error in it is a failed run. The failure comes at the report, with the problem named, before anything is applied — not halfway through a Helm upgrade.

If a component needs a setting config.yaml does not expose and you would rather not maintain it in a values file, tell us. The list is short because it started from what clusters actually needed, not because it is finished.

Drift

bke-state records what BKE installed, and enough about how it was configured to notice later if something changed underneath it. On a later run, a component whose live state no longer matches what BKE recorded is reported. That is how a hand-edited release surfaces, rather than being silently overwritten without anyone noticing it had been changed.

When something refuses

Refusals are plain text, and each carries a cause. The three you are most likely to meet:

Refusal Means
not registered the licence has no cluster yet — run register.sh
endpoint mismatch this cluster’s endpoint is not the one on the licence
unresolved Secret reference a name in config.yaml matches neither secrets.d/ nor secrets.unmanaged

If we are unreachable, you get a 503 that says so — in those words, that it is our fault and not a problem with your licence. You will never have to guess whether you have been cut off or we are down. Retry shortly.