OpenClaw на Kubernetes

Минимальная отправная точка для запуска OpenClaw в Kubernetes — не production-ready развёртывание. Описаны базовые ресурсы, которые нужно адаптировать под ваше окружение.

Почему не Helm?

OpenClaw — это один контейнер с несколькими конфигурационными файлами. Интересная кастомизация — в контенте агентов (markdown-файлы, скиллы, переопределения конфигурации), а не в инфраструктурном шаблонировании. Kustomize обрабатывает overlay без накладных расходов Helm-чарта. Если развёртывание усложнится, Helm-чарт можно наложить поверх этих манифестов.

Что вам потребуется

  • Работающий Kubernetes-кластер (AKS, EKS, GKE, k3s, kind, OpenShift и т.д.)
  • kubectl, подключённый к кластеру
  • API-ключ хотя бы одного провайдера моделей

Быстрый старт

# Замените на вашего провайдера: ANTHROPIC, GEMINI, OPENAI или OPENROUTER
export <PROVIDER>_API_KEY="..."
./scripts/k8s/deploy.sh

kubectl port-forward svc/openclaw 18789:18789 -n openclaw
open http://localhost:18789

Получите токен шлюза и вставьте в Control UI:

kubectl get secret openclaw-secrets -n openclaw -o jsonpath='{.data.OPENCLAW_GATEWAY_TOKEN}' | base64 -d

Для локальной отладки ./scripts/k8s/deploy.sh --show-token выводит токен после развёртывания.

Локальное тестирование с Kind

Если у вас нет кластера, создайте локальный с Kind:

./scripts/k8s/create-kind.sh           # автоопределение docker или podman
./scripts/k8s/create-kind.sh --delete  # удаление

Затем разверните как обычно через ./scripts/k8s/deploy.sh.

Пошагово

1) Развёртывание

Вариант A — API-ключ в переменной окружения (один шаг):

# Замените на вашего провайдера: ANTHROPIC, GEMINI, OPENAI или OPENROUTER
export <PROVIDER>_API_KEY="..."
./scripts/k8s/deploy.sh

Скрипт создаёт Kubernetes Secret с API-ключом и автоматически сгенерированным токеном шлюза, затем разворачивает. Если Secret уже существует, он сохраняет текущий токен и ключи провайдеров, которые не изменяются.

Вариант B — создание secret отдельно:

export <PROVIDER>_API_KEY="..."
./scripts/k8s/deploy.sh --create-secret
./scripts/k8s/deploy.sh

Используйте --show-token, если хотите вывести токен для локальной отладки.

2) Доступ к шлюзу

kubectl port-forward svc/openclaw 18789:18789 -n openclaw
open http://localhost:18789

Что развёртывается

Namespace: openclaw (настраивается через OPENCLAW_NAMESPACE)
├── Deployment/openclaw        # Один pod, init-контейнер + шлюз
├── Service/openclaw           # ClusterIP на порту 18789
├── PersistentVolumeClaim      # 10Gi для состояния агентов и конфигурации
├── ConfigMap/openclaw-config  # openclaw.json + AGENTS.md
└── Secret/openclaw-secrets    # Токен шлюза + API-ключи

Кастомизация

Инструкции агентов

Отредактируйте AGENTS.md в scripts/k8s/manifests/configmap.yaml и переразверните:

./scripts/k8s/deploy.sh

Конфигурация шлюза

Отредактируйте openclaw.json в scripts/k8s/manifests/configmap.yaml. Полная справка — Конфигурация шлюза.

Добавление провайдеров

Перезапустите с дополнительными ключами:

export ANTHROPIC_API_KEY="..."
export OPENAI_API_KEY="..."
./scripts/k8s/deploy.sh --create-secret
./scripts/k8s/deploy.sh

Существующие ключи провайдеров в Secret сохраняются, если вы их не перезаписываете.

Или обновите Secret напрямую:

kubectl patch secret openclaw-secrets -n openclaw \
  -p '{"stringData":{"<PROVIDER>_API_KEY":"..."}}'
kubectl rollout restart deployment/openclaw -n openclaw

Свой namespace

OPENCLAW_NAMESPACE=my-namespace ./scripts/k8s/deploy.sh

Свой образ

Отредактируйте поле image в scripts/k8s/manifests/deployment.yaml:

image: ghcr.io/openclaw/openclaw:2026.3.1

Доступ за пределами port-forward

Манифесты по умолчанию привязывают шлюз к loopback внутри pod. Это работает с kubectl port-forward, но не с Kubernetes Service или Ingress, которым нужно достучаться до IP pod.

Для доступа через Ingress или балансировщик:

  • Измените привязку шлюза в scripts/k8s/manifests/configmap.yaml с loopback на non-loopback привязку, подходящую вашей модели развёртывания
  • Оставьте авторизацию шлюза включённой и используйте правильный TLS-terminated entrypoint
  • Настройте Control UI для удалённого доступа через поддерживаемую модель веб-безопасности (например, HTTPS/Tailscale Serve и явные allowed origins)

Повторное развёртывание

./scripts/k8s/deploy.sh

Применяет все манифесты и перезапускает pod для подхвата изменений конфигурации или секретов.

Удаление

./scripts/k8s/deploy.sh --delete

Удаляет namespace и все ресурсы в нём, включая PVC.

Архитектурные замечания

  • Шлюз по умолчанию привязывается к loopback внутри pod, поэтому стандартная схема — kubectl port-forward
  • Нет cluster-scoped ресурсов — всё живёт в одном namespace
  • Безопасность: readOnlyRootFilesystem, drop: ALL capabilities, непривилегированный пользователь (UID 1000)
  • Конфигурация по умолчанию сохраняет Control UI на более безопасном локальном пути: loopback bind + kubectl port-forward на http://127.0.0.1:18789
  • Для доступа за пределами localhost используйте поддерживаемую удалённую модель: HTTPS/Tailscale + соответствующая привязка шлюза и настройки origin для Control UI
  • Секреты генерируются во временной директории и применяются напрямую в кластер — секретные данные не записываются в checkout репозитория

Структура файлов

scripts/k8s/
├── deploy.sh                   # Создание namespace + secret, развёртывание через kustomize
├── create-kind.sh              # Локальный Kind-кластер (автоопределение docker/podman)
└── manifests/
    ├── kustomization.yaml      # Kustomize base
    ├── configmap.yaml          # openclaw.json + AGENTS.md
    ├── deployment.yaml         # Pod spec с security hardening
    ├── pvc.yaml                # 10Gi постоянного хранилища
    └── service.yaml            # ClusterIP на 18789