我下面这个非常优秀的教程:https://github.com/binblee/springcloud-swarm
当我将一个堆栈部署到包含单个节点(只有管理器节点)的Docker群时,它可以完美地工作。
docker stack deploy -c all-in-one.yml springcloud-demo
我有四个Docker容器,其中一个是Eureka服务发现,其他三个容器都成功注册了。
问题是,当我向群添加一个工作节点时,两个容器将部署到工作节点,两个部署到管理器,部署到工作节点的服务找不到Eureka服务器。
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/开始:
所有节点都参与到一个入口路由网格中,该路由网格使群中的每个节点都能够接受群中运行的任何服务在发布端口上的连接,即使该节点上没有任务运行。
这是 * 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
以及 * Docker Stack PSSpring云演示 *:
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
- 更新日期:**
我成功地添加了另一台主机,但现在无法添加第三台。我尝试了几次,遵循相同的步骤,(安装Docker,打开必要的端口,加入群集)-但节点无法找到具有容器主机名的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
4条答案
按热度按时间3zwtqj6y1#
让我们把解决方案分成几个部分,每个部分都试图给你一个关于解决方案的想法,并且是相互联系的。
码头集装箱网络
每当我们创建一个没有指定网络的容器时,Docker会将其连接到默认网桥网络。根据这一点,服务发现在默认网络中不可用。因此,为了使服务发现正常工作,我们应该创建一个用户定义的网络,因为它提供了隔离,DNS解析和许多其他功能。所有这些都适用于当我们使用
docker run
命令时。当使用docker-compose来运行一个container并且没有指定network时,它是creates its own bridge network.,它具有用户定义的网络的所有属性。
默认情况下,这些网桥网络是不可连接的,但它们允许本地机器中的Docker容器连接到它们。
码头群网络
在Docker swarm和swarm mode routing mesh中,只要我们在不指定外部网络的情况下向其部署服务,它就会连接到
ingress
网络。当你指定一个外部覆盖网络时,你可以注意到创建的覆盖网络将只对管理器可用,而不是在工作者节点中,除非一个服务被创建并复制到它。这些也是默认不可连接的,不允许群服务之外的其他容器连接到它们。所以你不需要声明一个网络是可连接的,直到你在群服务之外将一个容器连接到它。
码头群
由于没有pre defined/official limit on number of worker/manager nodes,您应该能够从第三个节点连接。一种可能性是,该节点可能作为工作节点连接,但如果覆盖网络不可连接,您可能会尝试在该节点中部署受工作节点限制的容器。
此外,您不能直接在工作节点中部署服务,所有服务都部署在管理节点中,管理节点负责根据提供的配置和模式复制和扩展服务。
防火墙
如群模式入门中所述
这些端口应该被列入白名单,以便节点之间进行通信。大多数防火墙在您进行更改后需要重新加载。这可以通过向防火墙传递reload选项来完成,它在Linux发行版之间有所不同。
ufw
不需要重新加载,但needs commit if rules are added in file需要。防火墙中需要遵循的额外步骤
除了将上述端口列入白名单之外,您可能还需要将docker0、docker_gw_bridge、br-123456 IP地址,网络掩码为16。否则,服务发现将无法在同一台主机上运行。例如,如果您尝试连接到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
和类似的异常。我的own experience也有这样的情况。这里ping解析正确,但Java rmi抛出一个错误。所以,当你连接到用户定义的网络时,你可以定义自己的自定义别名。Docker服务发现
默认情况下,可以使用容器名解析为服务,除此之外,还可以将服务解析为
<container_name>.<network_name>
,当然也可以定义别名,甚至可以将其解析为<alias_name>.<network_name>
。溶液
因此,您应该在加入群集后创建一个用户定义的覆盖网络,然后部署服务。在服务中,您应该提到这里定义的外部网络以及防火墙的更改。
如果要允许外部容器连接到网络,则应使网络可附加。
由于你还没有提供足够的细节上发生了什么事与第三服务器。我假设你是试图部署一个容器有被码头覆盖网络拒绝,因为网络是不可连接的。
xxslljrj2#
您需要为服务创建一个网络,如下所示:
attachable: true
是这样的,你可以从另一个合成文件连接到这个网络(如果不是这样,你可以删除它)lnlaulya3#
我终于找到了答案,问题是我在添加防火墙例外后没有重新启动主机。
我将合成文件的版本更新为“3.3”,因为根据文档,“endpoint_mode:dnsrr”仅在版本3.3中可用。
有了这个改变,我就能让它工作了。
感谢大家花时间来看我的问题,试图解决它。
kg7wmglp4#
我在亚马逊AWS中也有同样的问题。
我的问题是在docker网络入口。我解决了这个开放端口在我的主机和vpc。
https://docs.docker.com/network/overlay/#customize-the-docker_gwbridge-interface
您需要打开以下端口,以允许往来于参与覆盖网络的每个Docker主机的流量:
用于群集管理通信的TCP端口2377
TCP和UDP端口7946用于节点间通信
UDP端口4789用于覆盖网络流量