私はこの非常に優れたチュートリアルに従っています: 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
ソリューションをいくつかの部分に分けてみましょう。各部分は、ソリューションについてのアイデアを提供しようとし、相互に接続されています。
ネットワークを指定せずにコンテナを作成すると、dockerはそれをデフォルトのブリッジネットワークに接続します。 これによれば、 。デフォルトネットワークでは、サービス検出は利用できません。サービスディスカバリを適切に機能させるために、分離、DNS解決、および その他の多くの機能。 を提供するユーザー定義ネットワークを作成することになっています。これらはすべて、docker run
コマンドを使用するときに適用できます。
Docker-composeを使用してコンテナーを実行し、ネットワークが指定されていない場合、docker-composeは 独自のブリッジネットワークを作成します。 ユーザー定義ネットワークのすべてのプロパティを持ちます。
これらのブリッジネットワークはデフォルトでは接続できませんが、ローカルマシンのDockerコンテナがそれらに接続できるようにします。
Docker swarm および swarm mode routing mesh では、外部ネットワークを指定せずにサービスをデプロイすると、入力ネットワークに接続します。
外部オーバーレイネットワークを指定すると、作成されたオーバーレイネットワークは、サービスが作成されて複製されない限り、マネージャーのみが使用でき、ワーカーノードでは使用できないことがわかります。これらもデフォルトでは接続できず、スウォームサービス外の他のコンテナがそれらに接続することを許可しません。したがって、スウォームの外部でコンテナをネットワークに接続するまで、ネットワークを接続可能として宣言する必要はありません。
ワーカー/マネージャーノードの数に事前定義/公式制限 がないため、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.12のeureka
に接続しようとしている場合、eureka
サービスは同じ192.168.0.12ファイアウォールがトラフィックをブロックするため、解決されません。 これを参照してください(コンテナからホストへのルートをホストしない-ip:portは他のコンテナから公開されています)
Javaは、Java.net.MalformedURLException
や同様の例外をスローするなど、奇妙に動作することがあります。そのような場合の 自身の経験 も ソリューション で経験しています。 pingは正しく解決されましたが、Java rmiがエラーをスローしていました。したがって、ユーザー定義ネットワークに接続するときに、独自のカスタムエイリアスを定義できます。
デフォルトでは、コンテナ名を使用してサービスに解決できます。それとは別に、サービスを<container_name>.<network_name>
として解決することもできます。もちろん、エイリアスを定義することもできます。そして、あなたもそれを<alias_name>.<network_name>
として解決することができます。
したがって、群れに参加した後にユーザー定義のオーバーレイネットワークを作成してから、サービスをデプロイする必要があります。サービスでは、ファイアウォールに変更を加えるとともに、 ここで定義されている外部ネットワークについて言及する する必要があります。
外部コンテナがネットワークに接続できるようにする場合は、ネットワークを接続可能にする必要があります。
3番目のサーバーで何が起こっているかについて十分な詳細を提供していないため。ネットワークが接続できないため、Dockerオーバーレイネットワークによって拒否されたコンテナをそこにデプロイしようとしていると思います。
私はついに答えを見つけました。 問題は、ファイアウォールの例外を追加した後、ホストマシンを再起動していなかったことです。
ドキュメントによると、「endpoint_mode:dnsrr」はバージョン3.3からしか利用できないため、作成ファイルのバージョンを「3.3」に更新しました。
この変更により、私はそれを機能させることができました。
問題を解決するために時間を割いてくれたすべての人に感謝します。
次のようなサービスのネットワークを作成する必要があります。
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
は、別の作成ファイルからこのネットワークに接続できるようにするためのものです(そうでない場合は削除できます)。
amazonAWSでも同じ問題があります。
私の問題は、Dockerネットワークの入力にあります。ホストとVPCでこの開いているポートを解決しました。
https://docs.docker.com/network/overlay/#customize-the-docker_gwbridge-interface
オーバーレイネットワークに参加している各Dockerホストとの間のトラフィックに対して次のポートを開く必要があります。
クラスタ管理通信用のTCPポート2377
ノード間の通信用のTCPおよびUDPポート7946
オーバーレイネットワークトラフィック用のUDPポート4789