Skip to Content
Agent RuntimeKubernetes / k3s

Kubernetes / k3s (PoC)

Die Coding-Agenten lassen sich auch als Pod in k3s/Kubernetes betreiben. Dies ist ein Proof of Concept: Es zeigt den tragfähigen Weg und die Stolpersteine gegenüber dem Docker-Compose-Setup.

In Entwicklung / PoC. Einzelinstanz ohne HA, kein Ingress/TLS enthalten — bewusst minimal. Teil der Preview-Phase (1.2.0-insiders.x).

Betriebsmodell

  • Genau eine Instanz. Die Runtime ist stateful (OpenClaw-State-DB im WAL-Modus, Workspaces, Auth, Worktrees) und nicht horizontal skalierbar → StatefulSet mit replicas: 1.
  • Node-lokales Storage (ReadWriteOnce). SQLite-WAL kann auf NFS/Netz-Storage korrumpieren. Unter k3s passt der Default-Provisioner local-path.
  • Agenten-Registrierung beim Start, nicht im Image — siehe unten.

Der entscheidende Unterschied zu Docker

Die Agenten werden im Image (Dockerfile.agents) zur Build-Zeit in ~/.openclaw registriert. Zur Laufzeit gilt jedoch:

  • Docker: Ein frisches Named Volume wird beim ersten Mount aus dem Image geseedet — die Registrierung überlebt.
  • Kubernetes: Ein leeres PVC wird nicht geseedet. Es überdeckt ~/.openclaw vollständig → die eingebackene Registrierung ist weg, im Pod existierte nur Agent main.

Deshalb registriert ein initContainer die Agenten beim Start erneut, gegen das PVC-gemountete ~/.openclaw. install.mjs ist dafür geeignet: läuft ohne laufende Gateway und ist idempotent. Erst danach startet der Gateway-Container.

Voraussetzungen

  • k3s/Kubernetes-Cluster, kubectl
  • Default-StorageClass mit ReadWriteOnce (k3s: local-path ist gesetzt)
  • Zugriff auf ghcr.io/processcube-io/agents (ggf. imagePullSecret)
  • uid/gid verifizieren: Das Manifest nimmt 1000 (node-User) an — sonst sind die PVCs nicht beschreibbar.

Installation

# 1. Namespace (optional) kubectl create namespace processcube-agents kubectl config set-context --current --namespace=processcube-agents # 2. Secret anlegen (NICHT committen) kubectl create secret generic openclaw-agents \ --from-literal=gateway-token="$(openssl rand -hex 32)" \ --from-literal=gh-token="$GH_TOKEN" \ --from-literal=anthropic-setup-token="$ANTHROPIC_SETUP_TOKEN" # beide optional # 3. StatefulSet + Service kubectl apply -k deployment/ # 4. Hochlaufen abwarten kubectl rollout status statefulset/openclaw-agents kubectl logs statefulset/openclaw-agents -c register-agents # Registrierungs-Log

Backend-Login (einmalig)

Für Claude reicht ein Setup-Token — der braucht kein TTY und lässt sich deklarativ aus einem Secret setzen. Token einmalig auf einem beliebigen Rechner mit claude setup-token erzeugen, ins Secret legen und dem Pod als ANTHROPIC_SETUP_TOKEN mitgeben:

# Token in das bestehende Secret legen (Key: anthropic-setup-token) … kubectl patch secret openclaw-agents --type merge \ -p "{\"stringData\":{\"anthropic-setup-token\":\"sk-ant-oat01-…\"}}" kubectl rollout restart statefulset/openclaw-agents # … das Auth-Profil für jeden Agenten anlegen (kein TTY nötig) … kubectl exec statefulset/openclaw-agents -c gateway -- pc-runtime setup --all-agents # … und erneut neu starten: ein laufender Agent sieht das frische Profil sonst # nicht ("No API key found for provider"). kubectl rollout restart statefulset/openclaw-agents kubectl exec statefulset/openclaw-agents -c gateway -- pc-runtime doctor --smoke

Das StatefulSet reicht den Key als ANTHROPIC_SETUP_TOKEN durch (optional: true — ohne Secret startet der Pod normal weiter).

Der Token gilt rund ein Jahr; pc-runtime doctor warnt 30 Tage vor Ablauf. Pro Kunde/Instanz ein eigenes Claude-Konto bzw. Auth-Profil — Tokens nicht zwischen Kunden oder unabhängigen OpenClaw-Instanzen teilen.

Der Codex-Device-Code bleibt interaktiv und braucht weiterhin ein TTY; die Credentials persistieren im codex-PVC und überstehen Pod-Neustarts:

kubectl exec -it statefulset/openclaw-agents -c gateway -- pc-runtime setup

Prüfen:

kubectl exec -it statefulset/openclaw-agents -c gateway -- pc-runtime doctor --smoke kubectl exec -it statefulset/openclaw-agents -c gateway -- openclaw agents list

openclaw agents list muss jetzt code-selector, coding-agent, coding-agent-worker, coding-agent-pr-watcher zeigen — nicht nur main.

Zugriff

In-Cluster (z. B. ProcessCube®-Engine im selben Cluster):

ws://openclaw-agents.<namespace>.svc:18789

Connect-Token = gateway-token aus dem Secret. Extern: Service auf LoadBalancer umstellen oder einen Ingress davorsetzen; für die Control-UI im Browser zusätzlich die Origin freigeben und die Gateway neu starten.

Support-Agent als zweite Instanz

Der Support-Agent nutzt dasselbe Agenten-Image wie die Coding-Agenten (Dockerfile.agents) und braucht zusätzlich IMAP-/SMTP-Zugangsdaten, eine Engine-URL und den Wissens-Index. Als eigenes StatefulSet ableiten:

  • image: → Agenten-Image, initContainer-Command → install.mjs support-agent
  • Mail-/Engine-Env (MAIL_USER, MAIL_PASSWORD, IMAP_HOST, SMTP_HOST …) aus einem Secret (vgl. docker-compose.support.yml)
  • host.docker.internal gibt es in k8s nicht → ENGINE_URL auf die Engine-Service-DNS bzw. einen externen Endpoint setzen
  • Wissens-Index: der Compose-Bind-Mount ist nicht portabel → eigenes PVC, per initContainer/Job befüllen (RW, wegen SQLite-WAL)

Grenzen dieses PoC

  • Einzelinstanz, kein HA. Ein Pod-Neustart killt laufende Worker-/Watcher-Sessions; der Recovery-Cron (alle 5 min) fängt das ab.
  • Kein Ingress/TLS enthalten — bewusst minimal.
  • uid/gid 1000 ist eine Annahme — im Cluster verifizieren.