【Dockerの最新機能を使ってみよう】マルチホストネットワークで複数ホスト間を繋ぐ仮想ネットワークを作る
新たなサーバー環境構築ツールとして普及が始まっているDockerは、その開発も積極的に行われている。そこで本連載記事では、4回に渡って最近Dockerに実装された新機能について紹介していく。まず第1回となる今回は、Dockerのネットワーク周りの新機能について紹介する。
進化しているDockerのネットワーク機能
DockerはLinuxカーネルが持つ名前空間(namespace)機構を使い、プロセスやリソースを隔離するツールとして開発が始められた。そのような背景もあってか、開発当初はネットワーク関連機能としては仮想ブリッジとiptablesを使ったパケットルーティング程度の機能しか備えられていなかった。そのため、Dockerを使ってコンテナを動かすマシン(Dockerホスト)を複数台用意して動かすような環境の場合、別途仮想ネットワーク構築ツールを用意する必要があった。
この状況が変わり始めたのが、2015年6月16日にリリースされたバージョン1.7からである。バージョン1.7ではネットワークスタックがリライトされて「libnetwork」という別モジュールに分離されると同時に、異なるDockerホストをまたぐ仮想ネットワークの構築機能の実験的実装がDockerに追加された。2015年11月3日にリリースされたバージョン1.9ではこの仮想ネットワーク機能が正式な機能となり、ついにDocker単独での仮想ネットワーク構築が可能となった。2016年2月4日にリリースされたDocker 1.10では従来はbridgeネットワークでのみ利用できたリンク機能がほかのネットワークでも利用可能になり、また外部ネットワークと通信できない「内部ネットワーク」を作成できるようになるなど、ネットワーク関連機能が強化されている。
Dockerのネットワーク機能の基本
このように機能強化が進められているDockerのネットワーク機構であるが、その基本となるのはブリッジを使った仮想ネットワークだ。まずはこのブリッジによる仮想ネットワークについて、そのデフォルトの動作を簡単に説明しておこう。
DockerではDockerホスト上に仮想ブリッジを利用してネットワークの端点を作り、それをコンテナの仮想ネットワークインターフェイスに仮想的に接続することで、コンテナとのネットワーク通信を可能にしている(図1)。
Dockerホスト上で作成されているネットワークブリッジは、brctlコマンドで確認できる。
# brctl show bridge name bridge id STP enabled interfaces docker0 8000.02429125675e no docker_gwbridge 8000.0242ef401d36 no
これらネットワークブリッジにはそれぞれIPアドレスが割り当てられており、これを経由してコンテナとの通信が行われる。先の例では、以下のように「docker0」ブリッジには172.17.0.1/16、「docker_gwbridge」には172.18.0.1/16というIPアドレスが割り当てられていることが確認できる。
# ip a : : 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:91:25:67:5e brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:91ff:fe25:675e/64 scope link valid_lft forever preferred_lft forever 70: docker_gwbridge: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:ef:40:1d:36 brd ff:ff:ff:ff:ff:ff inet 172.18.0.1/16 scope global docker_gwbridge valid_lft forever preferred_lft forever inet6 fe80::42:efff:fe40:1d36/64 scope link valid_lft forever preferred_lft forever
この環境で新たに仮想マシンを作成すると、新たにdocker0ブリッジに接続された仮想ネットワークインターフェイスが作成される。この仮想ネットワークインターフェイスはコンテナの仮想ネットワークインターフェイスに対応付けられており、コンテナへのパケットの出入りはこの仮想ネットワークインターフェイスを経由して行われる。
たとえば、次のようにして新たなコンテナを作成してみよう。なおここで作成している「busybox」コンテナは、最小限のシェル環境を備えるコンテナだ。
# docker run -ti --rm busybox
すると、Dockerホスト上では次のような仮想ネットワークインターフェイスが新たに作成される。
# ip a : : 180: veth7044735@if179: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether ae:9a:34:77:96:e9 brd ff:ff:ff:ff:ff:ff link-netnsid 13 inet6 fe80::ac9a:34ff:fe77:96e9/64 scope link valid_lft forever preferred_lft forever
brctlコマンドで確認すると、この仮想ネットワークインターフェイスがdocker0ブリッジに接続されていることが分かる。
# brctl show bridge name bridge id STP enabled interfaces docker0 8000.02429125675e no veth7044735 docker_gwbridge 8000.0242ef401d36 no
コンテナ内でネットワークインターフェイスに割り当てられたIPアドレスを確認すると、docker0ブリッジと同じネットワークに属する172.17.0.2/16というIPアドレスが割り当てられていることが分かる。
/ # ip a : : 179: eth0@if180: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::42:acff:fe11:2/64 scope link valid_lft forever preferred_lft forever
Dockerホスト上で複数のコンテナを起動した場合、これと同様にそのコンテナに対応する仮想ネットワークインターフェイスが作成され、それがdocker0ブリッジに接続される。この場合、すべてのコンテナは同一の仮想ネットワーク内に存在するため、コンテナ同士はこの仮想ネットワークを通じて通信でき、さらにコンテナ-ホスト間の通信も可能となる。しかし、Dockerホストが複数存在する場合、デフォルトでは各Dockerホスト上に構築された仮想ネットワーク同士は接続されていないため、異なるDockerホスト上にあるコンテナはそのままではお互いに通信は行えない(図2)。
そのため、異なるDockerホスト上にあるコンテナ間で通信を行いたい場合はコンテナの起動時に「-p」オプションを使用してDockerホストからのポートフォワーディングを利用するか、flannelなどの仮想ネットワーク構築ソフトウェアを使って別途複数のDockerホストにまたがる仮想ネットワークを構築する必要があった。
Docker 1.9で導入されたマルチホストネットワーク機能
Docker 1.9ではネットワーク機能が刷新され、新たに複数のDockerホストにまたがる仮想ネットワークを構築・管理する機構であるマルチホストネットワーク機能が導入された。マルチホストネットワーク機能は「ドライバ」と呼ばれるプラグイン形式で実装されており、さらに仮想ネットワーク技術であるVXLANベースでマルチホストネットワークを実現するドライバも標準で提供されるようになった。これによって、従来は別途用意する必要があったDockerホスト間を繋ぐ仮想ネットワークをDocker単体で実現できるようになったのである(図3)。
なお、Docker標準のマルチホストネットワークドライバ(「overlay」ドライバ)以外のドライバを利用することも可能だ。これらのうちいくつかはDocker公式ドキュメントのプラグインページに掲載されているが、Dockerクラスタ構築支援ツールを提供するWeaveによるものや、ポリシーベースのコンテナ向けネットワーク/ストレージを提供するContivが提供するもの、IaaS型クラウド構築ソフトウェア「OpenStack」の仮想ネットワーク管理機構を利用する「Kuryr」などがすでにリリースされている。