web-dev-qa-db-ja.com

Docker SwarmHostは他のノードのホストを解決できません

私はこの非常に優れたチュートリアルに従っています: https://github.com/binblee/springcloud-swarm

単一のノード(マネージャーノードのみ)を含むDockerスウォームにスタックをデプロイすると、完全に機能します。

docker stack deploy -c all-in-one.yml springcloud-demo

私は4つのDockerコンテナーを持っていますが、そのうちの1つはEurekaサービスディスカバリーであり、他の3つのコンテナーすべてが正常に登録されます。

問題は、ワーカーノードをスウォームに追加すると、2つのコンテナーがワーカーにデプロイされ、2つがマネージャーにデプロイされ、ワー​​カーノードにデプロイされたサービスが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 ServiceDiscoveryサーバーにのみアクセスできます。

「dockerstackdeploy」を使用すると、オーバーレイネットワークが自動的に作成され、公開されているすべてのポートが、それぞれのサービスが実行されているホストにルーティングされると思いました。

から https://docs.docker.com/engine/swarm/ingress/

すべてのノードは、入力ルーティングメッシュに参加します。ルーティングメッシュを使用すると、ノードで実行されているタスクがない場合でも、スウォーム内の各ノードが、スウォームで実行されているすべてのサービスの公開ポートでの接続を受け入れることができます。

これはdocker service 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 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

更新:

別のホストを正常に追加しましたが、3番目のホストを追加できません。同じ手順(dockerのインストール、必要なポートのオープン、群れへの参加)に従って、数回試しましたが、ノードはコンテナーHost nameの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
5
simbro

ソリューションをいくつかの部分に分けてみましょう。各部分は、ソリューションについてのアイデアを提供しようとし、相互に接続されています。

Dockerコンテナネットワーク

ネットワークを指定せずにコンテナを作成すると、dockerはそれをデフォルトのブリッジネットワークに接続します。 これによれば、 。デフォルトネットワークでは、サービス検出は利用できません。サービスディスカバリを適切に機能させるために、分離、DNS解決、および その他の多くの機能。 を提供するユーザー定義ネットワークを作成することになっています。これらはすべて、docker runコマンドを使用するときに適用できます。

Docker-composeを使用してコンテナーを実行し、ネットワークが指定されていない場合、docker-composeは 独自のブリッジネットワークを作成します。 ユーザー定義ネットワークのすべてのプロパティを持ちます。

これらのブリッジネットワークはデフォルトでは接続できませんが、ローカルマシンのDockerコンテナがそれらに接続できるようにします。

Dockerスウォームネットワーク

Docker swarm および swarm mode routing mesh では、外部ネットワークを指定せずにサービスをデプロイすると、入力ネットワークに接続します。

外部オーバーレイネットワークを指定すると、作成されたオーバーレイネットワークは、サービスが作成されて複製されない限り、マネージャーのみが使用でき、ワーカーノードでは使用できないことがわかります。これらもデフォルトでは接続できず、スウォームサービス外の他のコンテナがそれらに接続することを許可しません。したがって、スウォームの外部でコンテナをネットワークに接続するまで、ネットワークを接続可能として宣言する必要はありません。

DockerSwarm

ワーカー/マネージャーノードの数に事前定義/公式制限 がないため、3番目のノードから接続できるはずです。 1つの可能性は、ノードがワーカーノードとして接続されている可能性がありますが、オーバーレイネットワークが接続できない場合は、ワーカーノードによって制限されているコンテナーをそのノードにデプロイしようとする可能性があります。

さらに、ワーカーノードにサービスを直接デプロイすることはできません。すべてのサービスはマネージャーノードにデプロイされ、提供された構成とモードに基づいてサービスの複製とスケーリングを処理します。

ファイアウォール

スウォームモード入門 で述べたように

  • クラスタ管理通信用のTCPポート2377
  • ノード間の通信用のTCPおよびUDPポート7946
  • オーバーレイネットワークトラフィック用のUDPポート4789
  • 暗号化されたオーバーレイネットワーク用のIPプロトコル50(ESP)

これらのポートは、ノード間の通信用にホワイトリストに登録する必要があります。変更を加えたら、ほとんどのファイアウォールを再ロードする必要があります。これは、ファイアウォールにリロードオプションを渡すことで実行でき、Linuxディストリビューションによって異なります。 ufwをリロードする必要はありませんが、 ファイルにルールが追加されている場合はコミットする必要があります

ファイアウォールで従うべき追加の手順

上記のポートをホワイトリストに登録することは別として。ネットマスクが16のdocker0、docker_gw_bridge、br-123456 IPアドレスをホワイトリストに登録する必要がある場合があります。それ以外の場合、サービス検出は同じホストマシンでは機能しません。つまり、192.168.0.12eurekaに接続しようとしている場合、eurekaサービスは同じ192.168.0.12ファイアウォールがトラフィックをブロックするため、解決されません。 これを参照してください(コンテナからホストへのルートをホストしない-ip:portは他のコンテナから公開されています)

Java

Javaは、Java.net.MalformedURLExceptionや同様の例外をスローするなど、奇妙に動作することがあります。そのような場合の 自身の経験ソリューション で経験しています。 pingは正しく解決されましたが、Java rmiがエラーをスローしていました。したがって、ユーザー定義ネットワークに接続するときに、独自のカスタムエイリアスを定義できます。

Dockerサービスディスカバリ

デフォルトでは、コンテナ名を使用してサービスに解決できます。それとは別に、サービスを<container_name>.<network_name>として解決することもできます。もちろん、エイリアスを定義することもできます。そして、あなたもそれを<alias_name>.<network_name>として解決することができます。

解決

したがって、群れに参加した後にユーザー定義のオーバーレイネットワークを作成してから、サービスをデプロイする必要があります。サービスでは、ファイアウォールに変更を加えるとともに、 ここで定義されている外部ネットワークについて言及する する必要があります。

外部コンテナがネットワークに接続できるようにする場合は、ネットワークを接続可能にする必要があります。

3番目のサーバーで何が起こっているかについて十分な詳細を提供していないため。ネットワークが接続できないため、Dockerオーバーレイネットワークによって拒否されたコンテナをそこにデプロイしようとしていると思います。

3
Mani

私はついに答えを見つけました。 問題は、ファイアウォールの例外を追加した後、ホストマシンを再起動していなかったことです。

ドキュメントによると、「endpoint_mode:dnsrr」はバージョン3.3からしか利用できないため、作成ファイルのバージョンを「3.3」に更新しました。

この変更により、私はそれを機能させることができました。

問題を解決するために時間を割いてくれたすべての人に感謝します。

2
simbro

次のようなサービスのネットワークを作成する必要があります。

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は、別の作成ファイルからこのネットワークに接続できるようにするためのものです(そうでない場合は削除できます)。

2
Patricio Napoli

amazonAWSでも同じ問題があります。

私の問題は、Dockerネットワークの入力にあります。ホストとVPCでこの開いているポートを解決しました。

https://docs.docker.com/network/overlay/#customize-the-docker_gwbridge-interface

オーバーレイネットワークに参加している各Dockerホストとの間のトラフィックに対して次のポートを開く必要があります。

クラスタ管理通信用のTCPポート2377

ノード間の通信用のTCPおよびUDPポート7946

オーバーレイネットワークトラフィック用のUDPポート4789

0
Tainha