Масштабируем OpenClaw: Docker, Kubernetes и отказоустойчивость

Масштабируем OpenClaw: Docker, Kubernetes и отказоустойчивость

Продолжаем серию статей о контейнеризации OpenClaw и его развертывании в Kubernetes, а также о неочевидных сложностях при настройке автомасштабирования. В материале детально разбирается путь от Dockerfile до продакшн-кластера — с рабочими конфигурациями, инструкциями и примерами сборки. Предложенные решения не всегда оптимальны, поэтому в текст включены комментарии эксперта, где указаны возможные улучшения и альтернативные подходы.

OpenClaw, запущенный на одном сервере, справляется с большинством задач, стоящих перед агентами. Для личного использования, параллельных сессий и простой автоматизации его возможностей достаточно. Однако одного VPS перестает хватать при появлении пиковых нагрузок.

В продакшене пиковые нагрузки у OpenClaw возникают быстрее, чем можно ожидать. Параллельные сессии, тяжелые cron-задачи, интенсивная работа с памятью и одновременные входящие сообщения от нескольких коннекторов — всё это приводит к перегрузке шлюза. Он начинает упираться в лимиты CPU и RAM, а отказоустойчивость стремительно падает.

Когда это происходит, остаётся два пути: добавить вычислительных мощностей или пересмотреть архитектуру. Если вы выбираете второй — эта статья для вас. Мы рассмотрим контейнеризацию в Docker, отказоустойчивый деплой через Kubernetes и управление stateful-хранилищем, без которого стабильная работа нескольких инстансов невозможна.

Предполагается, что вы уже умеете разворачивать один инстанс OpenClaw. Здесь мы сосредоточимся исключительно на вопросах масштабирования.

Когда масштабирование — не оверхед?

Большинство личных и небольших командных конфигураций отлично работают на одном сервере. Добавлять оркестрацию без реальной необходимости — значит увеличивать операционную сложность.

Как понять, что пришло время масштабировать систему?

  • Нагрузка на CPU выше 80% при параллельных сессиях. Если шлюз не справляется с двумя-тремя одновременными сессиями, дальнейшее нагружение одного инстанса бессмысленно.
  • Появляются OOM-киллы в логах. Сложные tool chains, индексация памяти и мультиагентный роутинг быстро исчерпывают RAM. Если ОС убивает процесс шлюза — пора распределять нагрузку.
  • Более 10 одновременных сессий или множество cron-задач. Шлюз изолирует сессии через механизм lane, но у одного процесса есть предел производительности.
  • Требуется zero-downtime. Обновление через systemd вызывает простои. Если перерывы недопустимы — нужны реплики и rolling-деплой.
  • Высокий поток входящих webhook-событий. Сотни событий в час превращают один шлюз в бутылочное горлышко.

Контейнеризация OpenClaw с Docker

Пишем свой Dockerfile

OpenClaw поддерживает Docker «из коробки» и поставляется с официальным образом openclaw/openclaw:latest. Однако при необходимости контроля над окружением лучше собрать образ самостоятельно. Это позволяет добавлять системные пакеты, использовать непривилегированных пользователей и кастомизировать сборку.

За основу берётся образ на базе Node 22 slim:

Примечание: использование CMD node dist/index.js health || exit 1 в хелсчеке запускает новый процесс Node.js при каждой проверке. Это ресурсоёмко и медленно. Лучше использовать легковесный HTTP-запрос к уже запущенному процессу — как сделано в Kubernetes через httpGet.

Что можно изменить под себя:

  • Если нужны ffmpeg или другие системные зависимости, установите их до копирования кода: RUN apt-get update && apt-get install -y ffmpeg build-essential. Это сохранит кэш при пересборке.
  • Переключитесь на непривилегированного пользователя. Добавьте USER node и убедитесь, что права на тома корректны после chown.
  • Выберите между Alpine и Debian slim. Alpine может конфликтовать с нативными Node-модулями. Для продакшна предпочтительнее bookworm-slim.

Три сервиса — один Compose

