Docker Swarm 主机无法解析其他节点上的主机
Docker Swarm host cannot resolve hosts on other nodes
我正在学习这个非常优秀的教程:https://github.com/binblee/springcloud-swarm
当我将堆栈部署到包含单个节点(仅管理器节点)的 Docker 群时,它运行良好。
docker stack deploy -c all-in-one.yml springcloud-demo
我有四个docker容器,其中一个是Eureka服务发现,其他三个容器都注册成功。
问题是当我添加一个worker节点到swarm时,两个容器会部署到worker,另外两个容器到manager,部署到worker节点的服务找不到Eureka server。
java.net.UnknownHostException: eureka: Name does not resolve
这是我的撰写文件:
version: '3'
services:
eureka:
image: demo-eurekaserver
ports:
- "8761:8761"
web:
image: demo-web
environment:
- EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka
zuul:
image: demo-zuul
environment:
- EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka
ports:
- "8762:8762"
bookservice:
image: demo-bookservice
environment:
- EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka
此外,我只能在部署到的主机上访问 Eureka Service Discovery 服务器。
我认为使用 "docker stack deploy" 会自动创建一个覆盖网络,其中所有暴露的端口都将路由到相应服务所在的主机 运行:
来自 https://docs.docker.com/engine/swarm/ingress/ :
All nodes participate in an ingress routing mesh. The routing mesh
enables each node in the swarm to accept connections on published
ports for any service running in the swarm, even if there’s no task
running on the node.
这是 docker 服务 ls:
的输出
manager:~/springcloud-swarm/compose$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
rirdysi0j4vk springcloud-demo_bookservice replicated 1/1 demo-bookservice:latest
936ewzxwg82l springcloud-demo_eureka replicated 1/1 demo-eurekaserver:latest *:8761->8761/tcp
lb1p8nwshnvz springcloud-demo_web replicated 1/1 demo-web:latest
0s52zecjk05q springcloud-demo_zuul replicated 1/1 demo-zuul:latest *:8762->8762/tcp
and of docker stack ps springcloud-demo:
manager:$ docker stack ps springcloud-demo
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE
o8aed04qcysy springcloud-demo_web.1 demo-web:latest workernode Running Running 2 minutes ago
yzwmx3l01b94 springcloud-demo_eureka.1 demo-eurekaserver:latest managernode Running Running 2 minutes ago
rwe9y6uj3c73 springcloud-demo_bookservice.1 demo-bookservice:latest workernode Running Running 2 minutes ago
iy5e237ca29o springcloud-demo_zuul.1 demo-zuul:latest managernode Running Running 2 minutes ago
更新:
我成功添加了另一台主机,但现在无法添加第三台。我尝试了几次,遵循相同的 steps,(安装 docker,打开必要的端口,加入 swarm)——但是节点找不到具有容器主机名的 Eureka 服务器)。
更新 2:
在测试端口是否打开时,我检查了防火墙配置:
workernode:~$ sudo ufw status
Status: active
To Action From
-- ------ ----
8080 ALLOW Anywhere
4789 ALLOW Anywhere
7946 ALLOW Anywhere
2377 ALLOW Anywhere
8762 ALLOW Anywhere
8761 ALLOW Anywhere
22 ALLOW Anywhere
但是 - 当我尝试从管理器节点访问工作节点上的端口 2377 时,我不能:
managernode:~$ telnet xx.xx.xx.xx 2377
Trying xx.xx.xx.xx...
telnet: Unable to connect to remote host: Connection refused
我在亚马逊 AWS 上遇到了同样的问题。
我的问题出在 docker 网络入口。我在我的主机和 VPC 中解决了这个开放端口。
https://docs.docker.com/network/overlay/#customize-the-docker_gwbridge-interface
You need the following ports open to traffic to and from each Docker host participating on an overlay network:
TCP port 2377 for cluster management communications
TCP and UDP port 7946 for communication among nodes
UDP port 4789 for overlay network traffic
您需要为服务创建网络,如下所示:
version: '3'
services:
eureka:
image: demo-eurekaserver
networks:
- main
ports:
- "8761:8761"
web:
image: demo-web
networks:
- main
environment:
- EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka
zuul:
image: demo-zuul
networks:
- main
environment:
- EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka
ports:
- "8762:8762"
bookservice:
image: demo-bookservice
networks:
- main
environment:
- EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka
networks:
main:
driver: overlay
attachable: true
attachable: true
是为了让您可以从另一个撰写文件连接到此网络(如果不是这种情况,您可以将其删除)
我终于找到了答案。 问题是我在添加防火墙例外后没有重新启动主机。
我将撰写文件的版本更新为“3.3”,因为根据文档,"endpoint_mode: dnsrr" 仅适用于 3.3 版。
有了这个改变,我就可以让它工作了。
感谢大家花时间查看我的问题并尝试解决它。
让我们把解决方案分解成几个部分。每个部分都试图让您了解解决方案并且相互关联。
Docker容器网络
每当我们在不指定网络的情况下创建容器时,docker 都会将其附加到默认桥接网络。 According to this,. Service discovery is unavailable in the default network. Hene in order to maker service discovery work properly we are supposed to create a user-defined network as it provides isolation, DNS resolution and many more features. 当我们使用 docker run
命令时,所有这些都适用。
当docker-compose用于运行一个容器并且没有指定网络时,它creates its own bridge network.具有用户定义网络的所有属性。
默认情况下这些桥接网络不可附加,但它们允许本地计算机中的 docker 个容器连接到它们。
Docker群网络
在 Docker swarm and swarm mode routing mesh 中,每当我们在不指定外部网络的情况下向其部署服务时,它都会连接到入口网络。
当您指定外部覆盖网络时,您会注意到创建的覆盖网络将仅对管理器可用,而不在工作节点中可用,除非创建服务并将其复制到它。默认情况下,这些也是不可附加的,并且不允许 swarm 服务之外的其他容器连接到它们。因此,在将容器连接到 swarm 之外的网络之前,您不需要将网络声明为可附加的。
Docker群
由于没有pre defined/official limit on no of worker/manager nodes,您应该可以从第三个节点连接。一种可能性是该节点可能作为工作节点连接,但如果覆盖网络不可附加,您可能会尝试在该节点中部署一个容器,该容器受工作节点限制。
此外,您不能直接在工作节点中部署服务。所有服务都部署在管理器节点中,它负责根据提供的配置和模式复制和扩展服务。
防火墙
如Getting started with swarm mode
所述
- TCP port 2377 for cluster management communications
- TCP and UDP port 7946 for communication among nodes
- UDP port 4789 for overlay network traffic
- ip protocol 50 (ESP) for encrypted overlay network
这些端口应列入节点间通信的白名单。进行更改后,大多数防火墙都需要重新加载。这可以通过将重新加载选项传递给防火墙来完成,它在 Linux 发行版之间有所不同。 ufw
不需要重新加载但是needs commit if rules are added in file.
在防火墙中需要遵循的额外步骤
除了将上述端口列入白名单。您可能需要将 docker0,docker_gw_bridge,br-123456 网络掩码为 16 的 IP 地址列入白名单。否则服务发现将无法在同一台主机上运行。即,如果您尝试连接到 192.168.0.12 中的 eureka
,其中 eureka
服务位于同一 192.168.0.12 它不会解析,因为防火墙会阻止流量。 Refer this (NO ROUTE TO HOST network request from container to host-ip:port published from other container)
Java
有时 Java 工作起来很奇怪,以至于它会抛出 java.net.MalformedURLException
和类似的异常。我也有我的 of such case with 。这里 ping 正确解析,但 Java rmi 抛出错误。因此,您可以在连接到用户定义的网络时定义自己的自定义别名。
Docker 服务发现
默认情况下,您可以使用容器名称解析服务。除此之外,您还可以将服务解析为 <container_name>.<network_name>
。当然,您也可以定义别名。甚至您也可以将其解析为 <alias_name>.<network_name>
.
解决方案
所以你应该在加入集群后创建一个用户定义的覆盖网络,然后部署服务。在服务中,您应该 mention the external network as defined here 同时在防火墙中进行更改。
如果您想允许外部容器连接到网络,您应该使网络可附加。
因为您没有提供足够的关于第三台服务器的详细信息。我假设您正在尝试在那里部署一个容器,该容器被 docker 覆盖网络拒绝,因为该网络不可连接。
我正在学习这个非常优秀的教程:https://github.com/binblee/springcloud-swarm
当我将堆栈部署到包含单个节点(仅管理器节点)的 Docker 群时,它运行良好。
docker stack deploy -c all-in-one.yml springcloud-demo
我有四个docker容器,其中一个是Eureka服务发现,其他三个容器都注册成功。
问题是当我添加一个worker节点到swarm时,两个容器会部署到worker,另外两个容器到manager,部署到worker节点的服务找不到Eureka server。
java.net.UnknownHostException: eureka: Name does not resolve
这是我的撰写文件:
version: '3'
services:
eureka:
image: demo-eurekaserver
ports:
- "8761:8761"
web:
image: demo-web
environment:
- EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka
zuul:
image: demo-zuul
environment:
- EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka
ports:
- "8762:8762"
bookservice:
image: demo-bookservice
environment:
- EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka
此外,我只能在部署到的主机上访问 Eureka Service Discovery 服务器。
我认为使用 "docker stack deploy" 会自动创建一个覆盖网络,其中所有暴露的端口都将路由到相应服务所在的主机 运行:
来自 https://docs.docker.com/engine/swarm/ingress/ :
All nodes participate in an ingress routing mesh. The routing mesh enables each node in the swarm to accept connections on published ports for any service running in the swarm, even if there’s no task running on the node.
这是 docker 服务 ls:
的输出manager:~/springcloud-swarm/compose$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
rirdysi0j4vk springcloud-demo_bookservice replicated 1/1 demo-bookservice:latest
936ewzxwg82l springcloud-demo_eureka replicated 1/1 demo-eurekaserver:latest *:8761->8761/tcp
lb1p8nwshnvz springcloud-demo_web replicated 1/1 demo-web:latest
0s52zecjk05q springcloud-demo_zuul replicated 1/1 demo-zuul:latest *:8762->8762/tcp
and of docker stack ps springcloud-demo:
manager:$ docker stack ps springcloud-demo
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE
o8aed04qcysy springcloud-demo_web.1 demo-web:latest workernode Running Running 2 minutes ago
yzwmx3l01b94 springcloud-demo_eureka.1 demo-eurekaserver:latest managernode Running Running 2 minutes ago
rwe9y6uj3c73 springcloud-demo_bookservice.1 demo-bookservice:latest workernode Running Running 2 minutes ago
iy5e237ca29o springcloud-demo_zuul.1 demo-zuul:latest managernode Running Running 2 minutes ago
更新:
我成功添加了另一台主机,但现在无法添加第三台。我尝试了几次,遵循相同的 steps,(安装 docker,打开必要的端口,加入 swarm)——但是节点找不到具有容器主机名的 Eureka 服务器)。
更新 2:
在测试端口是否打开时,我检查了防火墙配置:
workernode:~$ sudo ufw status
Status: active
To Action From
-- ------ ----
8080 ALLOW Anywhere
4789 ALLOW Anywhere
7946 ALLOW Anywhere
2377 ALLOW Anywhere
8762 ALLOW Anywhere
8761 ALLOW Anywhere
22 ALLOW Anywhere
但是 - 当我尝试从管理器节点访问工作节点上的端口 2377 时,我不能:
managernode:~$ telnet xx.xx.xx.xx 2377
Trying xx.xx.xx.xx...
telnet: Unable to connect to remote host: Connection refused
我在亚马逊 AWS 上遇到了同样的问题。
我的问题出在 docker 网络入口。我在我的主机和 VPC 中解决了这个开放端口。
https://docs.docker.com/network/overlay/#customize-the-docker_gwbridge-interface
You need the following ports open to traffic to and from each Docker host participating on an overlay network:
TCP port 2377 for cluster management communications
TCP and UDP port 7946 for communication among nodes
UDP port 4789 for overlay network traffic
您需要为服务创建网络,如下所示:
version: '3'
services:
eureka:
image: demo-eurekaserver
networks:
- main
ports:
- "8761:8761"
web:
image: demo-web
networks:
- main
environment:
- EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka
zuul:
image: demo-zuul
networks:
- main
environment:
- EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka
ports:
- "8762:8762"
bookservice:
image: demo-bookservice
networks:
- main
environment:
- EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka
networks:
main:
driver: overlay
attachable: true
attachable: true
是为了让您可以从另一个撰写文件连接到此网络(如果不是这种情况,您可以将其删除)
我终于找到了答案。 问题是我在添加防火墙例外后没有重新启动主机。
我将撰写文件的版本更新为“3.3”,因为根据文档,"endpoint_mode: dnsrr" 仅适用于 3.3 版。
有了这个改变,我就可以让它工作了。
感谢大家花时间查看我的问题并尝试解决它。
让我们把解决方案分解成几个部分。每个部分都试图让您了解解决方案并且相互关联。
Docker容器网络
每当我们在不指定网络的情况下创建容器时,docker 都会将其附加到默认桥接网络。 According to this,. Service discovery is unavailable in the default network. Hene in order to maker service discovery work properly we are supposed to create a user-defined network as it provides isolation, DNS resolution and many more features. 当我们使用 docker run
命令时,所有这些都适用。
当docker-compose用于运行一个容器并且没有指定网络时,它creates its own bridge network.具有用户定义网络的所有属性。
默认情况下这些桥接网络不可附加,但它们允许本地计算机中的 docker 个容器连接到它们。
Docker群网络
在 Docker swarm and swarm mode routing mesh 中,每当我们在不指定外部网络的情况下向其部署服务时,它都会连接到入口网络。
当您指定外部覆盖网络时,您会注意到创建的覆盖网络将仅对管理器可用,而不在工作节点中可用,除非创建服务并将其复制到它。默认情况下,这些也是不可附加的,并且不允许 swarm 服务之外的其他容器连接到它们。因此,在将容器连接到 swarm 之外的网络之前,您不需要将网络声明为可附加的。
Docker群
由于没有pre defined/official limit on no of worker/manager nodes,您应该可以从第三个节点连接。一种可能性是该节点可能作为工作节点连接,但如果覆盖网络不可附加,您可能会尝试在该节点中部署一个容器,该容器受工作节点限制。
此外,您不能直接在工作节点中部署服务。所有服务都部署在管理器节点中,它负责根据提供的配置和模式复制和扩展服务。
防火墙
如Getting started with swarm mode
所述
- TCP port 2377 for cluster management communications
- TCP and UDP port 7946 for communication among nodes
- UDP port 4789 for overlay network traffic
- ip protocol 50 (ESP) for encrypted overlay network
这些端口应列入节点间通信的白名单。进行更改后,大多数防火墙都需要重新加载。这可以通过将重新加载选项传递给防火墙来完成,它在 Linux 发行版之间有所不同。 ufw
不需要重新加载但是needs commit if rules are added in file.
在防火墙中需要遵循的额外步骤
除了将上述端口列入白名单。您可能需要将 docker0,docker_gw_bridge,br-123456 网络掩码为 16 的 IP 地址列入白名单。否则服务发现将无法在同一台主机上运行。即,如果您尝试连接到 192.168.0.12 中的 eureka
,其中 eureka
服务位于同一 192.168.0.12 它不会解析,因为防火墙会阻止流量。 Refer this (NO ROUTE TO HOST network request from container to host-ip:port published from other container)
Java
有时 Java 工作起来很奇怪,以至于它会抛出 java.net.MalformedURLException
和类似的异常。我也有我的
Docker 服务发现
默认情况下,您可以使用容器名称解析服务。除此之外,您还可以将服务解析为 <container_name>.<network_name>
。当然,您也可以定义别名。甚至您也可以将其解析为 <alias_name>.<network_name>
.
解决方案
所以你应该在加入集群后创建一个用户定义的覆盖网络,然后部署服务。在服务中,您应该 mention the external network as defined here 同时在防火墙中进行更改。
如果您想允许外部容器连接到网络,您应该使网络可附加。
因为您没有提供足够的关于第三台服务器的详细信息。我假设您正在尝试在那里部署一个容器,该容器被 docker 覆盖网络拒绝,因为该网络不可连接。