Come distribuire OpenClaw su Kubernetes
I ricercatori di sicurezza hanno trovato oltre 135.000 istanze OpenClaw completamente esposte su Internet. Molte di queste erano vulnerabili all’esecuzione remota di codice. La crisi di sicurezza di OpenClaw è reale: CVE critiche, skill malevoli e un problema fondamentale nel modo in cui la maggior parte dei deployment gestisce l’autenticazione. Eseguire OpenClaw su un VPS con docker run è facile. Eseguirlo in modo sicuro è tutta un’altra questione.
Kubernetes risolve questo problema. Si ottengono isolamento di rete, limiti di risorse, riavvii automatici e impostazioni di sicurezza che richiederebbero ore per essere configurate manualmente. E con l’Operatore Kubernetes di OpenClaw, si ottiene tutto questo da un singolo file YAML.
Questa guida La porta da zero a un agente OpenClaw pronto per la produzione su Kubernetes. Ogni blocco YAML è pronto per essere copiato e incollato.
Perché un operatore
Eseguire OpenClaw su Kubernetes è molto più di un Deployment e un Service. Servono isolamento di rete, gestione dei Secret, storage persistente, monitoraggio della salute, rollout della configurazione e, opzionalmente, automazione del browser. Configurare tutto questo correttamente a mano è noioso e soggetto a errori.
Un operatore Kubernetes codifica queste esigenze in un’unica Custom Resource. Si dichiara ciò che si vuole, e l’operatore lo riconcilia continuamente con i giusti oggetti Kubernetes. Questo fornisce:
- Sicurezza di default. Ogni agente viene eseguito come UID 1000, tutte le capability Linux rimosse, Seccomp abilitato, filesystem root in sola lettura e una NetworkPolicy deny-by-default che consente solo egress DNS e HTTPS. Nessun hardening manuale necessario.
- Aggiornamenti automatici con rollback. L’operatore interroga il registro OCI per nuove versioni, esegue il backup del workspace, distribuisce l’aggiornamento e automaticamente effettua il rollback se il nuovo pod non supera gli health check.
- Rollout della configurazione. Si modifica
spec.config.rawe l’operatore rileva la modifica dell’hash del contenuto, attivando un aggiornamento progressivo. Lo stesso vale per la rotazione dei secret. - Backup e ripristino. Backup automatico del workspace su storage compatibile S3 alla cancellazione dell’istanza. Ripristino in una nuova istanza da qualsiasi snapshot.
- Autenticazione del gateway. Genera automaticamente un token gateway per istanza. Nessun accoppiamento manuale, nessun mDNS (che in Kubernetes comunque non funziona).
- Rilevamento della deriva. Ogni 5 minuti, l’operatore verifica che ogni risorsa gestita corrisponda allo stato desiderato. Se qualcuno modifica manualmente una NetworkPolicy o elimina un PDB, viene ripristinato.
Prerequisiti
Servono:
- Un cluster Kubernetes (1.28+). Qualsiasi distribuzione conforme funziona: EKS, GKE, AKS, k3s, o un cluster Kind locale per i test.
kubectlconfigurato per il proprio cluster.helmv3 installato.- Una chiave API del proprio provider AI (Anthropic, OpenAI, o qualsiasi endpoint compatibile con OpenAI).
Passo 1: Installare l’operatore
L’operatore viene distribuito come chart Helm OCI. Un singolo comando lo installa:
helm install openclaw-operator \
oci://ghcr.io/openclaw-rocks/charts/openclaw-operator \
--namespace openclaw-operator-system \
--create-namespace
Verificare che sia in esecuzione:
kubectl get pods -n openclaw-operator-system
Si dovrebbe vedere il pod dell’operatore nello stato Running. L’operatore installa anche un webhook di validazione che impedisce configurazioni non sicure (come l’esecuzione come root).
Passo 2: Creare il Secret della chiave API
Memorizzare la chiave API del provider AI in un Secret Kubernetes. L’operatore la inietterà nel container dell’agente:
kubectl create namespace openclaw
kubectl create secret generic openclaw-api-keys \
--namespace openclaw \
--from-literal=ANTHROPIC_API_KEY=sk-ant-your-key-here
Per OpenAI o altri provider, utilizzare il nome della variabile d’ambiente appropriato (OPENAI_API_KEY, OPENROUTER_API_KEY, ecc.). È possibile includere più provider nello stesso Secret.
Suggerimento: Per la produzione, si consideri l’uso dell’External Secrets Operator per sincronizzare le chiavi da AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager o Azure Key Vault. La documentazione dell’operatore contiene esempi dettagliati.
Passo 3: Distribuire il primo agente
Creare un file chiamato my-agent.yaml:
apiVersion: openclaw.rocks/v1alpha1
kind: OpenClawInstance
metadata:
name: my-agent
namespace: openclaw
spec:
envFrom:
- secretRef:
name: openclaw-api-keys
config:
raw:
agents:
defaults:
model:
primary: "anthropic/claude-sonnet-4-20250514"
storage:
persistence:
enabled: true
size: 10Gi
Applicarlo:
kubectl apply -f my-agent.yaml
Questa singola risorsa crea un StatefulSet, un Service, un ServiceAccount, un Role, un RoleBinding, una ConfigMap, un PVC, un PDB, una NetworkPolicy e un Secret per il token gateway. L’operatore riconcilia tutto.
Passo 4: Verificare che sia in esecuzione
Osservare l’avvio dell’istanza:
kubectl get openclawinstances -n openclaw -w
NAME PHASE READY AGE
my-agent Provisioning False 10s
my-agent Running True 45s
Una volta che la fase mostra Running e Ready è True, l’agente è attivo. Controllare i log:
kubectl logs -n openclaw statefulset/my-agent -f
Per interagire con l’agente, fare il port-forward del gateway:
kubectl port-forward -n openclaw svc/my-agent 18789:18789
Poi aprire http://localhost:18789 nel browser.
Passo 5: Collegare un canale
OpenClaw supporta Telegram, Discord, WhatsApp, Signal e altri canali di messaggistica. Ogni canale è configurato tramite variabili d’ambiente. Aggiungere il token pertinente al proprio Secret:
kubectl create secret generic openclaw-channel-keys \
--namespace openclaw \
--from-literal=TELEGRAM_BOT_TOKEN=your-bot-token-here
Poi referenziarlo nella propria istanza:
spec:
envFrom:
- secretRef:
name: openclaw-api-keys
- secretRef:
name: openclaw-channel-keys
OpenClaw rileva automaticamente il token e abilita il canale. Nessuna configurazione aggiuntiva necessaria.
Questo copre le basi. L’agente è in esecuzione, protetto e raggiungibile. Il resto di questa guida copre funzionalità opzionali che è possibile abilitare quando si è pronti.
Automazione del browser
OpenClaw può navigare sul web, fare screenshot e interagire con le pagine. L’operatore rende questa un’aggiunta di una sola riga. Esegue un sidecar Chromium blindato nello stesso pod, connesso via localhost:
spec:
chromium:
enabled: true
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1000m
memory: 2Gi
L’operatore inietta automaticamente una variabile d’ambiente CHROMIUM_URL nel container principale. Il sidecar viene eseguito come UID 1001 con un filesystem root in sola lettura e il proprio security context.
Skill e dipendenze di runtime
Gli skill di OpenClaw da ClawHub possono essere installati in modo dichiarativo. L’operatore esegue un init container che scarica ogni skill prima dell’avvio dell’agente:
spec:
skills:
- "@anthropic/mcp-server-fetch"
- "@anthropic/mcp-server-filesystem"
Se gli skill o i server MCP necessitano di pnpm o Python, abilitare gli init container integrati per le dipendenze di runtime:
spec:
runtimeDeps:
pnpm: true # Installs pnpm via corepack
python: true # Installs Python 3.12 + uv
Gli init container installano questi strumenti sul PVC dei dati, così che persistono tra i riavvii senza appesantire l’immagine del container.
Aggiornamenti automatici
OpenClaw rilascia nuove versioni frequentemente. L’operatore può monitorarle automaticamente, eseguire il backup prima dell’aggiornamento e fare rollback in caso di problemi:
spec:
autoUpdate:
enabled: true
checkInterval: "12h"
backupBeforeUpdate: true
rollbackOnFailure: true
healthCheckTimeout: "10m"
Quando una nuova versione appare nel registro, l’operatore:
- Crea un backup del PVC del workspace su storage compatibile S3
- Aggiorna il tag dell’immagine sul StatefulSet
- Attende fino a
healthCheckTimeoutche il pod superi i controlli di disponibilità - Se il pod non diventa ready, ripristina il tag dell’immagine precedente e il backup
Dopo 3 rollback falliti consecutivi, l’operatore mette in pausa gli aggiornamenti automatici e imposta una condizione per consentire l’indagine.
Nota: L’aggiornamento automatico non ha effetto per le immagini fissate per digest (
spec.image.digest). Se si fissa per digest, gli aggiornamenti si controllano manualmente.
Hardening per la produzione
L’operatore è sicuro di default. Ecco i controlli aggiuntivi per i deployment in produzione.
Monitoraggio con Prometheus
Abilitare il ServiceMonitor per raccogliere le metriche dell’operatore e delle istanze:
spec:
observability:
metrics:
enabled: true
serviceMonitor:
enabled: true
interval: "30s"
L’operatore espone openclaw_reconcile_total, openclaw_reconcile_duration_seconds, openclaw_instance_phase e contatori degli aggiornamenti automatici.
Pianificare su nodi dedicati
Se si gestisce un cluster misto, utilizzare nodeSelector e tolerations per assegnare gli agenti a nodi dedicati:
spec:
availability:
nodeSelector:
openclaw.rocks/nodepool: openclaw
tolerations:
- key: openclaw.rocks/dedicated
value: openclaw
effect: NoSchedule
Aggiungere regole di egress personalizzate
La NetworkPolicy di default consente solo DNS (porta 53) e HTTPS (porta 443). Se l’agente deve raggiungere altri servizi (un database, una coda di messaggi, un’API interna), aggiungere regole di egress:
spec:
security:
networkPolicy:
additionalEgress:
- to:
- ipBlock:
cidr: 10.0.0.0/8
ports:
- port: 5432
protocol: TCP
Identità del provider cloud
Per AWS IRSA o GCP Workload Identity, annotare il ServiceAccount gestito:
spec:
security:
rbac:
serviceAccountAnnotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::123456789:role/openclaw"
Proxy aziendali e CA private
Se il cluster utilizza un proxy che intercetta il TLS, iniettare un bundle CA:
spec:
security:
caBundle:
configMapName: corporate-ca-bundle
key: ca-bundle.crt
L’operatore monta il bundle CA in tutti i container e imposta NODE_EXTRA_CA_CERTS automaticamente.
GitOps
Il CRD OpenClawInstance è un semplice file YAML. Questo significa che si integra direttamente in un workflow GitOps. Archiviare i manifesti degli agenti in un repository git e lasciare che ArgoCD o Flux li sincronizzino con il cluster.
Una struttura tipica del repository:
gitops/
└── agents/
├── kustomization.yaml
├── namespace.yaml
├── agent-a.yaml
└── agent-b.yaml
Ogni modifica passa attraverso una pull request. Il team esamina il diff. Merge su main, e ArgoCD lo applica. Nessun kubectl apply dai laptop, nessuna deriva della configurazione, traccia di audit completa.
L’hashing della configurazione dell’operatore rende questo processo particolarmente fluido. Quando ArgoCD sincronizza una spec.config.raw modificata, l’operatore rileva la modifica dell’hash del contenuto e attiva automaticamente un aggiornamento progressivo. Lo stesso vale per la rotazione dei secret: l’operatore monitora i Secret referenziati e riavvia i pod quando cambiano.
Backup e ripristino
L’operatore supporta backup compatibili con S3. Quando si elimina un’istanza, l’operatore crea automaticamente un backup del PVC del workspace prima della rimozione.
Per ripristinare un agente da un backup in una nuova istanza:
apiVersion: openclaw.rocks/v1alpha1
kind: OpenClawInstance
metadata:
name: my-agent-restored
namespace: openclaw
spec:
restoreFrom: "s3://bucket/path/to/backup.tar.gz"
envFrom:
- secretRef:
name: openclaw-api-keys
storage:
persistence:
enabled: true
size: 10Gi
L’operatore scarica lo snapshot, lo decomprime nel PVC e avvia l’agente con tutti i dati del workspace precedente, gli skill e la cronologia delle conversazioni intatti.
Inferenza locale con Ollama
Se si desidera che gli agenti utilizzino modelli locali (per privacy, latenza o costi), l’operatore offre supporto Ollama di prima classe. Non è necessario configurare un sidecar manualmente: spec.ollama gestisce il container, il pre-download dei modelli, lo storage e l’allocazione GPU:
spec:
ollama:
enabled: true
models:
- "llama3.2"
- "nomic-embed-text"
gpu: 1
resources:
requests:
cpu: "2"
memory: 4Gi
limits:
cpu: "4"
memory: 8Gi
storage:
sizeLimit: 30Gi
Quando abilitato, l’operatore:
- Aggiunge un container sidecar Ollama al pod
- Esegue un init container che scarica preventivamente i modelli elencati prima dell’avvio dell’agente
- Inietta
OLLAMA_HOST=http://localhost:11434nel container principale - Alloca la GPU NVIDIA richiesta tramite i limiti di risorse
nvidia.com/gpu
Di default, i modelli vengono archiviati in un volume emptyDir con un limite di dimensione configurabile. Per uno storage persistente dei modelli tra i riavvii (in modo che i modelli non vengano scaricati di nuovo ogni volta), utilizzare un PVC esistente:
spec:
ollama:
enabled: true
models: ["llama3.2"]
storage:
existingClaim: ollama-models-pvc
Integrazione Tailscale
Esporre l’agente al proprio tailnet senza Ingress, load balancer o IP pubblici. Il campo spec.tailscale dell’operatore gestisce l’iniezione della chiave di autenticazione, l’arricchimento della configurazione e le regole NetworkPolicy:
spec:
tailscale:
enabled: true
mode: serve # or "funnel" for public internet access
authKeySecretRef:
name: tailscale-authkey
hostname: my-agent
Creare il Secret della chiave di autenticazione con una chiave effimera e riutilizzabile dalla console di amministrazione Tailscale:
kubectl create secret generic tailscale-authkey \
--namespace openclaw \
--from-literal=authkey=tskey-auth-...
In modalità serve (predefinita), solo i membri del proprio tailnet possono raggiungere l’agente. In modalità funnel, Tailscale lo espone su Internet pubblico con HTTPS automatico.
L’operatore esegue automaticamente le seguenti operazioni:
- Inietta le variabili d’ambiente
TS_AUTHKEYeTS_HOSTNAME - Unisce
gateway.tailscale.modeegateway.tailscale.resetOnExitnella configurazione OpenClaw - Aggiunge le regole di egress STUN e WireGuard alla NetworkPolicy
Per l’accesso SSO senza password per i membri del tailnet, abilitare authSSO:
spec:
tailscale:
enabled: true
mode: serve
authKeySecretRef:
name: tailscale-authkey
authSSO: true
Questo imposta gateway.auth.allowTailscale=true nella configurazione OpenClaw, consentendo ai membri del tailnet di accedere all’agente senza un token gateway separato.
Sidecar e init container personalizzati
Per casi d’uso oltre il supporto integrato di Ollama e Tailscale, l’operatore accetta sidecar e init container arbitrari. Eseguire un Cloud SQL Proxy per l’accesso al database, un forwarder di log o qualsiasi altro helper accanto all’agente:
spec:
sidecars:
- name: cloudsql-proxy
image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2
args: ["--structured-logs", "project:region:instance"]
resources:
requests:
cpu: 100m
memory: 128Mi
Gli init container personalizzati vengono eseguiti dopo la pipeline di inizializzazione dell’operatore (seeding della configurazione, pnpm, Python, skill):
spec:
initContainers:
- name: fetch-data
image: curlimages/curl:8.5.0
command: ["sh", "-c", "curl -o /data/dataset.json https://..."]
volumeMounts:
- name: data
mountPath: /data
Modalità di merge della configurazione
Di default, l’operatore sovrascrive il file di configurazione ad ogni riavvio del pod. Se l’agente modifica la propria configurazione a runtime (tramite skill o auto-modifica), impostare mergeMode: merge per eseguire un deep-merge della configurazione dell’operatore con la configurazione PVC esistente:
spec:
config:
mergeMode: merge
raw:
agents:
defaults:
model:
primary: "anthropic/claude-sonnet-4-20250514"
In modalità merge, le chiavi specificate dall’operatore hanno la precedenza, ma le chiavi aggiunte dall’agente stesso sopravvivono ai riavvii.
L’esempio completo
Ecco un manifesto pronto per la produzione che combina tutto ciò che è stato presentato in questa guida:
apiVersion: openclaw.rocks/v1alpha1
kind: OpenClawInstance
metadata:
name: production-agent
namespace: openclaw
spec:
envFrom:
- secretRef:
name: openclaw-api-keys
config:
mergeMode: merge
raw:
agents:
defaults:
model:
primary: "anthropic/claude-sonnet-4-20250514"
skills:
- "@anthropic/mcp-server-fetch"
runtimeDeps:
pnpm: true
chromium:
enabled: true
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1000m
memory: 2Gi
ollama:
enabled: true
models: ["llama3.2"]
gpu: 1
resources:
requests:
cpu: "2"
memory: 4Gi
tailscale:
enabled: true
mode: serve
authKeySecretRef:
name: tailscale-authkey
authSSO: true
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 4Gi
storage:
persistence:
enabled: true
size: 10Gi
autoUpdate:
enabled: true
checkInterval: "24h"
backupBeforeUpdate: true
rollbackOnFailure: true
observability:
metrics:
enabled: true
serviceMonitor:
enabled: true
# Remove or adjust these if you don't use dedicated nodes
availability:
nodeSelector:
openclaw.rocks/nodepool: openclaw
tolerations:
- key: openclaw.rocks/dedicated
value: openclaw
effect: NoSchedule
Si applica, e si ottiene un agente AI blindato, con aggiornamenti automatici, capacità di navigazione, inferenza locale, accesso tailnet, monitoraggio, backup e isolamento di rete. Un singolo kubectl apply.
Cosa si ottiene immediatamente
Senza toccare una singola impostazione di sicurezza, ogni agente distribuito dall’operatore è dotato di:
- Esecuzione non-root (UID 1000)
- Filesystem root in sola lettura
- Tutte le capability Linux rimosse
- Profilo Seccomp RuntimeDefault
- NetworkPolicy deny-by-default (solo egress DNS + HTTPS)
- ServiceAccount per istanza senza montaggio automatico del token
- PodDisruptionBudget
- Probe di liveness, readiness e startup
- Token di autenticazione gateway generato automaticamente
- Riconciliazione della deriva ogni 5 minuti
Un webhook di validazione blocca i tentativi di esecuzione come root e avvisa in caso di NetworkPolicy disabilitate, assenza di TLS su Ingress e chiavi di provider AI non rilevate.
Prossimi passi
- Consultare il riferimento API completo per ogni campo del CRD
- Leggere le guide al deployment per EKS, GKE, AKS e Kind
- Configurare catene di fallback dei modelli attraverso più provider AI
- Configurare External Secrets per Vault, AWS, GCP o Azure
Se si riscontrano problemi o si desidera fornire feedback, aprire una issue su GitHub. Anche le PR sono benvenute.
Se non si desidera gestire Kubernetes in autonomia, OpenClaw.rocks si occupa di tutto. Si sceglie un piano, si collega un canale e l’agente è attivo in pochi secondi.