0020. Kubernetes, GitOps, secrets and benchmark tools¶
Status¶
Accepted
Context¶
Projects that use this image increasingly deploy to Kubernetes with Flux, keep
secrets in git as encrypted files, move images between registries, and need to
measure how fast a VM or disk is. The image had none of the CLIs for that:
kubectl, flux, crane, sops, age, sysbench and fio were all
missing. Installing them at runtime does not work, because apk add needs root
(sudo is scoped to four maintenance scripts) and the egress allowlist ships
locked down.
Constraints specific to this image:
- Alpine/musl (ADR 0001) on amd64 and arm64 (ADR 0012).
- Binaries are Renovate-pinned and checksum-verified in the builder stage (ADR 0008); packages that Alpine builds natively come from apk, unpinned, like the rest of Layer A.
Decision¶
Two routes, chosen per tool:
Pinned upstream binaries (builder stage, one ARG + # renovate: comment
each, sha256sum -c before install, both arches):
| Tool | Source | Checksum source |
|---|---|---|
kubectl |
dl.k8s.io/release/v<ver>/bin/linux/<arch>/kubectl |
kubectl.sha256 sidecar. It holds only the digest, so the check line is built by hand. |
flux |
fluxcd/flux2 release tarball |
flux_<ver>_checksums.txt |
crane |
google/go-containerregistry release tarball (only crane is extracted, not gcrane or krane) |
checksums.txt |
sops |
getsops/sops release, a bare binary |
sops-v<ver>.checksums.txt |
These four go into the existing cli-tools Renovate group, with the
kubernetes/kubernetes release tag tracked for kubectl.
Alpine packages (Layer A, unpinned):
sysbenchandfioare C programs, so the apk build is the natural route.ageis available as an upstream binary, but upstream publishes no checksum file for it, only sigsum.proofsidecars. Alpine's signed package index is a stronger integrity check than HTTPS alone, so it comes from apk. The trade-off is that the version tracks thealpine:3.24snapshot instead of Renovate; sops does not need theageCLI, since age support is built in.
Rejected:
- All seven from apk. Alpine 3.24 carries every one of them, but the
versions lag upstream (read from the aarch64 index: kubectl 1.36.1, flux
2.8.1, sops 3.12.2, crane 0.21.6, against upstream 1.37.2, 2.10.0, 3.13.3 and
0.22.1 at the time of writing). The repo pins CLI tools like
ghandglabfrom upstream for the same reason, and kubectl and flux should be close to the cluster they talk to. - Helm, kustomize, k9s, kubeconform. Not requested at the time.
kubectlhas built-inkustomize. Helm, k9s and kubeconform were added later by the same route in ADR 0021. gcraneandkrane. They ship in the same crane tarball but target Google Cloud and Kubernetes auth helpers, which this image has no need for.
Consequences¶
Accepted:
- The image gets larger (the arm64 flux and sops binaries measure 76 MB and 48 MB uncompressed, crane 11 MB; kubectl was not measured), and the Layer A change invalidates the layers below it for one build.
age,sysbenchandfioupdate with the Alpine base, not with a Renovate PR.- No egress allowlist entries were added. The tools talk only to the clusters,
registries and key servers a project configures; the
examples/allowlist already lists the common registries (commented out).
Not verified when this was written:
dl.k8s.iocould not be reached from the authoring container (the firewall's resolved IPs had gone stale), so the kubectl URL layout follows the documented pattern and is confirmed only by the CI build.- The apk versions above were read from the aarch64 index; the x86_64 index was not inspected.