90
85

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Docker : マルチホスト間での仮想ネットワーク

Last updated at Posted at 2015-11-08

概要

Docker 1.9 で正式版になったマルチホストネットワーク機能を使ってみたのでまとめます。

この機能では、複数のホストにまたがる仮想ネットワークを構築でき、コンテナはどこのホスト上で動いているかに関わらず、仮想ネットワークを経由して他のコンテナと通信することができます。

今回は下図のように、2台のホスト上のコンテナが仮想ネットワークを通じて通信できるようにしました。
DockerNetwork.png

マルチホストネットワークの要件

  • マルチホストネットワークを使うには、複数のホストにまたがる Key/Value ストアが必要になりますが(図の Consul がそれに相当)、これについては後述します
  • ホストの Linux Kernel は 3.16 かそれ以降が必要になります

今回の検証環境

  • Host: Ubuntu 15.10 (Kernel 4.2.0)
  • Docker Version: 1.9.0

手順

Docker 1.9 のインストール

2台のホスト上で、それぞれ以下を実行します。

Host1&Host2
# Docker Engine の最新版をインストール
$ curl -sSL https://test.docker.com/ | sh

# Docker デーモンが動いていたら停止しておく。後で、デフォルトとは異なるパラメータを付けて開始するため。
$ sudo service docker stop

# docker コマンドを実行するたびに sudo を打つのが面倒なので、以下のコマンドを実行して再ログインする。
$ sudo usermod -aG docker <username>

Consul のインストールと起動

複数のホストにまたがる仮想ネットワークを作成する場合は、ホスト間でネットワークの情報を共有するために 分散Key/Value ストアのクラスターが必要になります。

Docker 1.9 では Consul, etcd, ZooKeeper が利用できるようですが、今回は Consul を使いました。Consul は、Vagrant や Packer を開発している HashiCorp が提供している Key/Value ストアです。

まずは、両方のホストで consul をダウンロード。

Host1&Host2
# ダウンロード
$ wget https://releases.hashicorp.com/consul/0.5.2/consul_0.5.2_linux_amd64.zip

# もし unzip コマンドが入ってなければインストールしておく
$ sudo apt-get install unzip

# consul を解凍してコピー
$ unzip consul_0.5.2_linux_amd64.zip
$ sudo cp consul /usr/local/bin/

Host1 側で consul をサーバーとして起動。

Host1
consul agent -server -bootstrap -data-dir=/tmp/consul -bind=100.74.14.78

Host2 側の consul をクラスターに参加させる。

Host2
consul agent -data-dir=/tmp/consul -bind=100.74.120.62 -join=100.74.14.78

別のターミナルから両ホストにSSH接続して、以下のコマンドを実行。クラスタが形成されたか確認しておきます。

Host1&Host2
$ consul members
Node     Address             Status  Type    Build  Protocol  DC
Ubuntu1  100.74.14.78:8301   alive   server  0.5.2  2         dc1
Ubuntu2  100.74.120.62:8301  alive   client  0.5.2  2         dc1

Docker デーモンの起動

Key/Value ストアのクラスターが構成できたので、それを指定して Docker デーモンを起動します。引数は以下になります。

  • --cluster-store : Key/Value のクラスタ
  • --cluster-advertise : 自分自身の IP/Port を指定します。
Host1
$ sudo docker daemon --cluster-store=consul://localhost:8500 --cluster-advertise=100.74.14.78:2376
Host2
$ sudo docker daemon --cluster-store=consul://localhost:8500 --cluster-advertise=100.74.120.62:2376

ネットワークの作成

また新しいターミナルを起動して、まずはデフォルトで作成されているネットワークを確認します。どちらも、bridge, null, host の3つのネットワークがあることが分かります。

Host1
$ docker network ls
NETWORK ID          NAME                DRIVER
3db3635076e3        bridge              bridge
1f616c6c3c34        none                null
e459697f7cb8        host                host
Host2
$ docker network ls
NETWORK ID          NAME                DRIVER
a629ccb5fbba        bridge              bridge
2802d9ae3067        none                null
42b1f2f3d2bd        host                host

ここで、Host1 側だけで 新しいネットワークを作成します。

Host1
$ docker network create -d overlay TestNetwork
60231ea6adf2c36cafe68ddc5ee0548fbae034a812b988c3e018b41b1cc66278

