Badacze bezpieczeństwa znaleźli ponad 135 000 instancji OpenClaw całkowicie odsłoniętych w Internecie. Wiele z nich było podatnych na zdalne wykonanie kodu. Kryzys bezpieczeństwa OpenClaw jest prawdziwy: krytyczne CVE, złośliwe skille i fundamentalny problem z tym, jak większość wdrożeń obsługuje uwierzytelnianie. Uruchomienie OpenClaw na VPS z docker run jest proste. Bezpieczne uruchomienie to zupełnie inny problem.

Kubernetes rozwiązuje ten problem. Otrzymuje Pan/Pani izolację sieciową, limity zasobów, automatyczne restarty i ustawienia bezpieczeństwa, których ręczna konfiguracja zajęłaby godziny. A z operatorem Kubernetes OpenClaw otrzymuje Pan/Pani to wszystko z jednego pliku YAML.

Ten przewodnik prowadzi od zera do gotowego do produkcji agenta OpenClaw na Kubernetes. Każdy blok YAML jest gotowy do skopiowania i wklejenia.

Dlaczego operator

Uruchomienie OpenClaw na Kubernetes to więcej niż Deployment i Service. Potrzebna jest izolacja sieciowa, zarządzanie Secretami, trwałe przechowywanie, monitorowanie kondycji, rollouty konfiguracji i opcjonalnie automatyzacja przeglądarki. Prawidłowe skonfigurowanie tego wszystkiego ręcznie jest żmudne i podatne na błędy.

Operator Kubernetes koduje te wymagania w jednym Custom Resource. Deklaruje się, czego się chce, a operator ciągle rekoncyliuje to do właściwych obiektów Kubernetes. To daje:

  • Bezpieczeństwo domyślnie. Każdy agent działa jako UID 1000, wszystkie capability Linuksa usunięte, Seccomp włączony, system plików root tylko do odczytu i domyślna polityka NetworkPolicy deny, która zezwala tylko na egress DNS i HTTPS. Bez ręcznego hardeningu.
  • Automatyczne aktualizacje z rollbackiem. Operator odpytuje rejestr OCI o nowe wersje, tworzy kopię zapasową workspace, wdraża aktualizację i automatycznie cofa zmiany, jeśli nowy pod nie przejdzie health checków.
  • Rollouty konfiguracji. Zmiana spec.config.raw powoduje, że operator wykrywa zmianę hasha zawartości i wyzwala aktualizację kroczącą. To samo dotyczy rotacji secretów.
  • Kopia zapasowa i przywracanie. Automatyczna kopia zapasowa workspace do pamięci kompatybilnej z S3 przy usuwaniu instancji. Przywracanie do nowej instancji z dowolnego snapshota.
  • Uwierzytelnianie bramy. Automatycznie generuje token bramy na instancję. Bez ręcznego parowania, bez mDNS (który w Kubernetes i tak nie działa).
  • Wykrywanie dryfu. Co 5 minut operator sprawdza, czy każdy zarządzany zasób odpowiada pożądanemu stanowi. Jeśli ktoś ręcznie edytuje NetworkPolicy lub usunie PDB, zostanie to przywrócone.

Wymagania wstępne

Potrzebne są:

  • Klaster Kubernetes (1.28+). Dowolna zgodna dystrybucja działa: EKS, GKE, AKS, k3s lub lokalny klaster Kind do testów.
  • kubectl skonfigurowany dla klastra.
  • helm v3 zainstalowany.
  • Klucz API dostawcy AI (Anthropic, OpenAI lub dowolny endpoint kompatybilny z OpenAI).

Krok 1: Instalacja operatora

Operator jest dostarczany jako chart Helm OCI. Jedno polecenie go instaluje:

helm install openclaw-operator \
  oci://ghcr.io/openclaw-rocks/charts/openclaw-operator \
  --namespace openclaw-operator-system \
  --create-namespace

Sprawdzenie, czy działa:

kubectl get pods -n openclaw-operator-system

Powinien być widoczny pod operatora w stanie Running. Operator instaluje również webhook walidujący, który zapobiega niebezpiecznym konfiguracjom (takim jak uruchamianie jako root).

Krok 2: Utworzenie Secreta z kluczem API

Klucz API dostawcy AI należy przechowywać w Secrecie Kubernetes. Operator wstrzyknie go do kontenera agenta:

kubectl create namespace openclaw

kubectl create secret generic openclaw-api-keys \
  --namespace openclaw \
  --from-literal=ANTHROPIC_API_KEY=sk-ant-your-key-here

Dla OpenAI lub innych dostawców należy użyć odpowiedniej nazwy zmiennej środowiskowej (OPENAI_API_KEY, OPENROUTER_API_KEY itp.). W jednym Secrecie można uwzględnić wielu dostawców.

