在Docker Swarm中部署指定端口与主机名的4个容器副本
问题分析与解决方案
你的配置达不到预期效果,核心问题出在Docker Swarm的replicated模式特性和端口映射的逻辑上:
- 当使用
replicated:4时,Swarm会创建4个完全相同配置的容器副本,每个副本都会尝试绑定主机上的3001-3004所有端口。但主机端口是独占资源,第一个容器启动后会占用全部四个端口,后续3个容器会因端口冲突启动失败。 - 同时,replicated模式下无法为每个副本单独指定不同的
hostname,所有副本会默认使用服务名作为主机名基础,无法实现你需要的slave1至slave4的区分。
要实现每个副本对应独立端口和主机名的需求,最直接的方式是将每个slave定义为独立的服务——因为每个实例需要独特的配置,replicated模式的"批量相同副本"特性并不适配你的场景。
修改后的docker-compose配置
version: '3.8' services: slave1: image: "DOCKER_REPO_NAME" deploy: restart_policy: condition: on-failure networks: - my_net ports: - "3001:3001" hostname: slave1 slave2: image: "DOCKER_REPO_NAME" deploy: restart_policy: condition: on-failure networks: - my_net ports: - "3002:3002" hostname: slave2 slave3: image: "DOCKER_REPO_NAME" deploy: restart_policy: condition: on-failure networks: - my_net ports: - "3003:3003" hostname: slave3 slave4: image: "DOCKER_REPO_NAME" deploy: restart_policy: condition: on-failure networks: - my_net ports: - "3004:3004" hostname: slave4 networks: my_net: external: true
配置说明
- 每个
slaveX都是独立服务,各自配置专属的端口映射(主机端口:容器端口)和hostname,确保实例唯一性。 - 所有服务共享同一镜像,符合你的初始需求。
- 保留了原配置中的
restart_policy和外部网络设置,保持功能一致性。
部署命令
使用Swarm模式部署该配置:
docker stack deploy -c docker-compose.yml my_stack_name
部署完成后,你可以通过docker stack services my_stack_name查看所有服务状态,每个服务会对应一个运行中的容器,分别监听主机的3001-3004端口,主机名也会准确设置为slave1至slave4。
内容的提问来源于stack exchange,提问作者dventi3