すると、Host1 と Host2 の両方で、今作成した TestNetwork というネットワークが見えます。

Host1
$ docker network ls
NETWORK ID          NAME                DRIVER
60231ea6adf2        TestNetwork         overlay
3db3635076e3        bridge              bridge
1f616c6c3c34        none                null
e459697f7cb8        host                host
Host2
$ docker network ls
NETWORK ID          NAME                DRIVER
60231ea6adf2        TestNetwork         overlay
a629ccb5fbba        bridge              bridge
2802d9ae3067        none                null
42b1f2f3d2bd        host                host

コンテナの作成とコンテナ間の通信

仮想ネットワークが作成できたので、いよいよネットワーク上にコンテナを作成します。

Host1
# コンテナを起動
$ docker run -it --net=TestNetwork --name=Container1 ubuntu /bin/bash

# コンテナの中で ifconfig を実行してIPアドレスを確認
root@27f699b0d97c:/# ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:0a:00:00:02
          inet addr:10.0.0.2  Bcast:0.0.0.0  Mask:255.255.255.0
          inet6 addr: fe80::42:aff:fe00:2/64 Scope:Link
          (中略)

eth1      Link encap:Ethernet  HWaddr 02:42:ac:12:00:02
          inet addr:172.18.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe12:2/64 Scope:Link
          (中略)
Host2
# コンテナを起動
$ docker run -it --net=TestNetwork --name=Container2 ubuntu /bin/bash

# コンテナの中で ifconfig を実行してIPアドレスを確認
root@6b4baee6e4d0:/# ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:0a:00:00:03
          inet addr:10.0.0.3  Bcast:0.0.0.0  Mask:255.255.255.0
          inet6 addr: fe80::42:aff:fe00:3/64 Scope:Link
          (中略)

eth1      Link encap:Ethernet  HWaddr 02:42:ac:12:00:02
          inet addr:172.18.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe12:2/64 Scope:Link
          (中略)

どちらのコンテナにも 172.18.0.2 という IP のほかに、10.0.0.x という IP が割り当たっています。この 10.0.0.x が、仮想ネットワークに接続されている IP アドレスになります。

ping での通信

では、Container1(10.0.0.2) から Container2(10.0.0.3) に通信してみます。IP でもコンテナ名でも Ping が送れることが分かります。

Container1
# IP で ping を送る
root@27f699b0d97c:/# ping 10.0.0.3
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
64 bytes from 10.0.0.3: icmp_seq=1 ttl=64 time=1.11 ms
64 bytes from 10.0.0.3: icmp_seq=2 ttl=64 time=0.806 ms
・・・

# コンテナ名で ping を送る
root@27f699b0d97c:/# ping Container2
PING Container2 (10.0.0.3) 56(84) bytes of data.
64 bytes from Container2 (10.0.0.3): icmp_seq=1 ttl=64 time=0.661 ms
64 bytes from Container2 (10.0.0.3): icmp_seq=2 ttl=64 time=1.61 ms
・・・

# コンテナ名.ネットワーク名 で ping を送る
root@27f699b0d97c:/# ping Container2.TestNetwork
PING Container2.TestNetwork (10.0.0.3) 56(84) bytes of data.
64 bytes from Container2 (10.0.0.3): icmp_seq=1 ttl=64 time=1.00 ms
64 bytes from Container2 (10.0.0.3): icmp_seq=2 ttl=64 time=0.767 ms
・・・

HTTP での通信

次に HTTP で通信してみます。
まず、Container1 内に HTTP サーバーを入れます。

Container1
# apache のインストールと開始
root@27f699b0d97c:/# apt-get install apache2
root@27f699b0d97c:/# service apache2 start

# HTML ファイルの作成しておく
root@27f699b0d97c:/# echo "Hello, I'm Container1." > /var/www/html/test.html

Container2 から HTTP サーバーにアクセスすると、ちゃんと応答が返ってきます。

Container2
# コンテナ名で HTTP リクエストを送る
root@6b4baee6e4d0:/# curl http://Container1/test.html
Hello, I'm Container1.

マルチホストネットワーク機能を使わない場合は、docker run コマンドの -p, -P オプションでポートの公開をする必要がありましたが、マルチホストネットワークではそれも不要のようです。

参考サイト

90
85
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
90
85

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?