Wskazówka: W środowisku produkcyjnym warto rozważyć użycie External Secrets Operator do synchronizacji kluczy z AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager lub Azure Key Vault. Dokumentacja operatora zawiera szczegółowe przykłady.

Krok 3: Wdrożenie pierwszego agenta

Należy utworzyć plik o nazwie 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

Zastosowanie:

kubectl apply -f my-agent.yaml

Ten pojedynczy zasób tworzy StatefulSet, Service, ServiceAccount, Role, RoleBinding, ConfigMap, PVC, PDB, NetworkPolicy i Secret tokena bramy. Operator rekoncyliuje to wszystko.

Krok 4: Weryfikacja działania

Obserwacja uruchamiania instancji:

kubectl get openclawinstances -n openclaw -w
NAME       PHASE        READY   AGE
my-agent   Provisioning False   10s
my-agent   Running      True    45s

Gdy faza pokaże Running, a Ready będzie True, agent jest aktywny. Sprawdzenie logów:

kubectl logs -n openclaw statefulset/my-agent -f

Aby komunikować się z agentem, należy przekierować port bramy:

kubectl port-forward -n openclaw svc/my-agent 18789:18789

Następnie otworzyć http://localhost:18789 w przeglądarce.

Krok 5: Podłączenie kanału

OpenClaw obsługuje Telegram, Discord, WhatsApp, Signal i inne kanały komunikacyjne. Każdy kanał jest konfigurowany przez zmienne środowiskowe. Odpowiedni token należy dodać do Secreta:

kubectl create secret generic openclaw-channel-keys \
  --namespace openclaw \
  --from-literal=TELEGRAM_BOT_TOKEN=your-bot-token-here

Następnie odwołać się do niego w instancji:

spec:
  envFrom:
    - secretRef:
        name: openclaw-api-keys
    - secretRef:
        name: openclaw-channel-keys

OpenClaw automatycznie wykrywa token i aktywuje kanał. Dodatkowa konfiguracja nie jest potrzebna.


To obejmuje podstawy. Agent działa, jest zabezpieczony i dostępny. Reszta tego przewodnika omawia opcjonalne funkcje, które można włączyć, gdy będzie się gotowym.

Automatyzacja przeglądarki

OpenClaw może przeglądać strony internetowe, robić zrzuty ekranu i wchodzić w interakcje ze stronami. Operator sprawia, że jest to dodatek jednolinijkowy. Uruchamia zahartowany sidecar Chromium w tym samym podzie, połączony przez localhost:

spec:
  chromium:
    enabled: true
    resources:
      requests:
        cpu: 500m
        memory: 1Gi
      limits:
        cpu: 1000m
        memory: 2Gi

Operator automatycznie wstrzykuje zmienną środowiskową CHROMIUM_URL do głównego kontenera. Sidecar działa jako UID 1001 z systemem plików root tylko do odczytu i własnym kontekstem bezpieczeństwa.

Skille i zależności uruchomieniowe

Skille OpenClaw z ClawHub można instalować deklaratywnie. Operator uruchamia init kontener, który pobiera każdy skill przed uruchomieniem agenta:

spec:
  skills:
    - "@anthropic/mcp-server-fetch"
    - "@anthropic/mcp-server-filesystem"

Jeśli skille lub serwery MCP wymagają pnpm lub Pythona, należy włączyć wbudowane init kontenery dla zależności uruchomieniowych:

spec:
  runtimeDeps:
    pnpm: true    # Installs pnpm via corepack
    python: true  # Installs Python 3.12 + uv

Init kontenery instalują te narzędzia na PVC danych, dzięki czemu przetrwają restarty bez powiększania obrazu kontenera.

Automatyczne aktualizacje

OpenClaw często wydaje nowe wersje. Operator może je automatycznie śledzić, tworzyć kopię zapasową przed aktualizacją i cofać zmiany, jeśli coś pójdzie nie tak:

spec:
  autoUpdate:
    enabled: true
    checkInterval: "12h"
    backupBeforeUpdate: true
    rollbackOnFailure: true
    healthCheckTimeout: "10m"

Gdy w rejestrze pojawi się nowa wersja, operator:

  1. Tworzy kopię zapasową PVC workspace na pamięć kompatybilną z S3
  2. Aktualizuje tag obrazu w StatefulSet
  3. Czeka do healthCheckTimeout, aż pod przejdzie sprawdzenia dostępności
  4. Jeśli pod nie stanie się gotowy, przywraca poprzedni tag obrazu i kopię zapasową

Po 3 kolejnych nieudanych rollbackach operator wstrzymuje automatyczne aktualizacje i ustawia warunek, aby można było zbadać sprawę.

