kubernetes automation · tekton ci · v2.0 · mit
Your cluster. Your pipelines. No lock-in.
kubementat takes a bare Kubernetes cluster and one config directory to a productive one: kmt applies a declared set of open-source releases — Tekton CI, Prometheus & Grafana, Loki & Alloy, Traefik with cert-manager, OpenBao, Polaris — and gives you pipelines for building and shipping your own apps on top.
bare cluster→ 1 config dir→ 1 command→ productive cluster
- helm releases
- 0
- kmt commands
- 0
- config dirs
- 0
- vendor lock-in
- 0
§ 01 why kubementat
A cluster is only productive
when it already has everything.
| Do it by hand | kubementat | |
|---|---|---|
| First productive day | weeks of choosing, installing, wiring | one apply, converged |
| Monitoring, logging, routing, secrets, compliance | five projects wearing a trench coat | declared in one helmfile, applied by kmt |
| CI/CD on Kubernetes | a second weekend with Jenkins | Tekton tasks, pipelines & webhook triggers, generated per app |
| Cluster versions | whatever the docs mentioned last | a release index with a version window — 2.x answers today |
| Where it runs | tied to one provider | laptop, Raspberry Pi, on-prem, any cloud |
| Your configuration | spread across manifests and tribal memory | one git-managed directory, encrypted where credentials live |
No service mesh. No nginx-ingress. kubementat installs neither, on purpose. Linkerd is swept from a cluster that really has it, and nginx-ingress left on 2026-10-28 — Traefik with cert-manager in front does the routing. Convention over configuration means the choices are already made, so your first hour is spent on your apps, not on the platform.
§ 02 how it works
The config directory is the product.
-
~/kmt-config/
Named, never located. --config-dir or $KUBEMENTAT_PLATFORM_CONFIG_DIR — nothing is discovered by proximity. It is a git repository in its own right, prepared by kmt config init, not a subdirectory of a checkout.
-
environment / team layers
Every key answered once. The team file, else the environment file, else a shipped default. kmt config show <env> prints each key and who answered it.
-
helmfile inside kmt
Releases are configuration. What gets applied is declared in the helmfile that ships inside kmt; versions come from its release index. Both are answered over by your tree.
-
all Python, no scripts
One implementation. Every verb — user management, secrets, tunnels, component applies — is Python in the library, imported and never exec'd. There is no scripts/ to fall behind the docs.
~/kmt-config/ # prepared by `kmt config init`
├── kubementat.yaml # the stamp: product + schema
├── .gitattributes # *.encrypted.* filter=git-crypt
├── deployer_ssh_key{,.pub} # the deploy keypair
├── git_crypt_symmetric.key # mode 0600 — cannot be regenerated
└── dev/
├── static.json # environment layer: what this cluster is
├── static.encrypted.json # credentials, under git-crypt
├── tekton/{tasks,pipelines}
└── dev1/
├── static.json # team layer — answers over the env
└── tekton/… # tasks the team owns replace the rest
A kubementat environment is defined by that directory, not by where the tool was installed. Since v2 the checkout is irrelevant to what your clusters do:
- Git-Crypt where it counts — credentials live in *.encrypted.* files inside your tree; kubementat reads them and never unlocks anything itself.
- Refusals are sentences — a missing binary, an unnamed kube context or an unknown key comes back as the name of what was missing, not a traceback.
- Idempotent by design — config init writes no byte on a second run and names what it skipped; applies converge.
§ 03 quick start
Install, name it, apply.
-
01
Install the kmt CLI
uv tool install kubementat # or: pipx install kubementat kmt --helpFrom a checkout (you are hacking on kubementat) it is uv sync --all-extras, then every command is uv run kmt …. For operating clusters the tool install is all you need — the configuration directory is independent of the tree kubementat came from.
-
02
Prepare the configuration directory
kmt config init --environment dev --team dev1 \ --gpg-email you@example.com --config-dir ~/kmt-configWrites the environment's and the team's static layers, the deploy keypair, and git-crypt made live in that directory — in that order. --set KEY=VALUE answers plain keys, --encrypted-set the protected ones. It commits its own work once; a second run converges without touching a byte.
-
03
Name the cluster
kubectl config get-contexts kmt config set dev CLUSTER_KUBE_CONTEXT=dev-cluster --config-dir ~/kmt-config kmt environments listA new environment answers CLUSTER_KUBE_CONTEXT as null and install refuses until you name one — copying whatever kubectl was pointed at would be a claim the tool did not earn. Nothing is resolved from current-context.
-
04
Apply everything
kmt install kmt setup-secretskmt install checks the machine first — kubectl, helm, helmfile, helm-diff, the tkn CLI, gpg, git — each missing binary named in its own sentence. Then it applies the helmfile, wires Tekton, and your cluster is productive. setup-secrets lays the team's credentials so pipelines can pull and push.
Lose the symmetric key and you lose the environment. git_crypt_symmetric.key cannot be regenerated and nothing can rotate it. init says so while writing it, mode 0600, gitignored — back it up like the cluster itself.
§ 04 the cli
One binary, grouped verbs.
Everything refuses in words.
The same 14 commands whether you are on a laptop or in a pipeline. Nine of them are groups that each answer --help with the refusals they make; five act on a whole cluster.
kmt config …init, set / unset, show, validate, add-environment, add-team — the verbs that lay down and read a configuration tree
kmt environments listone row per environment: its address and the kube context that answers for it
kmt kubernetes …what runs in the cluster: analyze-deployment, deployment-logs / -ssh, pod-images, pvc-usage, cluster-capacity, create-ingress, service-account-token
kmt helm …apply the environment's helmfile; latest-version asks the release index what is new
kmt tekton …setup-pipelines, setup-triggers, run-pipeline, generate-deploy-pipeline / -pipeline-run / -triggers, list, cleanup, uninstall
kmt component …install or uninstall a single release — helmfile scoped to one name; the namespaces kubementat creates are refused
kmt routing …install applies Traefik + cert-manager; status reads which Traefik the cluster is actually running, and whose certs
kmt tunnel …grafana, openbao-ui, tekton, or any pod — a port-forward without the kubectl invocation ceremony
kmt users …team accounts with RBAC and tokens, read-only variants, Grafana accounts, and the clean delete that takes the token with it
install · uninstallthe whole platform onto a cluster, or off of it, with the dependency check up front
setup-secrets · setup-docker-registry-accessteam credentials, and the pull secrets an answered DOCKER_REGISTRY_BASE_URL needs
run-ci-containerthe automation container, from the same image the pipelines run in
# the machine-readable view of one environment
kmt config show dev --config-dir ~/kmt-config
# before anything touches the cluster
kmt config validate --config-dir ~/kmt-config
# one release at a time, converged
kmt component install grafana
kmt routing status
| ✓ | converged — re-running writes nothing |
| ✗ | named refusal: missing binary, null key, unknown component |
| · | skipped, and the sentence says why |
§ 05 the platform
Ten releases, declared,
version-pinned.
What a run applies is what the helmfile says — and that helmfile ships inside kmt itself. The versions come from its release index; the version window answers for 2.x. Every component is upstream, unmodified, and replaceable.
-
Tektonci/cd
pipelines
Pipelines, Triggers, the Dashboard and the resolvers — installed by kmt tekton setup-pipelines, not by the helmfile.
tekton.dev -
Helm · Helmfiledelivery
how every release arrives
The desired state of a cluster is one declarative file. Diff, apply, converge — and helm diff tells you what changed before it does.
helmfile.readthedocs.io -
Traefikrelease
routing
The ingress class kubementat installs, applied by kmt routing install. kmt routing status reads which Traefik is really running.
traefik.io -
cert-managerrelease
certificates
Lives "in front of" Traefik in the same group: real certificates for every hostname your cluster serves, renewed before they expire.
cert-manager.io -
Prometheusrelease
metrics
The metrics core, beside the blackbox exporter for probes and the helm exporter so released state is a metric like any other.
prometheus.io -
Grafanarelease
dashboards
Where the cluster is read. kmt users create-grafana-accounts wires the team accounts in; kmt tunnel grafana shows it to you.
grafana.com -
Loki · Alloyrelease
logs
Log aggregation and analysis as a pair: Alloy collects and fans out, Loki is the store you query. No ELK sprawl.
grafana.com/oss/loki -
OpenBaorelease
secrets
The cluster's secret store, forked from Vault before the license changed. The place secrets live when an annotation is not enough.
openbao.org -
Polarisrelease
compliance
Configuration best-practice scanning across the cluster — so drift in your own workloads gets caught by the platform, not by an incident.
fairwinds.com/polaris -
Examplesrepo
your apps
Worked examples: an nginx chart deployed by generated Tekton pipelines, manifests, and the tasks that build and ship an app on Kubernetes.
examples/
Deliberately absent. No service mesh — Linkerd is swept from a cluster that really has it and installed by nothing. No nginx-ingress. And cluster-cronjobs, goldilocks and vpa are namespaces kubementat creates, not releases it applies — kmt component install refuses them for exactly that reason.
§ 06 docs & guides
The manual is in the repo.
The README
Full reference: what installs where, the kmt verbs, the general goal.
read →Platform config
The configuration directory: layers, keys, precedence, the spec of the whole tree.
read →Tekton CI
Tasks, pipelines, triggers and resolvers — how build-and-deploy actually runs.
read →Monitoring & logging
Prometheus, Grafana, Loki and Alloy: what is wired to what and where it is exposed.
read →Git-Crypt
What it protects, where the key lives, and which command failed when unlocking goes wrong.
read →Development flow
The fork-own-customize way to run kubementat as your team's own platform.
read →Additional tools
What the platform does not apply via helmfile: namespaces, helpers, and what they are for.
read →E2E tests
VM-based lanes that apply the product for real and assert it converged.
read →