Для типичного деплоя нужны три сервиса: шлюз, CLI-утилита и реверс-прокси. Ниже — пример docker-compose.yml для всех трёх:

Примечание: секция deploy.resources работает только в Docker Swarm. Для обычного docker compose используйте флаг --compatibility или управляйте ресурсами через resources вне deploy.

Обратите внимание на два именованных тома:

  • openclaw-config — хранит ~/.openclaw: конфиги, учётные данные, сессии, cron/jobs.json.
  • openclaw-workspace — содержит MEMORY.md, папку memory/, инструменты и скиллы.

Оба тома должны быть персистентными — эфемерное хранилище не подойдёт.

Сервис openclaw-cli использует те же тома, что и шлюз. Это позволяет выполнять административные команды через одноразовые контейнеры, не вмешиваясь в работу шлюза:

docker compose run --rm openclaw-cli channels login

docker compose run --rm openclaw-cli status --all

docker compose exec openclaw-gateway openclaw status

Для команд с TTY добавьте -it:

docker compose run -it --rm openclaw-cli channels login

Изолируем агентов в песочницах

Песочницы повышают отказоустойчивость: при сбоях в tool-цепочке ущерб локализуется. OpenClaw запускает агентов в изолированных субконтейнерах, которые контролируются хост-шлюзом. Режим изоляции настраивается в agents.defaults.sandbox.mode: non-main (все, кроме главного) или all.

Песочницы монтируют /workspace и по умолчанию работают с network: none, с выборочными egress-правилами. Неактивные удаляются каждые 24 часа, просроченные — раз в 7 дней.

Примечание: песочницы и docker-in-docker. Изоляция через сеть — хороший шаг для безопасности. Но если песочницы запускаются через dind, в Kubernetes это создаёт проблемы: конфликты cgroup, уязвимости изоляции. Лучше использовать альтернативы — например, gVisor или Firecracker.

Деплой OpenClaw в Kubernetes

Docker-образ готов. Теперь — выбор оркестратора. Docker Compose подходит для одного хоста. Kubernetes — когда нужны реплики, автоматический фейловер, rolling-обновления и автомасштабирование.

Kubernetes добавляет операционную сложность. Если OpenClaw работает на VPS и справляется — оставайтесь в простом окружении. Если у вас SLA по аптайму — переходите к кластеру.

Хранилище секретов и namespace

Изолируйте ресурсы в отдельном namespace. Секреты (логины, токены) должны храниться в Secret, а не в ConfigMap или переменных окружения.

Base64-значения генерируются так: echo -n 'your-value' | base64. В продакшене лучше использовать External Secrets Operator для подтягивания секретов из внешнего хранилища.

Манифест деплоя

Три реплики — разумный минимум для отказоустойчивости. Если одна падает, две продолжают работать. Liveness-проба перезапускает под при зависании. Readiness-проба убирает под из балансировки, пока он не готов принимать трафик.

Персистентные тома

Для многорепликового деплоя тома config и workspace требуют режима ReadWriteMany (RWX), чтобы все поды могли одновременно к ним обращаться. Не все хранилища поддерживают RWX. Если в кластере нет подходящего storage class, добавьте NFS.

Если используются внешние бэкенды памяти (QMD, Cognee, Mem0), запускайте их отдельными деплоями с собственными PVC. Шлюзы подключаются к ним через внутренний DNS — так проще масштабировать и управлять.

Service и Ingress

Увеличьте таймауты прокси: OpenClaw использует WebSocket, а стандартные 60 секунд в nginx могут обрывать соединения. Установите минимум 3600 секунд (1 час).

Horizontal Pod Autoscaler

HPA масштабирует реплики по загрузке CPU, если в деплое указаны requests и limits.

Порог в 70% — консервативный выбор: лучше добавить ресурсы до перегрузки. Минимум в две реплики гарантирует работоспособность при падении одной.

Защита от простоя: Pod Disruption Budget

При обслуживании кластера Kubernetes может останавливать поды. Pod Disruption Budget (PDB) ограничивает количество одновременно останавливаемых подов.