Uwaga: Automatyczna aktualizacja nie ma efektu dla obrazów przypiętych przez digest (spec.image.digest). W przypadku przypięcia przez digest aktualizacje kontroluje się ręcznie.

Hardening produkcyjny

Operator jest domyślnie bezpieczny. Oto dodatkowe ustawienia dla wdrożeń produkcyjnych.

Monitorowanie z Prometheus

Włączenie ServiceMonitor do zbierania metryk operatora i instancji:

spec:
  observability:
    metrics:
      enabled: true
      serviceMonitor:
        enabled: true
        interval: "30s"

Operator udostępnia openclaw_reconcile_total, openclaw_reconcile_duration_seconds, openclaw_instance_phase i liczniki automatycznych aktualizacji.

Planowanie na dedykowanych węzłach

W przypadku klastra mieszanego należy użyć nodeSelector i tolerations, aby przypiąć agentów do dedykowanych węzłów:

spec:
  availability:
    nodeSelector:
      openclaw.rocks/nodepool: openclaw
    tolerations:
      - key: openclaw.rocks/dedicated
        value: openclaw
        effect: NoSchedule

Dodawanie niestandardowych reguł egress

Domyślna NetworkPolicy zezwala tylko na DNS (port 53) i HTTPS (port 443). Jeśli agent musi dotrzeć do innych usług (bazy danych, kolejki wiadomości, wewnętrznego API), należy dodać reguły egress:

spec:
  security:
    networkPolicy:
      additionalEgress:
        - to:
            - ipBlock:
                cidr: 10.0.0.0/8
          ports:
            - port: 5432
              protocol: TCP

Tożsamość dostawcy chmury

Dla AWS IRSA lub GCP Workload Identity należy zanotować zarządzane ServiceAccount:

spec:
  security:
    rbac:
      serviceAccountAnnotations:
        eks.amazonaws.com/role-arn: "arn:aws:iam::123456789:role/openclaw"

Firmowe proxy i prywatne CA

Jeśli klaster używa proxy przechwytującego TLS, należy wstrzyknąć pakiet CA:

spec:
  security:
    caBundle:
      configMapName: corporate-ca-bundle
      key: ca-bundle.crt

Operator montuje pakiet CA we wszystkich kontenerach i automatycznie ustawia NODE_EXTRA_CA_CERTS.

GitOps

CRD OpenClawInstance to zwykły plik YAML. To oznacza, że pasuje bezpośrednio do workflow GitOps. Manifesty agentów należy przechowywać w repozytorium git i pozwolić ArgoCD lub Flux synchronizować je z klastrem.

Typowa struktura repozytorium:

gitops/
└── agents/
    ├── kustomization.yaml
    ├── namespace.yaml
    ├── agent-a.yaml
    └── agent-b.yaml

Każda zmiana przechodzi przez pull request. Zespół przegląda diff. Merge do main, a ArgoCD to stosuje. Bez kubectl apply z laptopów, bez dryfu konfiguracji, pełna ścieżka audytu.

Hashowanie konfiguracji operatora czyni to szczególnie płynnym. Gdy ArgoCD synchronizuje zmienioną spec.config.raw, operator wykrywa zmianę hasha zawartości i automatycznie wyzwala aktualizację kroczącą. To samo dotyczy rotacji secretów: operator monitoruje referencjonowane Secrety i restartuje pody po ich zmianie.

Kopia zapasowa i przywracanie

Operator obsługuje kopie zapasowe kompatybilne z S3. Przy usuwaniu instancji operator automatycznie tworzy kopię zapasową PVC workspace przed usunięciem.

Aby przywrócić agenta z kopii zapasowej do nowej instancji:

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

Operator pobiera snapshot, rozpakowuje go do PVC i uruchamia agenta ze wszystkimi poprzednimi danymi workspace, skillami i historią konwersacji.

Lokalne wnioskowanie z Ollama

Jeśli agenci mają używać modeli lokalnych (ze względu na prywatność, opóźnienia lub koszty), operator oferuje wsparcie Ollama pierwszej klasy. Nie trzeba ręcznie konfigurować sidecara: spec.ollama obsługuje kontener, wstępne pobieranie modeli, pamięć i alokację 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

Po włączeniu operator:

  1. Dodaje kontener sidecar Ollama do poda
  2. Uruchamia init kontener, który wstępnie pobiera wymienione modele przed startem agenta
  3. Wstrzykuje OLLAMA_HOST=http://localhost:11434 do głównego kontenera
  4. Przydziela żądany GPU NVIDIA poprzez limity zasobów nvidia.com/gpu

Domyślnie modele są przechowywane w wolumenie emptyDir z konfigurowalnym limitem rozmiaru. Dla trwałego przechowywania modeli między restartami (aby modele nie były pobierane ponownie za każdym razem) należy użyć istniejącego PVC:

