LoginSignup
25
26

More than 5 years have passed since last update.

Docker 1.9 でマルチホストネットワーク機能を試した

Last updated at Posted at 2015-11-07

何周遅れだよって話ではあるけど Docker 使い始めました。

さて、【参考訳】 プロダクションに対応するマルチホスト Docker ネットワーク機能を参考にして試した。みんな「dockerのリンクはとても便利」と絶賛するけどどうも馴染まなかった自分には素晴らしい展開。

まずシングルホストでMySQLノードへと他のノードから接続させるテストをしたのち、マルチホストで同様の動作を試すことに。

動作環境は以下のとおりです。

  • MacBook(2015) Mem 8GB
  • OS X El Capitan
  • virtualbox 5.0.8

メモリが足りない。

<追記>なお、この記事の上位互換の内容が @zembutsu さんによって書かれているのでより詳細な内容を知りたい場合はそちらを。</追記>

Docker Toolboxのインストール

初心者なので公式インストーラを使います。

シングルホストで試す

docker networkを作る

$ docker network create backend
461b41ec193090776948e42bee70b64cdc46dfe59e8206e5bbf0cb49372d9589

必要なイメージを pull する

$ docker pull mysql
$ docker pull centos

DBを作る

dbというホスト名で、backend ネットワークに所属するコンテナを作成する。

$ docker run -d -e MYSQL_ROOT_PASSWORD=mysql --net=backend --name db mysql:5.7
3637731853a41c7c318c0f88d356005e48cf76806f360f0d5df8c217beaa544d

もいっこCentOSを立てて、さっきのDBにアクセスする

同じネットワークに属したホスト同士はホスト名でお互いを解決できる。

ネットワーク名(backend)とホスト名(db)の組み合わせで名前解決できることがわかる。このあたりの動きは自然。なお、/etc/hosts を見ればわかるが同じネットワークに属しているのでホスト名だけでも解決できる。

$ docker run -it --net=backend centos
[root@1ea2906c98f0 /]# ping db.backend
PING db.backend (172.19.0.2) 56(84) bytes of data.
64 bytes from db (172.19.0.2): icmp_seq=1 ttl=64 time=0.153 ms
64 bytes from db (172.19.0.2): icmp_seq=2 ttl=64 time=0.080 ms
64 bytes from db (172.19.0.2): icmp_seq=3 ttl=64 time=0.085 ms
[root@1ea2906c98f0 /]# yum install -y mysql

.... 

[root@1ea2906c98f0 /]# mysql --version
mysql  Ver 15.1 Distrib 5.5.44-MariaDB, for Linux (x86_64) using readline 5.1

[root@1ea2906c98f0 /]# mysql -h db.backend -uroot -pmysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.9 MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

ちゃんとdb.backend という名前で MySQL 5.7.9 に接続できた!

[root@1ea2906c98f0 /]# cat /etc/hosts
172.19.0.3  1ea2906c98f0
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.19.0.2  db
172.19.0.2  db.backend

これら名前は /etc/hosts に書かれている。まあこのあたりは理解できる話。しかし、この状態で mysql のコンテナを落とすと /etc/hosts に書かれた mysql のエントリも消える。 しかも、新しく同じネットワークにコンテナを起動すると /etc/hosts にエントリが増える。なんてことだ。やや感動した。

<余談> MySQLサーバの方の /etc/hosts

こうなってた。

# cat /etc/hosts
172.19.0.2  3637731853a4
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
#

centosがいないのはホスト名つけてないからかな。

<余談>作成済みのコンテナを後からネットワークに所属させたり

コンテナ作成時に --net=hogehoge で指定するだけでなく、connect サブコマンドで後から所属させることができる。

$ docker network connect <コンテナ名> <ネットワーク名>

手元で試した際、-p 80:80 で公開済みの Nginx コンテナを frontend ネットワークに所属させようとしたら、以下のように怒られたので一度ポートのバインド外す必要があったりとかしそう。このあたりは細かく見てない。ごめんなさい。

$ docker network connect frontend nginx_web
Error response from daemon: failed to create endpoint nginx_front on network frontend: Bind for 0.0.0.0:80 failed: port is already allocated

