Dockerのコンテナ間のネットワーク通信

Dockerのコンテナ間の通信をできないかなと思って調べてみました。今まではコンテナにDBとWebサーバを共存させるようなことをやっていたのですが、 実際には別のサーバになることも多いので、この際調べて変更をしていこうと思います。

今回のテスト環境

今回は以下の環境でテストを行っています。

  • Windows10 Home
  • WSL2環境のDocker
  • コンテナイメージUbuntu : latest

コンテナの生成・実行

実験の対象となるコンテナを以下の様に生成実行しました。

PS C:\> docker run -itd -v /c/sharebin:/sharebin --name myubuntu1 ubuntu
PS C:\> docker run -itd -v /c/sharebin:/sharebin --name myubuntu2 ubuntu

このコンテナの名前はmyubuntu1myubuntu2としていますが管理上の名前であるだけでホスト名をコンテナ内でhostnameコマンドを実行してもこのような名前では通信できません。生成されたコンテナ内では英数字のランダムな値がホスト名となっています。この乱数的なホスト名を使用すれば先程作成したコンテナ間の通信はできそうな気がしますが、これでも通信はできません。

実はDockerで作成したコンテナはネットワークを指定しなければデフォルトネットワークにぶら下がる形で生成されます。このデフォルトネットワークに接続されると相互のネットワーク疎通ができないというものになっています。もちろん、Dockerホストとは通信は行なえます。

ネットワークの作成

コンテナ間の通信を行う場合にはDockerに新規ネットワークを作成し、コンテナをそのネットワークに接続をすることでコンテナ間のIP通信ができるようになります。現在のDockerのネットワーク設定を表示するには以下のコマンドを実行します。

PS > docker network ls

先程デフォルトのネットワークといっていたのは、この表示の中のBridgeというNameになっているネットワークになります。こちらにのみ接続されているコンテナはコンテナ間のIP通信はできません。そこで、新たにmynetworkというネットワークを作成し、そのネットワークを経由して通信を行えるようにします。ネットワークの生成は以下の様に行います。

PS > docker network create mynetwork

生成後にもう一度Dockerのネットワークの状態を確認すると

PS > docker network ls

以下のようにmynetworkというネットワークが生成されました。

このネットワークの詳細を確認するには以下のコマンドを実行します。

PS C:\> docker network inspect mynetwork

すると、ネットワークの詳細が表示されます。ネットワークアドレスやゲートウェイなどが表示されています。また、このJSONエントリの中にContainersというものがありますが、このネットワークに接続されたコンテナがある場合にはここにホストの情報が入力されます。現在は接続されたコンテナが存在しないのでになっています。

コンテナをネットワークに接続

動作中のコンテナをネットワークに追加する場合

動作中のコンテナをネットワークに追加する場合には以下のコマンドをDockerホストから実行することで追加することができます。先程作成したmyubuntu1myubuntu2を接続してみます。

PS C:\> docker network connect mynetwork myubuntu1
PS C:\> docker network connect mynetwork myubuntu2

では、先程のネットワークの詳細を確認してみると…

PS C:\> docker network inspect mynetwork

以下は抜粋になりますが、Containersの値に接続したホスト名が入力されています。

これで新しく作成したネットワークに動作中の2つのホストが接続されました。

コンテナ作成時にネットワークを指定する場合

コンテナ作成時にネットワークを指定して作成することもできます。例えば以下のように行います。 追加しているのは--netオプションになります。こちらを指定することで、接続するネットワークを指定できます。

PS C:\> docker run -itd -v /c/sharebin:/sharebin --net=mynetwork --name myubuntu3 ubuntu

実行したら詳細を確認すると、今回作成したmyubuntu3というコンテナが追加されています。

疎通を確認

これで新規に作成したmynetworkというネットワークにmyubuntu1myubuntu3までの3台のコンテナが接続されています。

実はネットワーク設定を行うと、接続されたコンテナ間の名前解決をしてくれるため、ホスト名もmyubuntu1myubuntu3を使用することができるようになります。

もちろん、IPアドレス経由でも、乱数パターンのホスト名でもアクセスできますが、こちらの方法のほうが圧倒的に簡単かと思います。

おわりに

これでDockerで生成したコンテナを名前解決もしながら、コンテナ間通信を行うことができました。 よくある環境のWebサーバとDBを別コンテナにすることも、これで用意にできるようになったかなと思います。