spec:
  ollama:
    enabled: true
    models: ["llama3.2"]
    storage:
      existingClaim: ollama-models-pvc

Integracja z Tailscale

Udostępnienie agenta w tailnecie bez Ingress, load balancerów czy publicznych IP. Pole spec.tailscale operatora obsługuje wstrzykiwanie klucza uwierzytelniającego, wzbogacanie konfiguracji i reguły NetworkPolicy:

spec:
  tailscale:
    enabled: true
    mode: serve       # or "funnel" for public internet access
    authKeySecretRef:
      name: tailscale-authkey
    hostname: my-agent

Utworzenie Secreta klucza uwierzytelniającego z efemerycznym, wielokrotnego użytku kluczem z konsoli administracyjnej Tailscale:

kubectl create secret generic tailscale-authkey \
  --namespace openclaw \
  --from-literal=authkey=tskey-auth-...

W trybie serve (domyślnym) tylko członkowie tailnetu mogą dotrzeć do agenta. W trybie funnel Tailscale udostępnia go w publicznym Internecie z automatycznym HTTPS.

Operator automatycznie:

  • Wstrzykuje zmienne środowiskowe TS_AUTHKEY i TS_HOSTNAME
  • Łączy gateway.tailscale.mode i gateway.tailscale.resetOnExit z konfiguracją OpenClaw
  • Dodaje reguły egress STUN i WireGuard do NetworkPolicy

Dla bezhasłowego logowania SSO dla członków tailnetu należy włączyć authSSO:

spec:
  tailscale:
    enabled: true
    mode: serve
    authKeySecretRef:
      name: tailscale-authkey
    authSSO: true

To ustawia gateway.auth.allowTailscale=true w konfiguracji OpenClaw, pozwalając członkom tailnetu na dostęp do agenta bez osobnego tokena bramy.

Niestandardowe sidecary i init kontenery

Dla przypadków użycia wykraczających poza wbudowane wsparcie Ollama i Tailscale, operator akceptuje dowolne sidecary i init kontenery. Uruchomienie Cloud SQL Proxy dla dostępu do bazy danych, forwardera logów lub dowolnego innego pomocnika obok agenta:

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

Niestandardowe init kontenery uruchamiają się po własnym potoku inicjalizacji operatora (seedowanie konfiguracji, pnpm, Python, skille):

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

Tryb łączenia konfiguracji

Domyślnie operator nadpisuje plik konfiguracyjny przy każdym restarcie poda. Jeśli agent modyfikuje własną konfigurację w czasie działania (przez skille lub samomodyfikację), należy ustawić mergeMode: merge dla głębokiego łączenia konfiguracji operatora z istniejącą konfiguracją PVC:

spec:
  config:
    mergeMode: merge
    raw:
      agents:
        defaults:
          model:
            primary: "anthropic/claude-sonnet-4-20250514"

W trybie łączenia klucze określone przez operatora mają pierwszeństwo, ale klucze dodane przez agenta samodzielnie przetrwają restarty.

Kompletny przykład

Oto manifest gotowy do produkcji, łączący wszystko z tego przewodnika:

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

Zastosowanie tego manifestu daje zahartowanego, automatycznie aktualizowanego agenta AI z przeglądarką, lokalnym wnioskowaniem, dostępem tailnet, monitorowaniem, kopią zapasową i izolacją sieciową. Jeden kubectl apply.

Co otrzymuje się od razu

Bez dotykania jakiegokolwiek ustawienia bezpieczeństwa, każdy agent wdrożony przez operatora jest dostarczany z:

  • Działaniem jako nie-root (UID 1000)
  • Systemem plików root tylko do odczytu
  • Wszystkimi usuniętymi capability Linuksa
  • Profilem Seccomp RuntimeDefault
  • NetworkPolicy default-deny (tylko egress DNS + HTTPS)
  • ServiceAccount na instancję bez automatycznego montowania tokena
  • PodDisruptionBudget
  • Sondami liveness, readiness i startup
  • Automatycznie wygenerowanym tokenem uwierzytelniania bramy
  • 5-minutową rekoncyliacją dryfu

Webhook walidujący blokuje próby uruchomienia jako root i ostrzega o wyłączonych NetworkPolicy, brakującym TLS na Ingress i niewykrytych kluczach dostawcy AI.

Następne kroki

W razie problemów lub uwag prosimy o otwarcie issue na GitHub. PR-y również są mile widziane.

Jeśli nie chce Pan/Pani samodzielnie zarządzać Kubernetes, OpenClaw.rocks zajmie się tym wszystkim. Wystarczy wybrać plan, podłączyć kanał, a agent będzie aktywny w kilka sekund.