マルチホストで試す

swarm を作る

$ docker run swarm create

=> <SWARM_TOKEN>

このトークンを後から使うのでとっておく。

ところでマルチホストネットワークにはクラスタ設定が必要だ

--cluster-advertise--cluster-storeの指定をした Docker Engine が必要である。

To use multi-host networking you need to start your docker engines with --cluster-store and --cluster-advertise as indicated in the docker engine docs
https://docs.docker.com/swarm/networking/

公式のサンプルコードには Consul を起動する手順が書かれている。

ここではとりあえずなので、このまんま Consul用の環境を一個作ってしまう。Consulも使ったことがないが、いいんだ。どう動いているかどうかを細かく理解するのは後回しである。後で見よう。

docker-machine create \
    -d virtualbox \
    mhl-consul-1

docker $(docker-machine config mhl-consul-1) run -d \
    -p "8500:8500" \
    -h "consul" \
    progrium/consul -server -bootstrap

https://docs.docker.com/swarm/discovery/ このへん見ると クラスタ情報を外部で保持する discovery には consul だけでなく etcd とか zookeeper も選択できるみたい。

swarm master を作る

docker-machine create \
        -d virtualbox \
        --swarm \
        --swarm-master \
        --swarm-discovery token://${SWARM_TOKEN} \
        --engine-opt="cluster-store=consul://$(docker-machine ip mhl-consul-1):8500" \
        --engine-opt="cluster-advertise=eth1:0" \
        swarm-master

できたらこっちに環境を切り替える。eval $(docker-machine env --swarm swarm-master)する。

swarm node を作る

$ docker-machine create \
    -d virtualbox \
    --swarm \
    --swarm-discovery token://${SWARM_TOKEN} \
    --engine-opt="cluster-store=consul://$(docker-machine ip mhl-consul-1):8500" \
    --engine-opt="cluster-advertise=eth1:0" \
    swarm-agent-00


$ docker-machine create \
    -d virtualbox \
    --swarm \
    --swarm-discovery token://${SWARM_TOKEN} \
    --engine-opt="cluster-store=consul://$(docker-machine ip mhl-consul-1):8500" \
    --engine-opt="cluster-advertise=eth1:0" \
    swarm-agent-01

確認。

$ docker-machine ls
NAME             ACTIVE   DRIVER       STATE     URL                         SWARM
default          -        virtualbox   Running   tcp://192.168.99.100:2376
mhl-consul-1     -        virtualbox   Running   tcp://192.168.99.101:2376
swarm-agent-00   -        virtualbox   Running   tcp://192.168.99.103:2376   swarm-master
swarm-agent-01   -        virtualbox   Running   tcp://192.168.99.104:2376   swarm-master
swarm-master     -        virtualbox   Running   tcp://192.168.99.102:2376   swarm-master (master)

子供達が増えてた。

swarm-master に接続して状態を見る

swarm-master を普通のDockerエンジンのように扱って接続できる。--swarm を指定して接続すると、単独ノードではなくクラスタ全体を対象として操作することになる。

$ eval $(docker-machine env --swarm swarm-master)

あとは普通に docker コマンドが使える。

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

$ docker info
Containers: 4
Images: 3
Role: primary
Strategy: spread
Filters: health, port, dependency, affinity, constraint
Nodes: 3
 swarm-agent-00: 192.168.99.103:2376
  └ Containers: 1
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.021 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=4.1.12-boot2docker, operatingsystem=Boot2Docker 1.9.0 (TCL 6.4); master : 16e4a2a - Tue Nov  3 19:49:22 UTC 2015, provider=virtualbox, storagedriver=aufs
 swarm-agent-01: 192.168.99.104:2376
  └ Containers: 1
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.021 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=4.1.12-boot2docker, operatingsystem=Boot2Docker 1.9.0 (TCL 6.4); master : 16e4a2a - Tue Nov  3 19:49:22 UTC 2015, provider=virtualbox, storagedriver=aufs
 swarm-master: 192.168.99.102:2376
  └ Containers: 2
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.021 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=4.1.12-boot2docker, operatingsystem=Boot2Docker 1.9.0 (TCL 6.4); master : 16e4a2a - Tue Nov  3 19:49:22 UTC 2015, provider=virtualbox, storagedriver=aufs
CPUs: 3
Total Memory: 3.064 GiB
Name: a1eae869d74b

