Docker Swarm集群内服务无法通过published端口访问其他服务如何解决?
Docker Swarm集群内部服务端口访问问题解答
问题原因
- Docker Swarm 中
ports配置的published端口仅用于集群外部客户端访问,流量走ingress网络路由,与集群内部服务之间的访问逻辑完全无关。 - 集群内部服务通过服务名互访时,会直接请求对应服务容器的网络命名空间端口,不会经过ingress层的端口映射规则,因此容器本身没有监听的端口自然无法连通,这就是访问
smtp:2526提示连接拒绝的根本原因。
无需修改容器监听端口的解决方案
方案1:使用socat sidecar做端口转发(无侵入,推荐)
在同一个服务栈中加入socat转发容器,共享smtp服务的网络命名空间,监听25端口并转发到本地2525端口即可,docker-compose配置参考:
services: smtp: image: <your smtp repository> user: node environment: - NODE_ENV=production privileged: true deploy: replicas: 2 placement: constraints: - node.labels.scheme == task restart_policy: condition: on-failure delay: 5s window: 20s healthcheck: test: netstat -l | grep 2525 interval: 10s timeout: 10s retries: 10 start_period: 20s smtp-port-forward: image: alpine/socat command: TCP-LISTEN:25,fork TCP:127.0.0.1:2525 network_mode: service:smtp deploy: replicas: 2 placement: constraints: - node.labels.scheme == task restart_policy: condition: on-failure
配置完成后集群内其他服务直接访问smtp:25即可正常连通。
方案2:容器内添加iptables转发规则(无需额外容器)
由于你的服务已经开启了privileged: true权限,可以直接修改启动命令,通过iptables规则实现端口重定向,docker-compose配置参考:
smtp: image: <your smtp repository> user: root environment: - NODE_ENV=production privileged: true command: > sh -c " iptables -t nat -A PREROUTING -p tcp --dport 25 -j REDIRECT --to-port 2525 && iptables -t nat -A OUTPUT -p tcp --dport 25 -j REDIRECT --to-port 2525 && su node -c '<你的原smtp服务启动命令>' " deploy: replicas: 2 placement: constraints: - node.labels.scheme == task restart_policy: condition: on-failure delay: 5s window: 20s healthcheck: test: netstat -l | grep 2525 interval: 10s timeout: 10s retries: 10 start_period: 20s
注意需要先切换为root用户执行iptables规则,再切换回node用户启动原有服务,不需要额外部署容器即可实现需求。
内容的提问来源于stack exchange,提问作者Senica Gonzalez
相关产品推荐
相关产品推荐

