LoginSignup
36
40

More than 5 years have passed since last update.

docker networkでマルチホストネットワークを試してみた(docker-1.9.0)

Last updated at Posted at 2015-11-09

概要

docker 1.9.0がリリースされ、docker networkコマンドがproductionでも使えるようになりました。特にマルチホストでのコンテナネットワークがdockerコマンドから作成可能になったので試してみました。

docker networkコマンドとは

docker networkはコンテナに接続するネットワークを操作・管理するコマンド。
Docker Swarmと連携すればマルチホスト環境でも、コンテナ間でoverlayネットワークを構築してコンテナ間が通信できる。
マルチホストのコンテナネットワークを実現するツールや方法は他にもいろいろある。weaveetcd+flannelruncherbridge接続+GREなどなど。

環境

今回は2つのDockerホストVMをSwarmでクラスタ化し、docker networkコマンドでoverlayネットワークを構築して、マルチホストでのコンテナ通信ができるかを試しました。

あとdocker networkコマンドによるoverlayネットワークはLinux Kernel 3.16以上が必要になります。CentOS7は3.10なので、3.18をビルドしてインストールしています。(kernelビルド部分は省略)Ubuntu 14.10のカーネルは3.16なので、Ubuntuで試せばよかった。

  • CentOS7(VM) x2台
    • docker01 :192.168.11.48 (consul server)
    • docker02 :192.168.11.49 (consul client)
  • Linux Kernel 3.18
  • Docker 1.9.0
  • Docker Swarm 1.0
  • consul 0.5.2(Docker SwarmのバックエンドKVS)

やったこと目次

  1. consulのインストール・設定
  2. Docker1.9.0のインストール・設定
  3. Docker Swarmでクラスタ化
  4. overlay networkの作成
  5. コンテナにネットワークを接続して起動
  6. コンテナ間の疎通確認

consulインストール・設定

インストール
バイナリファイルをダウンロードして配置するだけ。合わせて必要な設定ファイル、ディレクトリを作成します。

$ wget https://releases.hashicorp.com/consul/0.5.2/consul_0.5.2_linux_amd64.zip
$ unzip consul_0.5.2_linux_amd64.zip
$ sudo cp consul /usr/local/bin/
$ sudo mkdir -p {/etc/consul,/var/lib/consul,/var/log/consul}

consul設定
consulの設定ファイルをserverとclientの2種類作成します。

docker01(consul server)

/etc/consul/consul.json
{
  "datacenter": "docker",
  "addresses" : {
    "http": "0.0.0.0"
  },
  "bind_addr": "192.168.11.48",
  "node_name": "docker01",
  "domain": "consul",
  "server": true,
  "bootstrap_expect": 1,
  "data_dir": "/var/lib/consul"
}

docker02(consul client)

/etc/consul/consul.json
{
  "datacenter": "docker",
  "addresses" : {
    "http": "0.0.0.0"
  },
  "bind_addr": "192.168.11.49",
  "node_name": "docker02",
  "domain": "consul",
  "retry_join": [ "192.168.11.48"],
  "server": false,
  "data_dir": "/var/lib/consul"
}

consul起動

docker01&docker02
$ consul -config-file=/etc/consul/consul.json >> /var/log/consul/consul.log &
$ consul members
Node      Address             Status  Type    Build  Protocol  DC
docker02  192.168.11.49:8301  alive   client  0.5.2  2         docker
docker01  192.168.11.48:8301  alive   server  0.5.2  2         docker

ちゃんとconsulクラスタにdocker01,02がいますね。

Docker 1.9.0インストール・設定

インストール
CentOS7はまだyumにあるdockerが1.8.2なので(2015/11/9現在)、最新のバイナリをダウンロードして挿し替えています。

docker01&docker02
$ sudo yum install -y docker
$ curl -o docker-1.9.0 https://get.docker.com/builds/Linux/x86_64/docker-1.9.0
$ sudo cp docker-1.9.0 /usr/bin/docker
$ sudo chmod +x /usr/bin/docker

Docker Engine設定
docker daemonの--cluster-store --cluster-advertiseオプションを設定して起動します。それぞれKVSのアドレス、ホスト自身のipaddress:portを設定します。

/etc/sysconfig/docker(docker01&docker02)
OPTIONS='--cluster-store=consul://localhost:8500 --cluster-advertise=<ホストIP>:2376 -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock'

Docker起動

docker01&docker02
$ sudo systemctl start docker

Docker Swarmクラスタ起動

docker01のホストでSwarmのクラスタマネージャコンテナを起動します。

docker01
$ docker run -d -p 2377:2375 --name swarm-manage-consul swarm manage consul://192.168.11.48:8500/docker

各ホストでSwarmクラスタへjoinするためのswarmコンテナを起動します。dockerコマンドがswarmマネージャコンテナに向けて実行できればOKです。

