Skip to main content
一个副本的每次编译都只使用一个节点的 CPU:在我们配备 2 个 vCPU 的测试节点上,六个同时进行的编译所花的时间是单个编译的三倍,而其他节点却处于空闲状态。多个副本可以将用户及其编译分散到各个节点上。 本方案遵循 Overleaf 的水平扩展设计,并将其移植到 Kubernetes:
请从一开始就规划好 S3。已在其卷上保存文件的实例需要先进行 S3 迁移。本方案将替代第 5 步中的 Deployment:在应用 StatefulSet 之前请先删除它(kubectl delete -f 40-overleaf.yaml)。
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 与 /git/ 一样路由到 overleaf-0(参见 MCP 服务器);在端口 8080 上使用普通 HTTP(该镜像以非 root 用户运行,在 containerd 下无法绑定端口 80);通过集群 DNS 查找服务器(Pod IP 在每次重启时都会变化);使用 DaemonSet,使每个节点都能响应;以及使用 balance leastconn 代替默认的 roundrobin(参见下面的 Q&A)。
80-haproxy.yaml
externalTrafficPolicy: Local 会在 X-Forwarded-For 中保留用户的 IP 地址。
6

TLS

按照 TLS 代理中的说明在 HAProxy 中终止 HTTPS,然后在 60-config.yaml 中将 OVERLEAF_SITE_URL 设置为 https:// 地址,并设置 OVERLEAF_SECURE_COOKIE: "true"。

预期效果

我们在三个各配备 2 个 vCPU 和 4 GB 内存的节点上测试了三个副本,MongoDB、Redis、Garage、git-bridge 和 HAProxy 也运行在这些节点上:
  • 12 名用户同时编译一篇 600 页的文档:全部 12 名用户都完成了编译并获取到 PDF,每个副本 4 名用户;一轮耗时 8 到 18 秒。每个节点至少保留了 1.3 GB 可用内存。
  • 每个用户都停留在同一个副本上(Cookie server-pro-ha),包括必须来自执行编译的副本的 PDF 下载。在 HTTPS 下同样如此,包括编辑器的 WebSocket。
  • 当某个副本停止时,其用户会在大约 15 到 20 秒内遇到错误,直到 HAProxy 将其标记为下线;之后用户会转移到另一个副本并保持登录状态,因为会话保存在 Redis 中。

Q&A

回答:在我们的测试中,使用 Overleaf 的示例配置(roundrobin,每个节点一个 HAProxy)时,12 名新用户在三个副本上的分布为 8、3 和 1,最繁忙的副本让最慢的用户等待了 29 秒。使用 leastconn(优先选择打开连接数最少的副本,每个编辑器都会保持一个 WebSocket 连接)时,同样的测试得到的分布为 4、4 和 4,耗时 18 秒。会话保持不受影响:它来自 Cookie。
回答:可以,前提是它能根据 Cookie 路由到固定的副本、支持 WebSocket、允许 10 分钟的请求时间和 50 MB 的上传、将其 keep-alive 超时保持在 65 秒以下、发送 X-Forwarded-For 和 X-Forwarded-Proto,并将 /git/ 和 /project/<id>/mcp 发送到 overleaf-0。请路由到各副本自身的名称(overleaf-N.overleaf-hl),而不是路由到对每个请求进行负载均衡的 Service。
回答:添加一个安装了 Docker 和 TeX Live 镜像的节点,在 70-overleaf.yaml 中设置 replicas: 4,并在 HAProxy 配置中添加一行 server overleaf-3 ...(同时递增 config-hash,以便 HAProxy 重启)。
最后修改于 2026年11月2日