Install¶
KubeManta installs via Helm from a private OCI registry. Your license key authenticates image pulls — there is no separate pull token to manage.
One page, one command
Everything you need is here. The builder below
assembles the exact helm command for your cloud, load balancer and
certificate — no other page has a different version of it.
Prerequisites¶
kubectlconfigured and pointed at your target clusterhelm3.8 or newer (OCI registry support required)- A KubeManta license key — get one free at kubemanta.com
Enter your email and the key arrives by return, along with the exact helm
commands for your key. Free licenses unlock the read-only core;
Pro adds AI, alerting and Helm write
operations.
Required flags¶
Every install needs these. Everything else has safe defaults.
| Flag | Required | Description |
|---|---|---|
license.key |
Yes | Your KubeManta license key — auto-creates the registry pull secret |
global.hostname |
Yes (for Ingress) | Public hostname, e.g. km.example.com |
global.ingressClassName |
Yes (for Ingress) | gce · alb · traefik |
global.tls |
Yes (for Ingress) | true for HTTPS · false for HTTP-only |
security.cookieSecure |
Yes when TLS | Must match global.tls |
global.acmCertificateArn |
EKS + TLS only | ACM certificate ARN |
rbac.allowWrites |
No | Default false (read-only). Set true to enable pod restart/delete, deployment scale. |
expertMode.enabled |
No | Default false. Set true for cluster-admin terminal + Helm write ops. |
metrics.kubeletScrape.enabled |
No | Default false. Grants read-only get on nodes/proxy so the Metrics tab can chart pod network bandwidth without Prometheus. CPU/memory work without it. Details below. |
agent.anthropicApiKey |
No | Pre-loads Anthropic key into PTY terminal sessions for Claude Code. |
global.hostnameandglobal.ingressClassNamemust both be set — either alone will not create an Ingress.Secure by default: a vanilla install is read-only observability. Add
--set rbac.allowWrites=truefor write features; add--set expertMode.enabled=truefor the cluster-admin terminal and Helm write ops.
Authenticate to the registry¶
KubeManta's images and chart are served from registry.kubemanta.com, gated by your
license key. Log in once with Helm (the username is always license) — this lets Helm
pull the chart, and the in-cluster pull secret handles image pulls:
echo '<LICENSE-KEY>' | helm registry login registry.kubemanta.com \
--username license --password-stdin
Use --password-stdin, not --password
Passing the key as --password <LICENSE-KEY> writes it into your shell
history and into the process list, where anyone else on the box can read it.
Piping it on stdin does not. This is the same command the license email
sends you.
helm install vs helm upgrade¶
The commands below use helm upgrade --install, which both creates the release
and updates an existing one — convenient when you are re-running a documented
scenario or driving it from automation.
For a first install by hand, helm install is the clearer command, and it is
what your license email contains. Afterwards, use helm upgrade to change a
setting or move to a new version — helm install fails once the release exists:
# change a setting later; --reset-then-reuse-values keeps everything you set
helm upgrade kubemanta oci://registry.kubemanta.com/kubemanta/charts/stable/kubemanta \
--namespace kubemanta-system --reset-then-reuse-values \
--set global.hostname=km.example.com
Use --reset-then-reuse-values, not --reuse-values
--reuse-values replays the previous release's computed values, which
freezes every chart default at whatever it was when that release was
created — so later improvements never reach your install, silently and with
no error. Our own two demo clusters ran a 30-minute session timeout for
weeks after the chart default became 8 hours, with no override set anywhere,
because of exactly this.
--reset-then-reuse-values takes the new chart defaults and re-applies
your explicit values on top, which is what "keep my settings, take your
improvements" actually means.
Build your install command¶
Answer five questions. Every flag below is validated against the chart itself, so the command it produces is the same one this page would tell you to write by hand — there is no second version to keep in sync.
1. Where are you installing?
2. Who owns the load balancer?
2b. How does that load balancer reach the cluster?
3. TLS certificate
4. Features
5. Details
No license key? Get a free one — the Free tier needs no key at all, but a key unlocks your trial.
Your install command
Step 1 — sign in to the registry with your license key (the chart is license-gated; an anonymous pull is refused):
Step 2 — install:
Using a load balancer you already run?
Choose "I already have one" above. The wizard drops the chart's Ingress and reminds you of the two things that are easy to miss: trusting your edge's source CIDRs, and routing the terminal WebSocket to the agent Service. Exposure & Load Balancers has the full topology detail and per-cloud worked examples.
What "full-featured" actually enables¶
KubeManta is read-only by default, deliberately. Three of the flags above change that, and they are worth understanding rather than pasting:
| Flag | What it turns on | What it grants |
|---|---|---|
rbac.allowWrites=true |
Pod restart/delete, deployment scale, apply manifests, pod exec | Adds write verbs to the reader ClusterRole cluster-wide |
expertMode.enabled=true |
Browser terminal writes, Helm install/upgrade/rollback, Resource Builder apply | Deploys a separate expert-exec pod holding a cluster-admin token. Restricted by NetworkPolicy to the agent, and every use is audited. |
security.scanning.enabled=true |
Security tab: image CVEs + workload misconfigurations | Read access to trivy-operator CRDs. Self-scan Jobs additionally need rbac.allowWrites. |
metrics.kubeletScrape.enabled=true |
Network bandwidth charts without Prometheus | Read-only get on nodes/proxy. CPU and memory work without it. |
Drop any you do not want — each is independent, and the product degrades cleanly rather than breaking.
Two things stay off even in a "full" install, on purpose:
rbac.readSecrets=true— lets the AI, MCP and terminal read Secret values. Add it only if you need the secret-viewing UI; it widens what an AI prompt or a leaked session can reach. Scope it withrbac.secretsNamespacesif you do.security.airgap.enabled=true— a deny-egress NetworkPolicy for sealed networks. Read Air-gap first: license validation is an online call, so paid features degrade to Free after the offline grace period.
Two features are not Helm flags at all — configure them after install:
- AI — add a provider key in Admin → AI. Nothing is sent anywhere until you do.
- SSO (Enterprise) — Admin → Auth.
Network access (egress allowlist)¶
KubeManta runs entirely inside your cluster. If your nodes sit behind an egress
firewall, an EgressNetworkPolicy, or a proxy that blocks outbound traffic by
default, allow the domains below. All connections are outbound HTTPS (TCP 443)
from the agent pod. Only two are ever required; everything else is
feature-gated — if you don't use the feature, you don't need the domain.
Always required¶
| Domain | What it's for | When |
|---|---|---|
registry.kubemanta.com |
Pull the license-gated agent, UI, and Helm-chart OCI images. Fronted by Cloudflare, so also allow Cloudflare edge IPs if you filter by IP rather than SNI. | Install & upgrade only (image pull). |
api.keygen.sh |
License validation (Keygen). Validates every tier, including Free — the agent re-checks periodically and caches the result, so a brief outage is tolerated (offline grace), but a permanent block eventually disables licensed features. | Runtime, periodic. |
Air-gapped / fully sealed clusters
With a local Ollama AI provider (or AI disabled), the operator scan
source (bring-your-own Trivy), and the update check turned off, the only
egress KubeManta needs is registry.kubemanta.com at install time and
api.keygen.sh for licensing. Everything below can stay blocked.
Optional — AI features¶
Needed only when AI is enabled and you use that provider. KubeManta's own
AI Guardrails → Egress Control can additionally enforce a deny-by-default
allowlist on this outbound traffic (Security → AI Guardrails), and
local_only mode restricts it to in-cluster providers with zero egress.
| Domain | What it's for |
|---|---|
api.anthropic.com |
Anthropic Claude — the default provider for AI Diagnose, the Copilot, and autonomous alert investigation, and the Claude Code CLI inside the browser terminal. |
console.anthropic.com, claude.ai |
Claude Code OAuth login in the terminal (per-user sign-in; only if operators authenticate Claude Code interactively rather than with an API key). |
api.openai.com |
OpenAI provider (if selected). |
generativelanguage.googleapis.com |
Google Gemini provider (if selected). |
api.groq.com |
Groq provider (if selected). |
<resource>.openai.azure.com |
Azure OpenAI provider — your own resource endpoint (if selected). |
| (your endpoint) | Custom OpenAI-compatible provider — whatever base_url you configure. An in-cluster Ollama needs no egress. |
Optional — other features¶
| Domain | What it's for | Enabled by |
|---|---|---|
api.kubemanta.com |
In-product update check ("a newer version is available"). Outbound-only, sends no cluster data, and is disableable in Admin → License. | On by default; opt-out. |
ghcr.io, mirror.gcr.io |
Trivy vulnerability database + Trivy scanner image for container self-scan. Not needed in operator / bring-your-own-scanner mode. |
security.scanning self-scan. |
acme-v02.api.letsencrypt.org |
Let's Encrypt ACME certificate issuance. | cert-manager TLS (installCertManager / a Let's Encrypt issuer). |
hooks.slack.com, events.pagerduty.com, api.opsgenie.com, api.datadoghq.com, (your webhook host) |
Delivering alert notifications to the integration you configure. | Alert integrations. |
AWS sts.*/ec2.*.amazonaws.com, GCP compute.googleapis.com, Azure management.azure.com |
Multi-cloud network topology (VPC/subnet inventory) — only the cloud(s) you add credentials for. | Cloud credentials (Admin → Cloud). |
ghcr.io, pkg-containers.githubusercontent.com |
Image pull only if you install from GHCR (global.pullToken) instead of the default registry.kubemanta.com. |
GHCR install path. |
IMDS is blocked by design
The bundled NetworkPolicy blocks the cloud metadata endpoint
(169.254.169.254) from the agent pod. Cloud topology uses the credentials
you provide, not node IAM — so blocking IMDS does not affect it.
After install¶
Get your admin password¶
The admin password is set at install time — there is no first-login setup step (setting a password from a public URL is blocked by design). If you provided security.adminPassword, use that. Otherwise the chart auto-generates a stable one; retrieve it:
kubectl get secret kubemanta-admin -n kubemanta-system \
-o jsonpath='{.data.password}' | base64 -d ; echo
Log in as the admin user with that password. Change it anytime (the install seed never overwrites an already-set password):
DNS¶
# Get the load balancer address
kubectl get ingress kubemanta -n kubemanta-system \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}{.status.loadBalancer.ingress[0].hostname}'
Create an A record (GKE/AKS, or an in-cluster controller) or CNAME record (EKS) pointing your hostname at the address above.
Verify¶
# Agent health
kubectl exec -n kubemanta-system deploy/kubemanta-agent -- \
python3 -c "import urllib.request; print(urllib.request.urlopen('http://localhost:8080/healthz').read())"
# Pod status
kubectl get pods -n kubemanta-system
# Stream logs
kubectl logs -n kubemanta-system deploy/kubemanta-agent -f
kubectl logs -n kubemanta-system deploy/kubemanta-ui -f
Cluster metrics (metrics-server)¶
KubeManta's node and pod CPU/memory utilization reads the Kubernetes
metrics.k8s.io aggregated API, served by metrics-server. There is nothing
to configure in KubeManta — the agent reads it in-cluster via its ServiceAccount
(the reader role already grants metrics.k8s.io read). But metrics-server must
be present in the cluster, and it is not on every distribution.
Check first
kubectl top nodes — if it returns CPU/memory, you're done. If it says
"Metrics API not available", install metrics-server below. Until then the
utilization panels show a "metrics unavailable" hint (everything else works).
| Platform | metrics-server | What to do |
|---|---|---|
| GKE | Pre-installed (managed add-on) | Nothing |
| AKS | Pre-installed (managed add-on) | Nothing |
| k3s / k0s / microk8s | Bundled | Nothing (microk8s: microk8s enable metrics-server) |
| EKS | Not installed by default | Install (below) — omit the --kubelet-insecure-tls step |
| kubeadm / bare-metal / vanilla | Not included | Install (below) — keep the --kubelet-insecure-tls step |
Install¶
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# BARE-METAL / kubeadm ONLY — kubelet serving certs are self-signed, so
# metrics-server can't verify them. (Skip this on EKS, where the certs are valid.)
kubectl patch deployment metrics-server -n kube-system --type=json \
-p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'
kubectl -n kube-system rollout status deploy/metrics-server --timeout=120s
kubectl top nodes # should now list every node with CPU + memory
metrics-server is a lightweight (~50 MiB) read-only scraper. Once it reports, KubeManta's utilization populates within about a minute (metrics are cached briefly). KubeManta also samples metrics-server in the background to build its own short-term CPU/memory trend charts (about 7 days of retention, Metrics → Built-in) — no Prometheus needed. A Prometheus connected via Admin → Observability remains a separate integration for long-retention history, your application metrics, and ad-hoc PromQL (see Metrics).
Bandwidth trends without Prometheus (opt-in)¶
metrics-server exposes no network metrics. To light up the Metrics tab's pod network bandwidth trends, KubeManta can scrape each node's kubelet cadvisor endpoint through the API-server proxy using its own ServiceAccount — opt in with one Helm value:
# Fresh install — add to any of the install commands above:
--set metrics.kubeletScrape.enabled=true
# Existing install — turn it on with an upgrade:
helm upgrade kubemanta oci://registry.kubemanta.com/kubemanta/charts/stable/kubemanta \
--version 1.0.0 \
-n kubemanta-system --reset-then-reuse-values \
--set metrics.kubeletScrape.enabled=true
What the flag does:
- Grants the reader ClusterRole one extra read-only permission:
getonnodes/proxy(this is how the agent reaches/api/v1/nodes/<node>/proxy/metrics/cadvisor). No new components, no egress. - Sets
METRICS_KUBELET_SCRAPE=trueon the agent so it attempts the scrape.
What you get / lose:
- On: RX/TX bandwidth trend charts in Metrics → Built-in (counter-reset and gap handling built in).
- Off (default): CPU/memory metrics and trends are unaffected — only the bandwidth charts stay empty, with an in-product hint. The scrape is fail-soft: without the RBAC grant it simply records the reason and skips.
Off by default because nodes/proxy reaches kubelet handlers — it is granted
only on explicit opt-in. If you already run a cluster-scraping Prometheus you
can skip this entirely and set the metrics source to prometheus instead
(Admin → Observability can generate the scrape
config
for it).
Restricted / policy-enforced clusters (OPA Gatekeeper, AKS Azure Policy, Kyverno)¶
KubeManta ships hardened by default — there is no profile flag to flip. Every container renders with CPU + memory limits, runAsNonRoot, a read-only root filesystem (writable /tmp and cache via emptyDir), all Linux capabilities dropped, the RuntimeDefault seccomp profile, an AppArmor annotation, and projected ServiceAccount tokens (automatic token mounting is off on the pods that talk to the API server, each given an explicit projected token volume). This clears the common Gatekeeper "baseline" / "restricted" bundles out of the box.
Two things a policy-enforced cluster still enforces that a Helm chart cannot satisfy for you — configure them on the cluster side:
-
Allowed container images. Add the KubeManta images to your image-allowlist constraint (or mirror them into your approved registry and override the
*.image.repositoryvalues accordingly):registry.kubemanta.com/kubemanta/*— the agent and UI (license-gated)python:3.12-alpine— the pre-install validation hook (preflight.image; air-gapped?--set preflight.enabled=false)aquasec/trivy:*— the container self-scan Job (security.scanning.selfScan.image)
-
Service / ingress constraints. If a policy restricts Service ports or requires HTTPS-only Ingress, allow KubeManta's ports and front the UI with your own TLS edge (
ingress.enabled=false+ your own gateway is supported).
Relax knobs if a policy or user tooling collides
Two escape hatches let you relax the settings most likely to collide with a customer's tooling — everything else stays hardened:
security.appArmorProfile— defaultruntime/default; set tounconfinedto emit no AppArmor annotation, orlocalhost/<name>to pin a custom loaded profile.terminal.readOnlyRootFilesystem— defaulttrue; setfalseif a terminal user's tooling insists on writing outside$HOMEand/tmp(both stay writable regardless). Every other container's root filesystem stays read-only unconditionally.
Restrict to specific namespaces¶
By default KubeManta auto-discovers all non-system namespaces. To restrict:
helm upgrade kubemanta oci://registry.kubemanta.com/kubemanta/charts/stable/kubemanta \
--version 1.0.0 \
-n kubemanta-system --reset-then-reuse-values \
--set "tenantNamespaces[0]=my-app" \
--set "tenantNamespaces[1]=staging"
Bring your own TLS certificate¶
Terminate TLS in the cluster from a certificate you already hold. Create the Secret first — an Ingress can only reference a Secret in its own namespace:
kubectl create secret tls kubemanta-tls \
--cert=fullchain.pem --key=privkey.pem \
-n kubemanta-system
--cert must be the full chain, not the leaf alone
Leaf certificate first, then any intermediates. A leaf-only Secret still
validates in a browser that happens to have cached the intermediate, and
fails everywhere else — which is why this is usually reported as
"works on my machine" rather than as a certificate problem.
openssl s_client -connect host:443 -showcerts shows what is actually served.
Then point the chart at it. The builder above emits these flags when you choose Existing TLS Secret; to add them to a release that already exists:
helm upgrade kubemanta oci://registry.kubemanta.com/kubemanta/charts/stable/kubemanta \
-n kubemanta-system --reset-then-reuse-values \
--set global.tls=true \
--set global.tlsSecret=kubemanta-tls \
--set security.cookieSecure=true
If global.tlsSecret is left unset the chart still expects a Secret, defaulting
to <release-name>-tls (kubemanta-tls for a release named kubemanta). Naming
it per release is deliberate — two releases in one namespace would otherwise
collide on a single certificate.
Not for ALB or Google-managed certificates
An AWS ALB reads certificates from ACM, and a Google-managed certificate
is provisioned by GCP; neither consumes a Kubernetes Secret. The chart
therefore omits spec.tls entirely for tlsProvider=acm and
gcp-managed — on GKE a stray spec.tls referencing a missing Secret
stalls load-balancer provisioning silently, with no error anywhere.
Use this option with an in-cluster controller: Traefik, HAProxy,
Contour.