3ノードが統括されている。
どうでもいいけど 3CPU、Total Memory 3GBはMacBookにはそれなりに深刻…。この他にConsulマシンがいるからね。

ネットワークを作成する

ネットワークを表示してみる。

$ docker network create backend
cf756ea9e77cbabf1e3ba019b4e7afc8b8b4575bd565415e9c304397e23c0664

$ docker network ls
NETWORK ID          NAME                    DRIVER
ded21015a5b2        swarm-master/none       null
41558558d9be        swarm-master/host       host
cf756ea9e77c        backend                 overlay
4cbc614ed481        swarm-agent-01/none     null
e9aefb33dfd7        swarm-agent-01/host     host
d1435420f650        swarm-master/bridge     bridge
01cbc675564a        swarm-agent-00/bridge   bridge
9ea065803ecc        swarm-agent-00/none     null
8fbe7735ed4c        swarm-agent-00/host     host
d69c33adb66c        swarm-agent-01/bridge   bridge

各ホストごとのネットワークの他に、今作った backend という名のオーバーレイネットワークができてる。

discovery を使わずに各エンジンを作っていると、オーバーレイネットワークの作成ができない。

$ docker network create backend
Error response from daemon: 500 Internal Server Error: failed to parse pool request for address space "GlobalDefault" pool "" subpool "": cannot find address space GlobalDefault (most likely the backing datastore is not configured)

このエラーが出た時は Docker エンジンが cluster-advertisecluster-store の指定なしで作られちゃってる疑惑。docker-machine inspectで確認するんだ。

上の手順で Consul を立ててなかったりするとこれでこける。

docker pull すると各ノードでダウンロードされる

各ノードでコンテナイメージは持たないとなわけだから、まあそうなるのか。

$ docker pull mysql
Using default tag: latest
swarm-agent-01: Pulling mysql:latest...
swarm-master: Pulling mysql:latest...
swarm-agent-00: Pulling mysql:latest...
$ docker pull centos
Using default tag: latest
swarm-agent-01: Pulling centos:latest... : downloaded
swarm-master: Pulling centos:latest... : downloaded
swarm-agent-00: Pulling centos:latest... : downloaded

全部 virtualbox だと複数並列で pull するので、自宅回線的につらみがある。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
swarm               latest              6b40fe7724bd        3 days ago          15.6 MB
mysql               latest              fb86ef4dd8b7        8 days ago          359.8 MB
centos              latest              e9fa5d3a0d0e        3 weeks ago         172.3 MB

swarm だと docker images コマンド叩けないと書かれた記事もあるが、現時点ではそんなこともない模様。

シングルホストの時と同じようにコンテナを作って試す

ネットワーク「backend」に所属させる。

docker run -d -e MYSQL_ROOT_PASSWORD=mysql --net=backend --name db mysql
docker run -it --net=backend --name centos centos

swarm上だと -d でデーモン起動しないとまずいという記事も見たが、現時点ではフォアグラウンド実行も可能みたい。

別窓でログインして docker ps 打つと、ちゃんと異なるノードで起動しているのがわかる。mysqlは swarm-agent-00、 centosは swarm-agent-01。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
6a2a862a4fac        centos              "/bin/bash"              39 seconds ago      Up 38 seconds                           swarm-agent-01/centos
33358a65ed35        mysql               "/entrypoint.sh mysql"   39 minutes ago      Up 39 minutes       3306/tcp            swarm-agent-00/db

CentOS側でmysql(maria)をインストールして、MySQLノードに接続する。

[root@6a2a862a4fac /]# yum install -y mysql
[root@6a2a862a4fac /]# mysql -uroot -hdb.backend -pmysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.9 MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]>

でけたー。ちゃんと MySQL5.7.9 につながる。
いい感じに「普通」につながる。

いったんはここまで。

25
26
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
25
26