docker01&docker02
# docker01
$ docker run -d --name swarm-join swarm join --advertise=192.168.11.48:2375 consul://192.168.11.48:8500/docker
# docker02
$ docker run -d --name swarm-join swarm join --advertise=192.168.11.49:2375 consul://192.168.11.48:8500/docker
$ docker -H tcp://192.168.11.48:2377 info
Containers: 3
Images: 4
Role: primary
Strategy: spread
Filters: health, port, dependency, affinity, constraint
Nodes: 2
 centos7-01: 192.168.11.48:2375
  └ Containers: 2
  └ Reserved CPUs: 0 / 2
  └ Reserved Memory: 0 B / 2.052 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.18.22, operatingsystem=CentOS Linux 7 (Core), storagedriver=overlay
 centos7-02: 192.168.11.49:2375
  └ Containers: 1
  └ Reserved CPUs: 0 / 2
  └ Reserved Memory: 0 B / 2.052 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.18.22, operatingsystem=CentOS Linux 7 (Core), storagedriver=overlay
CPUs: 4
Total Memory: 4.103 GiB
Name: 755cb58b105c

ここまででdocker networkコマンドでoverlayネットワークを作成する準備ができました。いよいよ次はoverlayネットワーク作成します。

overlay networkの作成

docker network createコマンドでoverlayネットワークを作成します。
1つのホストで作成したvn01のネットワーク設定はクラスタの全ホストで共有されます。docker inspectコマンドで作成したコンテナネットワーク情報が見れます。

docker01&docker02
# docker01
$ docker network ls
NETWORK ID          NAME                DRIVER
6f9ee8d629d6        none                null                
0f0d0f12a59f        host                host                
12613b8ef4b7        docker_gwbridge     bridge              
0ac1dafaa764        bridge              bridge 

$ docker network create -d overlay vn01 
b07f8c4a5cb954e7ff8d387bfc65e3239f67852ee65f68cea8d77e9032b577c5

$ docker network ls
NETWORK ID          NAME                DRIVER
b07f8c4a5cb9        vn01                overlay             
0ac1dafaa764        bridge              bridge              
6f9ee8d629d6        none                null                
0f0d0f12a59f        host                host                
12613b8ef4b7        docker_gwbridge     bridge 

$ docker network inspect vn01
[
    {
        "Name": "vn01",
        "Id": "b07f8c4a5cb954e7ff8d387bfc65e3239f67852ee65f68cea8d77e9032b577c5",
        "Scope": "global",
        "Driver": "overlay",
        "IPAM": {
            "Driver": "default",
            "Config": [
                {}
            ]
        },
        "Containers": {},
        "Options": {}
    }
]
# docker02
$ docker network ls
NETWORK ID          NAME                DRIVER
b07f8c4a5cb9        vn01                overlay             
65a8ead71e7c        none                null                
ebb12613053e        host                host                
02ca2b4c8d98        docker_gwbridge     bridge              
071afc5c93e3        bridge              bridge  

コンテナへのネットワーク割り当て

test01コンテナを作って、vn01ネットワークを付与させてみます。

docker01
$ docker run -idt --name test01 --hostname test01 centos:7 /bin/bash
$ docker network connect vn01 test01
$ docker exec test01 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    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
40: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    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
43: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP 
    link/ether 02:42:0a:00:00:02 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.2/24 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::42:aff:fe00:2/64 scope link 
       valid_lft forever preferred_lft forever

test01のコンテナのeth110.0.0.2/24のネットワークが付いてますね。IPアドレスは自動で割り振られるのかな?

コンテナ起動時に--netオプションを使うことでも付与できるみたいです。

dcoker01
$ docker run -dit --name test01 --hostname test01 --net vn01 centos:7 /bin/bash

同様に別のホストでもvn01を付与したコンテナを起動してネットワークを付与します。

docker02
$ docker run -dit --name test02 --hostname test02 centos:7 /bin/bash
$ docker network connect vn01 test02 
$ docker exec test02 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    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
39: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    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
42: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP 
    link/ether 02:42:0a:00:00:03 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.3/24 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::42:aff:fe00:3/64 scope link 
       valid_lft forever preferred_lft forever

こっちは10.0.0.3/24のネットワークがついてますね。

コンテナ間通信

やっとコンテナの疎通確認!test02(10.0.0.3)コンテナからtest01コンテナ(10.0.02)へpingを打ってみます。

$ docker exec test02 ping -c 4 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.991 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.639 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.650 ms
64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=0.664 ms

--- 10.0.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 0.639/0.736/0.991/0.147 ms

つながりました!

どうやらコンテナ名で名前解決もできるみたい。便利!

docker02
$ docker exec test02 ping -c 4 test01
PING test01 (10.0.0.2) 56(84) bytes of data.
64 bytes from test01 (10.0.0.2): icmp_seq=1 ttl=64 time=0.516 ms
64 bytes from test01 (10.0.0.2): icmp_seq=2 ttl=64 time=0.665 ms
64 bytes from test01 (10.0.0.2): icmp_seq=3 ttl=64 time=0.745 ms
64 bytes from test01 (10.0.0.2): icmp_seq=4 ttl=64 time=0.714 ms

--- test01 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 0.516/0.660/0.745/0.087 ms

静的IPは振れない(?)みたいですが、名前解決できるので問題なさそう。
いろいろオプションがあるみたいですがまだ試せていません…。
コンテナネットワークを外部に公開できる機能があれば最高なのになぁ。weave exposeみたいな。まだないのかな?それとも外部接続用コンテナ作ってそこはブリッジ接続かな。

あとは性能がどんなもんかですね。技術的にはvxlanでoverlayネットワークを作成しているみたいですが、そのオーバーヘッドで性能どうなるか私気になります!

参考

36
40
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
36
40