Docker Swarm主机无法解析其他节点上的主机

cuxqih21  于 2023-02-15  发布在  Docker
关注(0)|答案(4)|浏览(297)

我下面这个非常优秀的教程: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
3zwtqj6y

3zwtqj6y1#

让我们把解决方案分成几个部分,每个部分都试图给你一个关于解决方案的想法,并且是相互联系的。

码头集装箱网络

每当我们创建一个没有指定网络的容器时,Docker会将其连接到默认网桥网络。根据这一点,服务发现在默认网络中不可用。因此,为了使服务发现正常工作,我们应该创建一个用户定义的网络,因为它提供了隔离,DNS解析和许多其他功能。所有这些都适用于当我们使用docker run命令时。
当使用docker-compose来运行一个container并且没有指定network时,它是creates its own bridge network.,它具有用户定义的网络的所有属性。
默认情况下,这些网桥网络是不可连接的,但它们允许本地机器中的Docker容器连接到它们。

码头群网络

Docker swarmswarm mode routing mesh中,只要我们在不指定外部网络的情况下向其部署服务,它就会连接到ingress网络。
当你指定一个外部覆盖网络时,你可以注意到创建的覆盖网络将只对管理器可用,而不是在工作者节点中,除非一个服务被创建并复制到它。这些也是默认不可连接的,不允许群服务之外的其他容器连接到它们。所以你不需要声明一个网络是可连接的,直到你在群服务之外将一个容器连接到它。

码头群

由于没有pre defined/official limit on number of worker/manager nodes,您应该能够从第三个节点连接。一种可能性是,该节点可能作为工作节点连接,但如果覆盖网络不可连接,您可能会尝试在该节点中部署受工作节点限制的容器。
此外,您不能直接在工作节点中部署服务,所有服务都部署在管理节点中,管理节点负责根据提供的配置和模式复制和扩展服务。

防火墙

如群模式入门中所述

  • 用于群集管理通信的TCP端口2377
  • TCP和UDP端口7946用于节点间通信
  • UDP端口4789用于覆盖网络流量
  • 用于加密覆盖网络IP协议50(ESP)

这些端口应该被列入白名单,以便节点之间进行通信。大多数防火墙在您进行更改后需要重新加载。这可以通过向防火墙传递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>

溶液

因此,您应该在加入群集后创建一个用户定义的覆盖网络,然后部署服务。在服务中,您应该提到这里定义的外部网络以及防火墙的更改。
如果要允许外部容器连接到网络,则应使网络可附加。
由于你还没有提供足够的细节上发生了什么事与第三服务器。我假设你是试图部署一个容器有被码头覆盖网络拒绝,因为网络是不可连接的。

xxslljrj

xxslljrj2#

您需要为服务创建一个网络,如下所示:

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是这样的,你可以从另一个合成文件连接到这个网络(如果不是这样,你可以删除它)

lnlaulya

lnlaulya3#

我终于找到了答案,问题是我在添加防火墙例外后没有重新启动主机。
我将合成文件的版本更新为“3.3”,因为根据文档,“endpoint_mode:dnsrr”仅在版本3.3中可用。
有了这个改变,我就能让它工作了。
感谢大家花时间来看我的问题,试图解决它。

kg7wmglp

kg7wmglp4#

我在亚马逊AWS中也有同样的问题。
我的问题是在docker网络入口。我解决了这个开放端口在我的主机和vpc。
https://docs.docker.com/network/overlay/#customize-the-docker_gwbridge-interface
您需要打开以下端口,以允许往来于参与覆盖网络的每个Docker主机的流量:
用于群集管理通信的TCP端口2377
TCP和UDP端口7946用于节点间通信
UDP端口4789用于覆盖网络流量

相关问题