0%

迁移后端服务到Docker Swarm

在现有架构下,我主要维护的是一个运行在 AlmaLinux ECS 实例上的后端服务:基于 FastAPI 构建,通过 Docker Compose 进行容器化部署。服务中包含多条 AI 对话类 SSE(Server-Sent Events)长连接接口。

随着用户规模增加,我逐渐发现一个现实问题:Docker Compose 在滚动发布和长连接共存场景下,几乎无法实现真正的零停机更新。容器重建过程中,SSE 连接被强制断开,用户体验受到明显影响。

在与 AI 进行多轮技术探讨后,我重新审视了技术选型。结论是:在当前规模与复杂度下,并不需要直接迁移到 Kubernetes。采用 Docker Swarm 即可满足零停机更新与滚动发布的需求,同时保持架构复杂度可控。

经过半天实践,我成功将服务从 Docker Compose 迁移至 Docker Swarm。以下是关键迁移步骤与问题记录。

一、初始化 Swarm 集群

在 ECS 主机上执行:

docker swarm init

该命令会将当前 Docker Engine 切换为 Swarm 模式,并初始化为单节点集群(Manager)。对于单机部署场景,这已经足够。

二、调整 Compose 文件结构

Swarm 兼容 Compose 文件格式,但需要引入 deploy 段定义编排策略,例如:

  • replicas:副本数量
  • update_config:更新策略(并行数、延迟、顺序等)
  • restart_policy:重启策略

例如可配置:

  • 每次只更新一个副本
  • 新副本就绪后再停止旧副本(start-first 策略)

这一步是实现“零停机滚动更新”的核心。

三、使用 Stack 部署

Swarm 不再使用 docker-compose up,而是通过 Stack 进行编排部署:

docker stack deploy -c docker-compose.yml your_stack_name

Stack 会将服务转换为 Swarm Service,并交由调度器管理。

四、迁移过程中遇到的问题

  1. 本地构建镜像无法拉取

由于镜像是本地构建,未推送至 Docker Hub 或私有仓库,Swarm 默认会尝试从远程仓库解析镜像并拉取,导致部署失败。

解决方式是在部署时添加:

–resolve-image never

该参数指示 Swarm 跳过远程镜像解析,直接使用本地镜像。

  1. Swarm 网络无法直接访问宿主机服务

在 Compose 模式下,容器可以通过 bridge 网络访问宿主机服务(如本地数据库或 Redis)。但在 Swarm overlay 网络中,默认无法直接访问宿主机 127.0.0.1。

解决方案是将服务地址改为:

host.docker.internal

或在 Linux 环境中使用:

host-gateway

并在 compose 文件中通过 extra_hosts 显式声明 host-gateway 映射。这样容器即可访问宿主机网络资源。

五、迁移结果与技术判断

迁移至 Docker Swarm 后:

  • 支持多副本运行
  • 支持滚动更新与回滚
  • SSE 长连接在发布期间不中断
  • 架构复杂度远低于 Kubernetes

在当前业务规模下,Swarm 提供了一个性价比极高的“轻量级编排层”。它弥补了 Docker Compose 在生产环境部署能力上的不足,同时避免了 Kubernetes 带来的学习成本和运维复杂度。

对于单机或小规模集群的 AI 服务而言,这是一个务实且工程上合理的选择。

扫码加入技术交流群🖱️
QR code