Skip to main content
Одна реплика использует для каждой компиляции CPU одного узла: на наших тестовых узлах с 2 vCPU шесть одновременных компиляций выполнялись в три раза дольше одной, тогда как остальные узлы простаивали. Несколько реплик распределяют пользователей и их компиляции по узлам. Эта схема следует архитектуре горизонтального масштабирования Overleaf, перенесённой на Kubernetes:
Планируйте S3 с самого начала. Экземпляру, который уже хранит файлы на своём томе, сначала нужна миграция на S3. Эта конфигурация заменяет Deployment из шага 5: удалите его (kubectl delete -f 40-overleaf.yaml), прежде чем применять StatefulSet.
1

Хранилище S3

Создайте три бакета и двух пользователей, как описано в разделе S3, с помощью вашего сервиса S3 или Garage в кластере, и поместите четыре ключа в Secret overleaf-s3. В приведённой ниже конфигурации используется пример с Garage с той страницы.
2

Конфигурация

Этот ConfigMap заменяет 30-config.yaml. Он добавляет S3 и git-bridge и направляет OVERLEAF_SITE_URL на балансировщик нагрузки:
60-config.yaml
3

Реплики

70-overleaf.yaml
  • StatefulSet, а не Deployment. Каждая реплика получает стабильное имя (overleaf-0, overleaf-1, …), на которое ссылаются cookie балансировщика нагрузки и git-bridge, а OrderedReady сначала запускает только overleaf-0, поэтому миграции базы данных выполняет лишь одна реплика.
  • Одна реплика на узел. Каждая реплика запускает свои компиляции через Docker своего узла и хранит их в /srv/overleaf-ha своего узла.
  • V1_HISTORY_URL для каждой реплики. Каждая реплика выдаёт ссылки на историю со своим собственным именем, чтобы git-bridge мог к ним обратиться.
4

git-bridge

75-git-bridge.yaml
Почему GIT_BRIDGE_HOST — фиксированный IP-адрес, объясняется в разделе Интеграция с Git.
5

Балансировщик нагрузки

Конфигурация HAProxy — это пример Overleaf с пятью изменениями: /project/<id>/mcp направляется на overleaf-0, как и /git/ (см. MCP-сервер); обычный HTTP на порту 8080 (образ работает от имени пользователя без прав root, который не может занять порт 80 под containerd); серверы находятся через DNS кластера (IP-адреса подов меняются при каждом перезапуске); DaemonSet, чтобы отвечал каждый узел; и balance leastconn вместо roundrobin по умолчанию (см. раздел «Вопросы и ответы» ниже).
80-haproxy.yaml
externalTrafficPolicy: Local сохраняет IP-адреса пользователей в X-Forwarded-For.
6

TLS

Завершайте HTTPS в HAProxy, как описано в разделе TLS-прокси, затем задайте в 60-config.yaml для OVERLEAF_SITE_URL адрес https:// и OVERLEAF_SECURE_COOKIE: "true".

Чего ожидать

Мы протестировали три реплики на трёх узлах с 2 vCPU и 4 ГБ памяти каждый, с MongoDB, Redis, Garage, git-bridge и HAProxy на тех же узлах:
  • 12 пользователей одновременно компилировали документ на 600 страниц: все 12 скомпилировали и получили свой PDF, по 4 пользователя на реплику; один цикл занимал от 8 до 18 секунд. На каждом узле оставалось доступно не менее 1,3 ГБ памяти.
  • Каждый пользователь остаётся на одной реплике (cookie server-pro-ha), включая загрузку PDF, которая должна выполняться с реплики, выполнившей компиляцию. То же верно и для HTTPS, включая WebSocket редактора.
  • Когда реплика останавливается, её пользователи получают ошибки примерно 15–20 секунд, пока HAProxy не пометит её как недоступную; затем они переходят на другую реплику и остаются в системе, поскольку сессии хранятся в Redis.

Вопросы и ответы

Ответ: С примером Overleaf (roundrobin, один HAProxy на узел) 12 новых пользователей в нашем тесте распределились по трём репликам как 8, 3 и 1, и самая загруженная реплика заставляла самых медленных пользователей ждать 29 секунд. С leastconn, который выбирает реплику с наименьшим числом открытых соединений (каждый редактор держит открытым WebSocket), тот же тест дал 4, 4 и 4 и 18 секунд. Привязка сессий не меняется: она обеспечивается cookie.
Ответ: Да, если он маршрутизирует по cookie на стабильную реплику, поддерживает WebSocket, допускает время запроса до 10 минут и загрузки до 50 МБ, держит тайм-аут keep-alive ниже 65 секунд, отправляет X-Forwarded-For и X-Forwarded-Proto, а также направляет /git/ и /project/<id>/mcp на overleaf-0. Маршрутизируйте на собственные имена реплик (overleaf-N.overleaf-hl), а не на Service, который распределяет каждый запрос.
Ответ: Добавьте узел с Docker и образами TeX Live, задайте replicas: 4 в 70-overleaf.yaml и добавьте строку server overleaf-3 ... в конфигурацию HAProxy (а также увеличьте config-hash, чтобы HAProxy перезапустился).
Последнее изменение 2 ноября 2026 г.