Skip to main content

Kubernetes provisioner backend

Run Nora agents as Kubernetes Deployments and Services through the generic k8s execution target.
The Kubernetes backend is provider-neutral. Nora reads a kubeconfig, creates a namespace if needed, schedules one Deployment per agent, and creates one Service per agent. OpenClaw Services expose the runtime and gateway ports; Hermes Services expose the runtime and dashboard ports. During stop/start/restart, Nora patches the existing Kubernetes Deployment for the selected cluster and uses stored namespace hints from the agent host when needed. During delete or redeploy, Nora deletes the previous Deployment, Service, and bootstrap ConfigMap before removing or replacing the control-plane runtime reference. These lifecycle paths run through the same shared adapter for K3s, AKS, GKE, EKS, and generic Kubernetes clusters. Stopping an agent scales its Deployment to 0 replicas. Cloud consoles such as AKS can still show the zero-replica Deployment itself as OK because the object is healthy and matching its desired state; verify stop by checking that desired/ready replicas are 0 and that no pods remain for the agent. Use delete or redeploy when the Deployment and Service objects should be removed. The agent Overview tab shows the live Kubernetes pod replica snapshot in the Details block: desired, current, ready, available, and updated counts from the Deployment.
Kubernetes agent detail

Configuration

Register Kubernetes clusters in Admin -> Kubernetes. Nora does not create a Kubernetes execution target from .env; each enabled Admin row with a passing connection test becomes a concrete execution target such as k8s:aks-eastus2. For production, prefer a scoped identity or service account with the permissions below instead of a broad cluster-admin kubeconfig.

Cluster registry

Open Admin -> Kubernetes and register one row per cluster. Enabled rows appear in the operator Deploy page as separate execution targets only after the latest Admin Test result is ok:
FieldPurpose
Cluster idStable id used in persisted agents, for example k8s:aks-eastus2.
LabelOperator-facing name shown in Deploy and runtime cards.
Actual cluster nameCloud or kubeconfig cluster name, shown in target descriptions so operators know which backend is which.
Credential modeUse a mounted kubeconfig path or encrypted kubeconfig content. Encrypted kubeconfigs require ENCRYPTION_KEY.
Namespaces and exposurePer-cluster overrides for OpenClaw, Hermes, Service type, annotations, source ranges, and load-balancer class.
Agents deployed to a registry entry keep deploy_target=k8s and store the selected cluster in execution_target_id.

Admin registry setup

Use clear labels so the Deploy page can show a named cluster such as AKS East US 2 instead of a generic Kubernetes target.
1

Make sure the kubeconfig is mounted into Nora

With docker-compose.kubernetes.yml, NORA_KUBECONFIGS_DIR is mounted into both backend-api and worker-provisioner as /kubeconfigs. Put one kubeconfig file in that directory for each cluster Nora should control.
SetupHost-side .env valueAdmin Kubeconfig path
Single clusterNORA_KUBECONFIGS_DIR=./.secrets/kubeconfigs/kubeconfigs/aks-eastus2
Multiple mounted filesNORA_KUBECONFIGS_DIR=./.secrets/kubeconfigs/kubeconfigs/<cluster-file>
Kind smokeCONTAINER_KUBECONFIG_PATH=/tmp/nora-kind.container.kubeconfig/kubeconfigs/nora-kind.container.kubeconfig
The value used in the Admin form is the container path, not the host path.
2

Open the Admin Kubernetes page

Sign in as an admin and open Admin -> Kubernetes. Click Add cluster.
3

Fill the cluster identity fields

Use stable values that make the Deploy page obvious to operators:
FieldExample
Cluster idaks-eastus2
LabelAKS East US 2
ProviderAKS
Actual cluster namenora-dns-vjb9kjjz
4

Select the credential mode

