【Dockerの最新機能を使ってみよう】マルチホストネットワークで複数ホスト間を繋ぐ仮想ネットワークを作る 3ページ
マルチホストネットワークの作成と利用
それでは、マルチホストネットワークを実際に作成して使用してみよう。まず、次のように「-d」オプションでoverlayドライバを指定して「docker network create」コマンドを実行してネットワークを作成する。ここではネットワーク名として「testnet02」を指定した。
# docker network create -d overlay testnet02 a35a95625a09b2b7a680ec59932f323f4d5f7596b970ac3808449244eb03f7c7
「docker network inspect」コマンドでこのネットワークの情報を確認すると、bridgeドライバで作成したネットワークとは異なるネットワークアドレスが割り当てられていることが分かる。
# docker network inspect testnet02 [ { "Name": "testnet02", "Id": "a35a95625a09b2b7a680ec59932f323f4d5f7596b970ac3808449244eb03f7c7", "Scope": "global", "Driver": "overlay", "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "10.0.0.0/24", "Gateway": "10.0.0.1/24" } ] }, "Containers": {}, "Options": {} } ]
作成されたネットワークは、すべてのDockerホスト内で共有される。たとえば「docker create network」コマンドを実行したのとは異なるDockerホストで「docker network ls」コマンドを実行してみると、このホスト上でも先ほど作成した「testnet02」ネットワークが認識されていることが分かる。
# docker network ls NETWORK ID NAME DRIVER a35a95625a09 testnet02 overlay 1a1ecc8ea3f7 bridge bridge ae6eadc28386 none null 7c66cf43a8cc host host
続いて、このネットワークをコンテナに接続してみよう。「docker network connect」コマンドを利用すれば、すでに稼動しているコンテナに別のネットワークを接続することが可能だ。まずは本記事の初めに作成したmysql01コンテナに、testnet02ネットワークを接続してみよう。
# docker network connect testnet02 mysql01
接続後、「docker inspect」コマンドでmysql01コンテナの情報を見てみると、testnet01およびtestnet02の2つのネットワークに対応したIPアドレスが割り当てられていることが分かる。
# docker inspect mysql01 : : "Networks": { "testnet01": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "bd48adb5b4a787cb499640fabff3b2a4bd5c13077b954926443298bf5ad297bc", "EndpointID": "0d0c13fa6d3f266411e07980e8077fcc1bfce303deb9560a96ab13cf1e877283", "Gateway": "172.18.0.1", "IPAddress": "172.18.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:12:00:02" }, "testnet02": { "IPAMConfig": {}, "Links": null, "Aliases": null, "NetworkID": "a35a95625a09b2b7a680ec59932f323f4d5f7596b970ac3808449244eb03f7c7", "EndpointID": "0cc20ccf5c9f6a1128f1c3948c5e3065fbdc8d75b47ba74083c139f4bc278a8c", "Gateway": "", "IPAddress": "10.0.0.2", "IPPrefixLen": 24, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:0a:00:00:02" } : :
これで、testnet02ネットワーク内のコンテナからmysql01コンテナ内で稼動しているMySQLに「mysql01.testnet02」というホスト名を使ってアクセスできるようになる。もちろん、mysql01コンテナを稼動させているDockerホスト以外のDockerホスト上で稼動しているコンテナからもアクセスが可能だ。たとえば、別のDockerホスト上で次のようにWordPressコンテナを立ち上げて、WordPressを稼動させることができる。
# docker run --name wp01 --net=testnet02 -p 80:80 -e WORDPRESS_DB_HOST=mysql01.testnet02 -e WORDPRESS_DB_USER=wordpress -e WORDPRESS_DB_PASSWORD=<MySQLのrootパスワード> -d wordpress
なお、overlayドライバが割り当てたIPアドレス(この例ではtestnet02に接続された「10.0.0.2」というIPアドレス)には、そのコンテナを稼動させているDockerホストからもアクセスできない点に注意したい。
↓bridgeドライバで割り当てられたIPアドレスへのping # ping 172.18.0.1 PING 172.18.0.1 (172.18.0.1) 56(84) bytes of data. 64 bytes from 172.18.0.1: icmp_seq=1 ttl=64 time=0.062 ms 64 bytes from 172.18.0.1: icmp_seq=2 ttl=64 time=0.075 ms ^C --- 172.18.0.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 0.062/0.068/0.075/0.010 ms ↓overlayドライバで割り当てられたIPアドレスへのping # ping 10.0.0.2 PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. ^C --- 10.0.0.2 ping statistics --- 4 packets transmitted, 0 received, 100% packet loss, time 2999ms ↑パケットが到達せず、通信できない
マルチホストネットワークでのリンク機能
「docker run」コマンドでは、コンテナから別のコンテナにアクセスするための別名(エイリアス)を指定する「–link」オプションが用意されていた。Docker 1.9まではこのオプションはbridgeネットワークでしか利用できなかったが、Docker 1.10ではそれ以外のネットワークでも利用が可能になっている。
「–link」オプションでは、「–link=<コンテナ名>:<エイリアス名>」といった形でコンテナ名およびエイリアス名を指定できる。例えば「–link=mysql01:db」のように指定すると、そのコンテナ内からは「db」というホスト名でmysql01コンテナにアクセスが可能になる。
# docker run -it --rm --net=testnet02 --link=mysql01:db busybox / # ping db PING db (10.0.0.2): 56 data bytes 64 bytes from 10.0.0.2: seq=0 ttl=64 time=0.173 ms 64 bytes from 10.0.0.2: seq=1 ttl=64 time=0.114 ms ^C --- db ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.114/0.143/0.173 ms
なお、リンク機能は同じネットワーク上にあるホスト間でのみ利用可能だ。また、「docker network connect」コマンドの「–link」オプションでも同様のリンク設定が可能になっている。
ネットワーク外へのアクセスが禁止された内部ネットワークを作る
Docker 1.10では新たに「内部ネットワーク(internal network)」という機能も導入されている。これは、ネットワーク外との通信が行えないネットワークを作成する機能だ。内部ネットワークは、次のようにネットワークの作成時に「–internal」オプションを指定することで作成できる。
# docker network create --internal -d overlay testnet03 58936e24df57dcb670a64a5ccbb7225f7738c3d68f4ba8cc747782ab35b35c91
このように作成されたネットワークでは、ネットワーク外への通信が行えず、またネットワーク外からネットワーク内への通信も行えない。次の例は、内部ネットワークとして作成された「testnet03」ネットワークからネットワーク外にアクセスしようとした例だ。ここでは「Network is unreachable」と表示され、アクセスが行えなくなっていることが分かる。
# docker run -it --rm --net=testnet03 busybox / # ping osdn.jp PING osdn.jp (202.221.179.11): 56 data bytes ping: sendto: Network is unreachable
もちろん、この場合でも同じ内部ネットワークに接続されたホスト間での通信は可能だ。
コンテナに任意のIPアドレスを割り当てる
従来、Dockerではコンテナに割り当てられるIPアドレスは自動的に決定されていた。しかしDocker 1.10では、コンテナに割り当てるIPアドレスを指定できるよう「docker run」コマンドや「docker network」コマンドに「–ip」および「–ip6」オプションが追加されている。ただし、この機能はネットワークの作成時に明示的にネットワークが使用するIPアドレスを指定しておいたネットワークでのみ利用が可能となっている。
ネットワークの作成時に使用するIPアドレスを指定するには、「–subnet」オプションを使用する。次の例は、10.0.1.0/24というネットワークを指定するものだ。
# docker network create --subnet=10.0.1.0/24 testnet04 4d833c534a46fec58d72d8de5e8536574d6653a0600dce653c474e7d8bb4825d
このようにして作成したネットワークにコンテナを接続する場合、「–ip」オプションでコンテナに割り当てるIPアドレスを指定できる。次の例では、10.0.1.100というIPアドレスを割り当てている。
# docker run -ti --net=testnet04 --rm --ip=10.0.1.100 busybox / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 194: eth0@if195: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:0a:00:01:64 brd ff:ff:ff:ff:ff:ff inet 10.0.1.100/24 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::42:aff:fe00:164/64 scope link valid_lft forever preferred_lft forever
なお、ネットワークに割り当てられたサブネット外のIPアドレスを指定した場合、次のようにエラーが発生しコンテナを起動できない。
# docker run -ti --net=testnet04 --rm --ip=10.0.2.100 busybox docker: Error response from daemon: Invalid preferred address 10.0.2.100: It does not belong to any of this network's subnets.
なお、ここではIPv4アドレスを指定しているが、「–ip6」オプションを利用することでIPv6アドレスを割り当てることも可能だ。また、「docker run」コマンドだけでなく、「docker network connect」コマンドでも同様に「–ip」および「–ip6」オプションでIPアドレスの割り当てが可能だ。
マルチホストネットワークでDockerクラスタの構築がより容易かつ柔軟に
今回紹介したDockerのマルチホストネットワーク機能を利用することで、従来は別の技術を導入する必要があった複数のDockerホスト間の連携が簡単に行えるようになった。また、異なるネットワーク技術を使う場合でも、同じ「docker network」コマンドで仮想ネットワークの管理が行えるというメリットもある。Docker向けのネットワークドライバは仕様が公開されているため、今後サポートされる仮想ネットワークも増えていくと思われる。