Docker Swarm部署Compose V3后主机无法访问服务端口8081求助
排查Swarm集群中服务端口无法访问的问题
咱们先理清楚一个关键的点:你看到的docker ps和docker service ls端口显示差异是正常的,不用纠结这个——Swarm模式下,端口映射是通过集群层面的Ingress路由mesh实现的,单个容器只会暴露内部的8080端口,而主机的8081端口流量是由Swarm统一转发到容器的。所以问题肯定出在其他环节,咱们一步步排查:
1. 先检查节点防火墙/安全组配置
Swarm集群和应用端口都需要开放,这是最容易踩的坑:
- 必须开放的Swarm集群端口:
2377/tcp:集群管理通信7946/tcp、7946/udp:节点间发现与通信4789/udp:Overlay网络数据包传输
- 应用端口:
8081/tcp:外部访问用
以Ubuntu的ufw为例,执行这些命令开放端口:
sudo ufw allow 2377/tcp sudo ufw allow 7946/tcp sudo ufw allow 7946/udp sudo ufw allow 4789/udp sudo ufw allow 8081/tcp sudo ufw reload
如果是CentOS/RHEL的firewalld,替换成对应的命令即可。
2. 验证容器内应用的监听地址
如果应用只绑定了127.0.0.1:8080,哪怕Swarm把流量转过来,容器也接收不到——因为Ingress是转发到容器的外部IP,不是localhost。
- 先找到容器ID:
docker ps(找到deckin_node1对应的容器) - 进入容器:
docker exec -it <容器ID> sh - 检查端口监听:
ss -tulpn | grep 8080
如果输出显示监听的是127.0.0.1:8080,赶紧修改应用的启动配置,让它绑定0.0.0.0:8080。
3. 确认服务的运行状态与调度
看看服务是不是真的在正常运行,以及运行在哪个节点:
docker service ps deckin_node1
检查输出里的STATE列,确保所有副本都是Running;再看NODE列,确认容器所在的节点。
- 如果用的是默认的Ingress模式,理论上所有Swarm节点的8081都能访问;如果是
mode: host的端口配置,那只能访问运行容器的节点的8081端口。
4. 检查Compose文件的端口配置
确保你的docker-compose.yml(V3版本)端口配置正确,比如:
version: '3.8' services: deckin_node1: image: your-image:tag ports: - "8081:8080" # 正确格式:主机端口:容器端口 deploy: replicas: 1 # 其他部署配置...
要是你用了mode: host的配置,注意这种模式下服务副本数不能超过节点数(每个节点只能绑定一次8081):
ports: - target: 8080 published: 8081 protocol: tcp mode: host
5. 测试Ingress网络连通性
如果前面的步骤都没问题,试试直接访问容器的内部IP:
- 获取容器IP:
docker inspect <容器ID> | grep "IPAddress" - 测试连通性:
curl http://<容器IP>:8080
如果这个能通,但主机8081访问不通,大概率是Ingress网络出问题了,可以重启docker服务后重新部署:
sudo systemctl restart docker docker stack deploy -c docker-compose.yml <你的栈名称>
内容的提问来源于stack exchange,提问作者hY8vVpf3tyR57Xib




