Docker Swarm集群中绑定容器至eth0实现双网络访问的问题
先帮你揪出配置里的一个小问题——你的WordPress服务的depends_on里写了- wordpress,这会导致循环依赖,肯定要删掉,不然服务启动大概率会出问题。
接下来分析你遇到的核心问题:你想用host模式绑定8888端口到WordPress容器,但host模式的端口是直接绑定到容器所在节点(也就是vm2,192.168.99.101)的eth0上的。而你在VirtualBox里设置的NAT端口转发如果是把主机8888映射到vm1(管理器节点)的8888,那vm1上根本没有WordPress容器绑定的8888端口,自然访问不通。
下面给你两种可行的解决方案,你可以根据需求选择:
方案一:利用Swarm Ingress路由网格(推荐)
Ingress路由网格的好处是,不管容器跑在哪个节点,集群所有节点的指定端口都会自动转发到容器。这样你不需要关心容器在vm1还是vm2,只需要把VirtualBox的端口转发指向集群任意一个节点的端口即可。
修改WordPress服务的端口配置,去掉host模式的端口,换成两个Ingress模式的端口(如果需要区分集群内和本地访问的话):
services: wordpress: image: wordpress depends_on: - mysql # 删掉了之前的循环依赖项 deploy: placement: constraints: [node.labels.application==true] mode: replicated replicas: 1 update_config: parallelism: 1 delay: 10s restart_policy: condition: on-failure ports: - "80:80" # Ingress模式,集群内任意节点IP:80均可访问 - "8888:80" # 同样Ingress模式,集群内任意节点IP:8888也能访问 environment: WORDPRESS_DB_PASSWORD: "12345" networks: - wordpress_net
然后调整VirtualBox的NAT端口转发规则:
- 找到你用来做端口转发的虚拟机(vm1或者vm2都行),添加规则:
- 主机端口:8888
- 虚拟机端口:8888
- 协议:TCP
这样你在本地访问localhost:8888时,请求会通过VirtualBox转发到该虚拟机的8888端口,再通过Swarm的Ingress路由转发到vm2上的WordPress容器,同时集群内通过192.168.99.100:80或192.168.99.101:80也能正常访问。
方案二:保留Host模式端口,调整VirtualBox转发目标
如果你一定要用host模式绑定端口,那需要把VirtualBox的NAT端口转发目标指向容器所在的节点(也就是vm2,192.168.99.101):
- 保持你修改后的WordPress端口配置(注意删掉循环依赖):
services: wordpress: image: wordpress depends_on: - mysql deploy: placement: constraints: [node.labels.application==true] mode: replicated replicas: 1 update_config: parallelism: 1 delay: 10s restart_policy: condition: on-failure ports: - target: 80 published: 80 protocol: tcp mode: ingress - target: 80 published: 8888 protocol: tcp mode: host environment: WORDPRESS_DB_PASSWORD: "12345" networks: - wordpress_net
- 修改VirtualBox的NAT端口转发规则:
- 选择vm2这个虚拟机,添加端口转发规则:
- 主机端口:8888
- 虚拟机端口:8888
- 协议:TCP
- 选择vm2这个虚拟机,添加端口转发规则:
这样本地localhost:8888的请求会转发到vm2的8888端口,而vm2上的WordPress容器已经通过host模式绑定了这个端口,就能正常访问了。同时集群内通过192.168.99.100:80或192.168.99.101:80依然可以访问(Ingress模式的作用)。
验证步骤
不管选哪个方案,修改完compose后,都需要更新Swarm服务:
docker stack deploy -c docker-compose.yml wordpress_stack
然后等待服务更新完成后,先测试集群内访问:curl 192.168.99.100:80和curl 192.168.99.101:80,确认正常。再测试本地访问:打开浏览器访问localhost:8888,看是否能加载WordPress页面。
内容的提问来源于stack exchange,提问作者DaWe4444

