在本地大模型服务从个人实验走向团队应用后,单个 Ollama 实例很容易成为性能与可用性的瓶颈:并发请求可能互相排队,容器重启会造成服务中断,直接暴露端口也不利于统一管理。一个实用方案是将多个 Ollama 容器放在 Traefik 后端,由 Traefik 负责服务发现、请求分发、HTTPS 入口以及 TLS 证书续期。这样既保留 Ollama 部署简单的优势,也能获得更规范的生产入口。🚀
一、整体架构与工作方式
整个架构可以分为三层:客户端通过域名访问 HTTPS 接口;Traefik 监听 80 和 443 端口,根据 Host 规则匹配路由;多个 Ollama 实例在内部 Docker 网络中提供 11434 端口。Traefik 从 Docker 标签读取动态配置,并把请求转发到符合条件的容器。Docker 官方的 Traefik 指南说明,Docker Provider 会监听容器事件、读取标签并更新路由配置,后端容器只需与 Traefik 处于同一网络,无须把服务端口发布到宿主机,具体可参考 Docker 官方指南。
需要注意的是,负载均衡解决的是入口流量分发,而不是模型文件或显存共享。每个 Ollama 实例仍有独立的模型缓存、运行队列和计算资源。为了避免请求被分配到尚未准备好的节点,所有实例应提前拉取相同模型,并尽量保持版本、环境变量和硬件能力一致。⚙️
二、部署前的准备工作
- 准备一台安装了 Docker 与 Docker Compose 的服务器,或多台能够被 Traefik 访问的计算节点。
- 准备一个域名,例如 ollama.example.com,并把 DNS 记录解析到 Traefik 所在服务器。
- 开放 80 和 443 端口。HTTP-01 验证通常需要 80 端口,TLS-ALPN-01 验证则依赖 443 端口。
- 创建专用网络,例如执行 docker network create ollama-net。
- 确认每个 Ollama 实例可以获得必要的 CPU、内存或 GPU 资源。使用 NVIDIA GPU 时,需要先正确安装 NVIDIA Container Toolkit,Ollama 的 CPU、NVIDIA GPU 与 AMD GPU 容器启动方式可查看 Ollama Docker 文档。
三、配置 Traefik 与自动证书
Traefik 的静态配置需要启用 Docker Provider、Web 与 WebSecure 入口,并配置 ACME 证书解析器。建议关闭容器默认暴露功能,仅允许带有明确标签的服务进入反向代理,降低其他容器被意外公开的风险。🔒
services:
traefik:
image: traefik:v3
ports:
- "80:80"
- "443:443"
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.le.acme.email=admin@example.com"
- "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.le.acme.httpchallenge=true"
- "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./letsencrypt:/letsencrypt"
networks:
- ollama-net
首次启动前应创建证书存储目录,并限制 ACME 文件权限。证书数据必须持久化,否则 Traefik 容器重建后可能重复申请证书。正式上线前可以使用 Let’s Encrypt 测试环境检查配置,以免因反复调试触发申请频率限制。Traefik 对 ACME、HTTP Challenge、TLS Challenge 和 DNS Challenge 的配置说明可参阅 来源链接 ACME 官方文档。
四、启动多个 Ollama 后端
在 Compose 文件中定义 ollama-1、ollama-2 等服务,让它们加入同一个 ollama-net 网络。两个实例使用相同的 Traefik Service 名称后,Traefik 会把它们视为同一组后端服务器。实例无需映射宿主机的 11434 端口,只需通过标签告诉 Traefik 容器内部监听端口。
ollama-1:
image: ollama/ollama
volumes:
- ollama1-data:/root/.ollama
networks:
- ollama-net
labels:
- "traefik.enable=true"
- "traefik.http.routers.ollama.rule=Host(`ollama.example.com`)"
- "traefik.http.routers.ollama.entrypoints=websecure"
- "traefik.http.routers.ollama.tls.certresolver=le"
- "traefik.http.services.ollama.loadbalancer.server.port=11434"
为第二个实例设置不同的数据卷,但复用相同的路由与 Service 标签即可。启动后分别执行模型拉取操作,确保所有后端都具备客户端将要调用的模型。Ollama API 支持生成、对话、嵌入和模型管理等接口,应用端只需把原来的本地地址改成 HTTPS 域名,接口路径基本保持不变,详见 Ollama API 文档。
五、生产环境中的关键优化
健康检查与故障隔离
建议为负载均衡服务配置健康检查,并使用能够快速返回的接口判断实例状态。仅检查容器进程存在并不代表模型推理可用,还应结合响应超时、GPU 状态和实际请求失败率进行监控。当某个节点持续异常时,应先从后端池中移除,再排查模型加载或硬件问题。
流式响应与超时
Ollama 的生成接口可以返回流式数据,长文本生成也可能持续较长时间。因此需要合理设置 Traefik 转发超时,并确认调用端能够持续读取响应。不要把超时设得过短,否则中断看起来会像模型故障;也不宜无限放宽,应根据模型规模、上下文长度和业务等待上限制定策略。
安全边界与访问控制
HTTPS 只能保护传输链路,不能代替身份认证。若接口可被公网访问,应在 Traefik 中增加 BasicAuth、ForwardAuth、IP 白名单或限流中间件,并避免公开 Traefik Dashboard。Docker Socket 即使以只读方式挂载仍属于敏感资源,要求更高时可以使用 Socket Proxy 限制 Traefik 可读取的 Docker API 范围。🛡️
负载均衡不等于容量翻倍
推理负载的耗时差异较大,普通轮询无法感知某个实例是否正在处理超长任务。并发较低时轮询通常足够;任务复杂度差异明显时,可在业务层增加队列、并发限制或模型分组。例如,将大模型与嵌入模型使用不同域名或路由,避免短请求被长生成任务阻塞。
六、验证与排障步骤
- 启动 Traefik 后查看日志,确认 Docker Provider、入口点和证书解析器正常加载。
- 启动两个 Ollama 实例,确认它们加入相同网络,并能从 Traefik 容器访问 11434 端口。
- 检查域名解析是否指向正确公网地址,再访问 HTTPS 接口观察证书颁发者和有效期。
- 连续发起多次 API 请求,通过 Traefik 访问日志或实例日志确认流量进入不同后端。
- 停止其中一个 Ollama 容器,验证剩余实例能否继续处理新请求。
- 若出现 502,重点检查网络、服务端口标签和 Ollama 监听状态;若证书申请失败,则检查 DNS、端口、防火墙和 ACME 挑战方式。
总结
通过 Traefik 统一接入多个 Ollama 实例,可以实现动态服务发现、后端负载均衡、HTTPS 终止和 TLS 证书自动续期,让大模型接口从“直接暴露端口”升级为更易维护的服务入口。实际部署时,除了 Compose 配置,还要同步关注模型一致性、GPU 资源隔离、流式响应超时、健康检查和访问认证。先用两个实例完成故障切换与证书验证,再结合监控结果扩容,通常比一次性搭建复杂集群更加稳妥。✅