For an AKS kubeconfig copied to ./.secrets/kubeconfigs/aks-eastus2, use:
FieldValue
Credential modeMounted kubeconfig path
Kubeconfig path/kubeconfigs/aks-eastus2
Do not enter ./.secrets/aks-kubeconfig in this field unless Nora is running directly on the host without Docker. In Compose, always use the path under /kubeconfigs.
5

Set namespaces and exposure

For AKS LoadBalancer deployments:
FieldValue
Fallback namespacenora-openclaw-agents
OpenClaw namespacenora-openclaw-agents
Hermes namespacenora-hermes-agents
Exposure modeLoadBalancer
Service annotations JSON{} for public load balancers, or the internal-LB annotation JSON when needed
Source rangesYour Nora control-plane egress CIDR when you can restrict access
Load balancer classLeave empty for normal AKS Services
6

Save, test, then deploy

Save the cluster, click Test, then open the operator Deploy page. Nora hides failed, untested, and disabled Kubernetes clusters from Deploy for both OpenClaw and Hermes. Once the latest test is ok, the execution target appears as k8s:aks-eastus2 internally and as the label you configured in the UI.
Kubernetes target selected
For several Kubernetes clusters at once, use one Admin registry row per cluster. Mounted-path mode uses files under NORA_KUBECONFIGS_DIR, which is mounted at /kubeconfigs in both containers. For simpler multi-cluster setup, use Encrypted kubeconfig mode and paste each kubeconfig into its registry row; that requires a valid ENCRYPTION_KEY.

Provider quick values

Use these starting values when adding named clusters in Admin -> Kubernetes. Adjust labels, actual cluster names, CIDRs, and provider-specific Service options to match the real cluster.
ProviderExample cluster idCredential modeKubeconfig pathExposure
Kindkind-localMounted kubeconfig path/kubeconfigs/kind-localnode-port
K3sk3s-localMounted kubeconfig path/kubeconfigs/k3s-localnode-port
AKSaks-eastus2Mounted kubeconfig path/kubeconfigs/aks-eastus2load-balancer
GKEgke-us-central1Mounted kubeconfig path/kubeconfigs/gke-us-central1load-balancer
EKSeks-us-east-1Mounted kubeconfig path/kubeconfigs/eks-us-east-1load-balancer
If you paste kubeconfig content instead of mounting a file, select Encrypted kubeconfig and leave the path field empty. That mode is often simpler when Nora controls several cloud clusters from the same Compose stack.

Exposure modes

Set these fields on the Admin cluster row:
ModeUse whenRequired Admin settings
cluster-ipNora runs in the same cluster or has an in-cluster route to Services.Fallback namespace, plus runtime-specific namespaces if used
node-portK3s or another self-hosted cluster where Nora reaches node ports.Runtime host, optional fixed runtime and gateway node ports
load-balancerNora runs outside AKS, GKE, EKS, or another cloud cluster.Optional annotations, source ranges, and load balancer class
NodePort example:
Admin fieldValue
Exposure modeNodePort
Runtime hosthost.docker.internal
Runtime node port30909
Gateway node port31879
LoadBalancer example:
Admin fieldValue
Exposure modeLoadBalancer
Source ranges<nora-control-plane-egress-cidr>
Load balancer timeout1200000

Service customization

Provider-specific Service annotations are saved in the Admin Service annotations JSON field:
{ "example.com/annotation": "value" }
The Admin Source ranges field accepts comma-separated CIDRs. Use it to restrict cloud load balancers to the Nora control-plane egress IP whenever possible. The Admin Load balancer class field is copied to the Service loadBalancerClass field in load-balancer mode.

RBAC expectations

The kubeconfig identity needs permissions in the Admin fallback namespace and in any runtime-specific OpenClaw or Hermes namespaces to:
  • Create and read Namespaces.
  • Create, read, patch, and delete Deployments.
  • Create, read, and delete Services.
  • Create, read, update, and delete ConfigMaps.
  • List Pods for logs and terminal attachment.
  • Read Pod logs.
  • Create Pod exec sessions for runtime env sync and Hermes dashboard recovery.

Provider guides