kubernetes-bootstrap: apply minimal bootstrap helm charts on switch (#5) #23
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "issue-5-bootstrap-helm"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements the shape rpickler asked for in #5: charts rendered to a derivation, injected into the cluster by a systemd service during
nixos-rebuild switch— and scoped to the absolute minimum.What's in the slice
modules/kubernetes/bootstrap/default.nix— new module, optionkubernetes.bootstrap:helm templateinside a stdenv derivation (pure, builds without a cluster). The chart is taken from the existinginputs.btrfs-nfs-csiflake pin, so chart version and the agent binaryservices.btrfs-nfs-csiships to horse come from one pin and move together onnix flake update btrfs-nfs-csi— the version-coupling argument from the issue.systemd.services.kubernetes-bootstrap: oneshot reconciler,wantedBy = kubernetes.target, waits for the API server and retries viaRestart=on-failure(unit start ≠ apiserver ready on a fresh cluster). Applies/etc/kubernetes/bootstrap-manifestswithkubectl apply --server-side --prune -l app.kubernetes.io/managed-by=Helm— declarative, prunes removed resources, and never touches the runtime Secret (unlabelled).btrfs-nfs-nosync,btrfs-nfs-backup,kubeletDir = /var/lib/kubernetes, hostNetwork driver).existingSecret), created once at runtime from a sops-nix secret file. Verified against the driver source that the controller reads keyagentTokenfrom that Secret.snapshotClass = falseby default: the chart's VolumeSnapshotClass needs the snapshot CRDs + controller, which stockservices.kubernetesdoesn't ship; enabling a snapshotClass would fail apply.hosts/lurch.nix— the config block withenable = false(gated), sops keybtrfs-csi-agent-tokendeclared undermkIf enable. Flip-on procedure is in the code comment: sops key first, thenenable = true.What's deliberately NOT here
nix-kube-generators/nixhelminput. The rendering mechanism is ~25 lines ofhelm templatein a derivation (same thing nix-kube-generators'buildHelmChartdoes); for one bootstrap chart that dependency isn't worth pinning. Revisit when the ArgoCD slice arrives if we start vendoring many charts.Not enabled yet by design — enabling is a separate, visible switch after the sops key exists, and re-applies are idempotent once live.
No Nix runner available in this environment to
nix evalthe lurch config; changes were reviewed against the module sources of nixpkgsservices.kubernetes(kubernetes.target,etcClusterAdminKubeconfig = kubernetes/cluster-admin.kubeconfig) and the chart at the pinned rev. Flagging honestly for review.I attempted to switch to this branch on lurch, and nothing happened. The expected service didn't install. Now that you have nix underpinnings, can you review your work and ensure that it works as expected?
Root cause of 'nothing happened on switch': hosts/lurch.nix shipped with enable = false, gated on a sops key (btrfs-csi-agent-token) that does not exist in modules/secrets.yaml — flipping the gate would have broken activation on the missing secret, and enabling the module at all still failed with 'attribute inputs missing': lurch is the one host whose specialArgs is the bare inputs attrset, so the module argument `inputs` was never provided there. - flake.nix: lurch specialArgs becomes inputs // { inherit inputs; } (additive; keeps the per-input named args). - modules/kubernetes/csi-agent-token.nix: single source of truth for the agent tenant token; referenced by both the agent (btrfs-csi-driver.nix AGENT_TENANTS) and the cluster-side Secret, so both sides move together on rotation. - bootstrap module: agentTokenSecretFile now defaults to a store file with that token (status-quo parity with the deployed agent; the token is already committed via the agent env file), overridable with a sops path — rotation path documented. - hosts/lurch.nix: enable = true; sops gate removed. Verified with nix: bootstrap manifests derivation builds (helm renders 11 resources, all managed-by=Helm labelled, no token in the store output, secret refs match the apply script), lurch/horse/moose toplevels eval.Root cause found —
nothing happenedbecause it was still gated off, and two further bugs would have kept it from working even after unlocking the gate. Fixed and pushed in7135e8a; lurch's full system config now evaluates and the manifest derivation builds.Why the switch did nothing
hosts/lurch.nixshippedenable = false(the gate from my original PR description), so no unit was installed at all.sops.secrets.btrfs-csi-agent-tokenpoints at a key that does not exist inmodules/secrets.yaml.attribute 'inputs' missing: lurch is the only host wired asspecialArgs = inputsinstead of the repo's{ inherit inputs self; }convention, so the module arginputs(used forinputs.btrfs-nfs-csi) was never provided. The gate masked this because withenable = falsenothing forced the arg.Fixes (
7135e8a)flake.nix: lurchspecialArgs = inputs // { inherit inputs; }— strictly additive, keeps the per-input named args other lurch modules may use.modules/kubernetes/csi-agent-token.nix: single source of truth for the agent tenant token, read by both the cluster side (bootstrap Secret) and the agent side (btrfs-csi-driver.nixAGENT_TENANTS), so they can't drift and rotate together.agentTokenSecretFilenow defaults to a store file carrying that token, overridable with a sops path. Honest note: the token here is the placeholder already committed inbtrfs-csi-driver.nix(default:DEADBEEF...) — the agent on horse runs with it today, so the bootstrap matches the deployed reality instead of being blocked on a secret nobody has. The sops hardening path is documented in the new file.hosts/lurch.nix:enable = true, sops gate removed.option typeonagentTokenSecretFileaccepts paths or strings.Verified with nix (this time for real)
nix buildof the render derivation:helm templaterenders 11 resources, every object carriesapp.kubernetes.io/managed-by: Helm(the prune selector), both StorageClasses reference secretbtrfs-nfs-csi-agent-tokenin nsbtrfs-nfs-csi— exactly what the apply script creates —kubeletDir=/var/lib/kubernetes,hostNetworkon, no VolumeSnapshotClass, and no token value anywhere in the rendered output. (Built via a standalone x86 harness since lurch is aarch64 and this dev box can't build the Pi closure; YAML output is arch-independent.)nixosConfigurations.{lurch,horse,moose}.config.system.build.toplevel.drvPathall eval.kubernetes.targetis defined by the pinned nixpkgs (wantedBy multi-user) and/etc/kubernetes/cluster-admin.kubeconfigis what the module actually generates (etcClusterAdminKubeconfig), so the unit wiring and kubeconfig path in the script are correct.Remaining caveat: the apply against the live cluster itself (server-side adopting the helmfile-created resources via
--force-conflicts) can only be exercised on lurch — switching should now installkubernetes-bootstrap.service, start it on the switch, wait for the API server and converge. The placeholder token is the one real security debt; happy to take a follow-up issue for the sops rotation.Break up the bootstrap/default.nix file to make room for other charts/modules in the future.
@ -0,0 +171,4 @@apply Nix-rendered bootstrap Helm charts to the local cluster onnixos-rebuild switch'';btrfs-nfs-csi = lib.mkOption {It really seems like the btrfs-nfs-csi portion of this should be separated out into a separate submodule next to this bootstrap/default.nix file. This is to make room for other helm charts/modules we'll eventually add to the bootstrap mechanism. This
default.nixshould be left rendering and installing the charts provided by the other modules.Review points implemented in
77236da(branchissue-5-bootstrap-helm).No hardcoded chart in the machinery.
modules/kubernetes/bootstrap/default.nixnow knows nothing about individual charts: chart submodules register entries in a generickubernetes.bootstrap.charts.<name>option (namespace/chart/values/kubeVersion/setupScript). Everything registered + enabled is rendered withhelm templateinto one manifest dir and applied by the single reconciler unit; per-chartsetupScripthooks run between API-ready and apply. btrfs-nfs-csi lives in its ownbtrfs-nfs-csi.nixbeside it.Charts are optional. Each entry has
enable; the btrfs chart participates by default when the bootstrap is on, and a host can turn it off per-chart viakubernetes.bootstrap.btrfs-nfs-csi.enable = false(or directlycharts.btrfs-nfs-csi.enable = false). Assertion guards the empty-set case.One NixOS module-system trap hit and fixed: gating the chart registration with
config = { ... } // lib.optionalAttrs cfg.enable { ... }infinite-recurses (the//forces the config read at module-prep phase); the deferredlib.mkIf cfg.enable { ... }form is the working idiom — kept in a code comment so the next chart module doesn't rediscover it.Verification (all re-run on
77236da):nix evalof full-system toplevel drvPath for lurch, horse and moose — all green.7135e8a) and the new tree side-by-side via a standalone x86evalModulesharness —diff -rubyte-identical (only the single pinned input,btrfs-nfs-csi, feeds the chart; same helm 3.20.2, same values).Have an error when the kubernetes-bootstrap service tries to start:
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.