docker-composeで作ったコンテナ同士をネットワークでつなげる
ファイルはここに。
図のようにdockerコンテナを2つ(図中のmy_clientとmy_server)つくって、それらコンテナ間で通信したい。
単一のdocker-compose.yml
の中に2つ以上のコンテナが定義されてる場合は別に問題ない。同一ymlファイル内部でコンテナの名前がホスト名として使えるので、それを指定して通信できる。単一のymlファイルに定義されたDockerコンテナはすべて同一ネットワーク(Bridge)に所属できるのでコンテナ間通信ができるわけ。
問題はこれら2つのdockerコンテナが別々のdocker-compose.ymlファイルで定義されてるとき。この場合は、自分で独自のネットワーク(図中のmy_network)を構築した上で、接続したいコンテナをその独自ネットワーク(my_network)に所属させる必要があります。それで、コンテナ同士が接続がコンテナ名をホスト名として相互に通信できます。
(ちなみにBridgeとは、コンテナ内部のみで通信できるNATみたいなものが生成されて、そのNATネットワーク内部でコンテナが動く。BridgeなのにNATとはこれ如何に?)
ネットワークはdocker-compose upする前に自分で生成しときましょう。以下のように:
#!/bin/sh # make a network docker network create --driver bridge my_network cd ./client && docker-compose -f docker-compose.yml up -d cd - cd ./server && docker-compose -f docker-compose.yml up -d
こんな感じで。docker-compose.yml
ファイルは以下の2つ。
version: '3.8' services: my_client: build: context: ./ dockerfile: Dockerfile networks: - my_network networks: my_network: external: true
version: '3.8' services: my_server: build: context: ./ dockerfile: Dockerfile networks: - my_network networks: my_network: external: true
これでmy_client
コンテナに入って通信してみましょう。
kazushi@dev2:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 62af57565a5a server_my_server "/bin/sh -c 'while :…" 35 minutes ago Up 35 minutes server-my_server-1 7adf566c7103 client_my_client "/bin/sh -c 'while :…" 35 minutes ago Up 35 minutes client-my_client-1 kazushi@dev2:~$ docker exec -it 7adf566c7103 /bin/bash root@7adf566c7103:/client# root@7adf566c7103:/client# ping my_server PING my_server (172.25.0.3) 56(84) bytes of data. 64 bytes from server-my_server-1.my_network (172.25.0.3): icmp_seq=1 ttl=64 time=0.043 ms 64 bytes from server-my_server-1.my_network (172.25.0.3): icmp_seq=2 ttl=64 time=0.048 ms 64 bytes from server-my_server-1.my_network (172.25.0.3): icmp_seq=3 ttl=64 time=0.047 ms 64 bytes from server-my_server-1.my_network (172.25.0.3): icmp_seq=4 ttl=64 time=0.047 ms 64 bytes from server-my_server-1.my_network (172.25.0.3): icmp_seq=5 ttl=64 time=0.048 ms 64 bytes from server-my_server-1.my_network (172.25.0.3): icmp_seq=6 ttl=64 time=0.037 ms 64 bytes from server-my_server-1.my_network (172.25.0.3): icmp_seq=7 ttl=64 time=0.047 ms 64 bytes from server-my_server-1.my_network (172.25.0.3): icmp_seq=8 ttl=64 time=0.047 ms --- my_server ping statistics --- 8 packets transmitted, 8 received, 0% packet loss, time 7162ms rtt min/avg/max/mdev = 0.037/0.045/0.048/0.003 ms root@7adf566c7103:/client#
通信できてますねping my_server
で通信できます。
external: true
の意味
ちなみのymlファイル内に記述されてるexternal: true
の意味ですが、docker-composeですでに作成済みのnetworkを再利用するときはtrueを指定します。するとdocker-compose -f docker-compose.yml up
のときに通常生成される独自ネットワーク(Bridge)が生成されず、あり物のmy_network
を探して使用するようになります。逆言うと、my_network
が作られてない場合はエラーが出てコンテナが起動しません。上述したように事前にdocker network create --driver bridge my_network
で作っておきましょう。