Deploy on standard Kubernetes
Prepare an existing Kubernetes cluster for OpenClaw Enterprise (OCE), then run the custom Helm installation. To install with OpenShell and use the shared first-Agent session, follow Kubernetes setup or the Amazon EKS guide.
Prepare the cluster
Use Kubernetes 1.35 or later, IPv4 connectivity, and a network plugin that
enforces NetworkPolicies. The chart uses explicit IPv4 /32 rules for database
and Kubernetes API traffic. Install the tools in the production
prerequisites. One cluster can host the
OpenClaw Control Plane (OCC) and Agent workloads: OCC runs in openclaw-system,
and Compute creates isolated tenant namespaces. Use two node pools: a trusted
pool for OCC and dedicated Agent gateways, and an Agent pool for Harness and
embedded Agent Pods.
Have the cluster administrator provide a protected kubeconfig and node pools
labeled oce-role=control and oce-role=agents, or record the labels you will
use instead. Select the cluster explicitly:
umask 077export OCC_INPUT_DIRECTORY='/secure/occ'export KUBECONFIG_FILE="$OCC_INPUT_DIRECTORY/kubeconfig"export CONTEXT='<approved-cluster-context>'install -d -m 700 "$OCC_INPUT_DIRECTORY"# Place the administrator-provided kubeconfig at KUBECONFIG_FILE first.chmod 600 "$KUBECONFIG_FILE"kubectl --kubeconfig "$KUBECONFIG_FILE" --context "$CONTEXT" versionkubectl --kubeconfig "$KUBECONFIG_FILE" --context "$CONTEXT" get nodes -L oce-rolekubectl --kubeconfig "$KUBECONFIG_FILE" --context "$CONTEXT" get storageclassesCheck that the node list shows both roles and that the expected StorageClasses exist. Allow node memory on both pools for all running Agents; a dedicated Codex Agent's request is split between them (sizing). Dedicated Codex also needs a node syscall policy compatible with its command sandbox; review the Compute requirements before selecting node images.
Prepare storage, database, and network access
Provide these cluster services before installing OCC:
| Requirement | Operator preparation |
|---|---|
| Private gateway state | An explicit block-backed filesystem StorageClass supporting 10Gi RWO claims and reliable SQLite locking. |
| Bootstrap output | A fresh 1Gi RWO claim using a protected StorageClass; prepare it during shared installation. |
| Dedicated Agent workspace | A default StorageClass supporting 40Gi RWO claims. Embedded Agents do not need this Harness claim. |
| PostgreSQL | An external database with separate application and migrator roles and verified TLS. |
| Container registry | Push access for the image builder and pull access from every eligible node, including tenant workloads. |
| Operator access | An approved HTTPS origin and access path matching auth.baseUrl; the chart does not create public TLS or Ingress. |
An Envoy Gateway ingress for the console origin answers a path with an encoded
slash (%2F) itself: by default it redirects with 307 to the decoded path, so
the API never sees the request. The API refuses such an ID with 400 and names
the parameter. To give callers that answer, attach a ClientTrafficPolicy to the
ingress Gateway, or to its OCE listener with sectionName:
apiVersion: gateway.envoyproxy.io/v1alpha1kind: ClientTrafficPolicymetadata: name: occ-keep-escaped-slashes namespace: <ingress-gateway-namespace>spec: targetRefs: - group: gateway.networking.k8s.io kind: Gateway name: <ingress-gateway> path: escapedSlashesAction: KeepUnchangedEnvoy still resolves . and .. segments and merges slashes. Envoy and the
API router both keep %2F inside one path segment, so a route match cannot
differ between them. If a ClientTrafficPolicy already targets that Gateway or
listener, add path to it.
Keep the console route's request timeout at 15 seconds or more; Envoy Gateway's
default is 15 seconds. Configuration and Secret create, update and delete send no
Kubernetes call later than 12 seconds after the API starts the request, so on a slow
cluster they fail with 503 instead of saving after the ingress answered 504. The
database commit is not bounded by them.
Follow the storage contract
when choosing disks. A NetworkPolicy object alone is not proof of enforcement:
verify allowed and denied traffic with your CNI before placing tenant workloads.
Record the DNS Pod selectors for both Helm dns and Installation Compute
network.dns, exact database destinations, and Kubernetes API
addresses and ports as observed from controller Pods. These become the shared
installation's network settings; do not substitute whole cluster or VPC ranges.
See networking and isolation.
On OpenShift, select the actual DNS backend namespace and Pod labels; the
Helm DNS grants
permit both Service and backend ports. Helm merges dns.podLabels into the chart
default k8s-app: kube-dns. Profile rendering removes that default for you. In
hand-written values, set dns.podLabels.k8s-app: null when the DNS Pods lack that
label. Verify UDP and TCP DNS resolution from
the initialization, API, worker, and enabled supporting workloads, plus denied
traffic to a Pod outside the configured DNS selectors.
On OpenShift with OVN-Kubernetes, the CNI applies egress policy after the
kubernetes Service translates port 443 to the API server port, usually 6443.
Set Helm cluster.cidrs to the API server endpoint IPs and cluster.port to
that port. With the default 443, the API and worker fail with
KUBERNETES_API_UNAVAILABLE. List the endpoints with
oc get endpoints kubernetes -n default.
Configure the protected copies and install
Continue with production installation, retaining this shell's context. At its Configure the Installation step, set these values in the profile input and rerender, or edit the copied manual examples:
- Set
controlPlane.nodeSelectoranddrivers.compute.configuration.runtime.gatewayNodeSelectorto the trusted pool's labels, andruntime.nodeSelectorto the Agent pool's labels. - Replace the bootstrap and gateway StorageClass placeholders with the classes prepared above. The dedicated Harness workspace uses the cluster default.
- Replace sample image references, CIDRs, DNS/client selectors, cluster name, administrator email, and HTTPS origin.
- The example sets
database.caSecretName: occ-rds-ca. For a database whose CA is already trusted by the controller image, set it to"". For another private CA, choose your own Secret name and save its bundle as/secure/occ/occ-database-ca.pem; the shared procedure creates that Secret. Keep hostname-verifying TLS in both database URLs.
Complete bootstrap and occ installation get, then follow
production Agent deployment and
workload verification.
Verify a real model turn and persistence across gateway replacement before
handoff. Record operational ownership using production handoff.
