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
このコンテナの名前はmyubuntu1とmyubuntu2としていますが管理上の名前であるだけでホスト名をコンテナ内で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ホストから実行することで追加することができます。先程作成したmyubuntu1とmyubuntu2を接続してみます。
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というネットワークにmyubuntu1~myubuntu3までの3台のコンテナが接続されています。
実はネットワーク設定を行うと、接続されたコンテナ間の名前解決をしてくれるため、ホスト名もmyubuntu1~myubuntu3を使用することができるようになります。

もちろん、IPアドレス経由でも、乱数パターンのホスト名でもアクセスできますが、こちらの方法のほうが圧倒的に簡単かと思います。
おわりに
これでDockerで生成したコンテナを名前解決もしながら、コンテナ間通信を行うことができました。
よくある環境のWebサーバとDBを別コンテナにすることも、これで容易にできるようになったかなと思います。