Docker Swarm用Replicas扩展Rust Web服务,规避内置负载均衡
问题背景与需求
我用Rust开发Web服务器,在Docker Compose中手动定义两个服务时运行正常,配置如下:
x-common_auth_service: &common_auth_service container_name: auth build: context: ./auth dockerfile: Dockerfile network_mode: host restart: always deploy: resources: limits: memory: 40M reservations: memory: 20M depends_on: - redis services: auth: <<: *common_auth_service container_name: auth environment: APP_PORT: 3002 # 指定端口 auth2: <<: *common_auth_service container_name: auth2 environment: APP_PORT: 3003 # 指定端口
但切换到Docker Swarm部署并使用Replicas时遇到问题,当前配置如下:
compose.yml
auth_service: image: service/auth_app_rust build: context: ./auth dockerfile: Dockerfile networks: - network_overlay # 之前用的host网络,这就是问题所在 ports: - "5000-5001:3002" deploy: mode: replicated replicas: 2 nginx: image: nginx:latest volumes: - ./nginx/auth.conf:/etc/nginx/nginx.conf networks: - host depends_on: - auth_service
nginx.conf
upstream auth_server { server 127.0.0.1:5000; server 127.0.0.1:5001; keepalive 200; } server { listen 9999; location / { proxy_buffering off; proxy_set_header Connection ""; proxy_http_version 1.1; proxy_set_header Keep-Alive ""; proxy_set_header Proxy-Connection "keep-alive"; proxy_pass http://auth_server; } }
原本手动定义服务时,每个副本用不同端口,于是尝试用端口范围映射,但发现Docker Swarm不会给每个容器分配固定端口,反而会在副本间做内置负载均衡——比如执行curl http://localhost:5000时,不一定访问到容器1。
需求:
- 继续使用Replicas扩展服务,不逐个定义服务
- 不使用Docker Swarm内置负载均衡(已有Nginx实现,内置负载适配效果不佳)
- 实现Rust Web服务器容器的批量扩展
Host网络场景解决方案
核心思路:通过{{.Task.Slot}}占位符为每个任务副本分配唯一端口,避免冲突;同时修改update_config配置,确保容器更新时不会出现端口占用冲突。
关键配置片段:
update_config: parallelism: 1 order: stop-first
完整的compose.yml配置(Host网络模式,提升性能):
auth_service: image: service/auth_app_rust hostname: auth-service-{{.Task.Slot}} build: context: ./auth dockerfile: Dockerfile networks: # 端口使用300*段 - host environment: REDIS_HOST: localhost APP_PORT: "300{{.Task.Slot}}" # 基于任务槽位ID指定服务端口 METRIC_PORT: "301{{.Task.Slot}}" deploy: mode: replicated replicas: 2 update_config: parallelism: 1 # 每次仅更新1个副本 order: stop-first # 先停止旧副本再启动新副本,避免端口冲突 failure_action: rollback delay: 5s resources: limits: memory: 40M reservations: memory: 20M depends_on: - redis - rust_service_builder healthcheck: test: wget --no-verbose --tries=1 --spider http://127.0.0.1:3002/health retries: 5 interval: 3s timeout: 5s networks: host: name: host external: true
内容的提问来源于stack exchange,提问作者rick
相关产品推荐
相关产品推荐

