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を別コンテナにすることも、これで容易にできるようになったかなと思います。