Например, при трёх репликах и minAvailable: 2 за один раз можно остановить только одну. Это обеспечивает zero-downtime во время обновлений.

Общее состояние между репликами

Это — главная сложность мультиреплицированного деплоя. OpenClaw не является stateless: в нём хранятся сессии, cron-задачи, авторизация и память агентов. Если три реплики одновременно пишут в общий NFS-том — возникает состояние гонки.

Архитектура OpenClaw изначально рассчитана на один шлюз. Общее хранилище через RWX PV подходит для конфигов и учётных данных (в основном чтение) и для файлов памяти (последовательная запись). Но cron/jobs.json — проблема: при нескольких шлюзах возможны дублирование задач, если все реплики читают один файл и запускают выполнение независимо.

Примечание: Главный редфлаг. Фраза «архитектура OpenClaw спроектирована вокруг модели с одним шлюзом» — ключевая. Попытка запустить её в мультиинстансном режиме — архитектурно рискованное решение. RWX-тома, общий NFS, Redis-локи — это костыли поверх неадаптированного фундамента. Такой подход чреват состояниями гонки, задержками и трудновоспроизводимыми багами. Решение OPENCLAW_SKIP_CRON — ручное управление без автоматического фейловера.

Варианты решения:

  1. Назначить крон-лидера. Включите cron только на одной реплике (OPENCLAW_SKIP_CRON=0), остальные — с OPENCLAW_SKIP_CRON=1. Создайте отдельный Deployment для лидера. Остальные реплики обрабатывают трафик, а лидер — задачи.
  2. Использовать Redis или внешний сервис блокировок. Сложнее, но надёжнее при масштабировании.

Бэкенды памяти (QMD, Cognee, Mem0) должны быть выделенными сервисами. Все поды шлюза подключаются к одному эндпоинту через DNS — так состояние памяти остаётся согласованным.

Высокая доступность: health-чеки, rolling-обновления и фейловер

При правильной настройке Kubernetes сам управляет здоровьем подов: перезапускает зависшие, убирает неготовые из ротации. Rolling-обновления с maxUnavailable: 1 гарантируют, что минимум два пода всегда в работе. Pod Disruption Budget предотвращает массовое отключение.

Kubernetes не решает фейловер на уровне каналов. Например, Telegram доставляет вебхуки только на один активный эндпоинт. Убедитесь, что Ingress или балансировщик направляет вебхуки на стабильный адрес кластера, а не на IP пода. То же касается Discord и WhatsApp.

Также есть нюансы с авторизацией. WhatsApp-сессии по QR-коду привязаны к устройству и часто истекают. Данные авторизации должны обновляться для всех подов. Решение — использовать openclaw-cli для записи в общие тома конфигурации.

Бэкапы в контейнеризованном сетапе

Именованные тома и PVC — не бэкап. Они защищают от перезапуска, но не от сбоев хранилища или кластера. Для Docker Compose добавьте контейнер с cron-задачей, который делает снапшоты в S3 или на удалённый сервер. Для Kubernetes используйте Velero — стандартный инструмент для бэкапов PV и состояния кластера.

Антихрупкость. Автор описал запуск OpenClaw в кластере, но упустил важные аспекты продакшн-стабильности: ● Распределённое хранилище сессий — вместо NFS используйте Redis. Сессии, блокировки, состояние — всё это должно быть в in-memory хранилище. ● Очередь сообщений — входящие события должны попадать в очередь (Kafka, RabbitMQ), а не распределяться напрямую. ● Rate limiting — защита от перегрузки вебхуков. ● Логирование и трейсинг — централизованные логи (Loki, ELK) и распределённый трейсинг (OpenTelemetry, Jaeger) критичны для отладки в мультирепликовой среде.

Стоит ли в это ввязываться?

Для большинства пользователей описанная архитектура — оверкил. Грамотно настроенный VPS с systemd, мониторингом и бэкапами покрывает подавляющее большинство сценариев без сложностей Kubernetes. Контейнеризацию и кластеризацию стоит рассматривать только при реальных лимитах: OOM-киллы, стабильно высокая нагрузка на CPU, критичные простои.

Читать оригинал