ようへいの日々精進XP

よかろうもん

Docker Swarm with Consul Tutorial

タイトルの英語綴りが正しいか気になる。

tl;dr

JMeterクラスタ構成を Docker でなんとか出来ないかなと思ったら Docker Swarm というものがあるらしいのでチュートリアルしてみた。


Docker Swarm とは

参考

docs.docker.com

イメージ

Docker Swarm とは複数 Docker ホストをクラスタリングして個々の Docker エンジンを一つの Docker エンジンとして扱えるツール(という認識)で以下のようなイメージを頭に描いた。

f:id:inokara:20150826165129p:plain

チュートリアルしてみて上記のイメージは大体合っている気がしたが、実際に構築する場合には以下のように swarm クラスタ内には swarm manager という役割を持ったクラスタの master ノードが必要になる。

f:id:inokara:20150826171123p:plain

swarm manager となるノードについてはクラスタオーケストレーションやコンテナのスケジューリングを行う役割がある。

バックエンド

クラスタ構成やコンテナ内のサービスを動的に管理する為に etcd や Consul や Zookeeper 等を利用することが出来るとのこと。(Docker Hub も利用出来る)

フィルター

コンテナのスケジューリングに以下のようなフィルタを利用することが出来る。

例えば、Affinity フィルタを以下のように利用することで web コンテナと redis コンテナを同じ swarm ノードに起動することが出来る。

a$ docker run -d -p 80:80 --name web nginx
fcdff6790f6b887002a4821a6e97ec66fc328e96bf1b25a7de2c7401b6de469f
$ docker run -d --name redis -e affinity:container==web redis
f18e26e2538c4c54843af7a5f808123bcd76771eb0346bbdbb3b3522a66ed2c3
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                NAMES
f18e26e2538c        redis               "/entrypoint.sh redis"   4 seconds ago       Up 4 seconds        6379/tcp                             swarm-master/redis
fcdff6790f6b        nginx               "nginx -g 'daemon off"   54 seconds ago      Up 53 seconds       192.168.99.103:80->80/tcp, 443/tcp   swarm-master/web

web コンテナと redis コンテナは swarm-master ノード上で起動している。


チュートリアル

やること

チュートリアルの環境

# MacOS のバージョン
$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.10.5
BuildVersion:   14F27

# VirtualBox のバージョン
$ /Applications/VirtualBox.app/Contents/MacOS/VBoxManage --version
5.0.2r102096

# Docker のバージョン
$ docker version
Client:
 Version:      1.8.1
 API version:  1.20
 Go version:   go1.4.2
 Git commit:   d12ea79
 Built:        Thu Aug 13 02:49:29 UTC 2015
 OS/Arch:      darwin/amd64

Server:
 Version:      swarm/0.4.0
 API version:  1.16
 Go version:   go1.4.2
 Git commit:   d647d82
 Built:        
 OS/Arch:      linux/amd64

Consul の起動

Swarm でクラスタを構成する場合に etcd や Consul や Zookeeper をバックエンドの KVS として利用出来るということで、今回は Consul 1 node でお試し。

$ consul agent -server -bootstrap-expect=1 -node=consul01 -data-dir=/tmp/consul -client=0.0.0.0 & 

上記のように Consul を起動しておく。

swarm node(VirtualBox VM) の起動

# swarm master の起動
$ docker-machine create \
  --driver virtualbox \
  --swarm \
  --swarm-master \
  --swarm-discovery=consul://192.168.xx.xx:8500/swarm \
swarm-master
 
# swarm node 01 の起動
$ docker-machine create \
  --driver virtualbox \
  --swarm \
  --swarm-discovery=consul://192.168.xx.xx:8500/swarm \
 swarm-node01
 
# swarm node 02 の起動
$  docker-machine create \
  --driver virtualbox \
  --swarm \
  --swarm-discovery=consul://192.168.xx.xx:8500/swarm \
 swarm-node02

swarm クラスタの確認

docker-machine ls で確認。

$ docker-machine ls
NAME           ACTIVE   DRIVER       STATE     URL                         SWARM
default                 virtualbox   Stopped
swarm-master            virtualbox   Running   tcp://192.168.xx.103:2376   swarm-master (master)
swarm-node01            virtualbox   Running   tcp://192.168.xx.104:2376   swarm-master
swarm-node02            virtualbox   Running   tcp://192.168.xx.105:2376   swarm-master

Consul の KVS を確認。

$ curl -s http://localhost:8500/v1/kv/?recurse | python -m json.tool
[
    {
        "CreateIndex": 1020,
        "Flags": 0,
        "Key": "swarm/docker/swarm/nodes/192.168.xx.103:2376",
        "LockIndex": 1,
        "ModifyIndex": 2806,
        "Session": "080f0255-953c-f5e6-56e9-a1a235d408e2",
        "Value": "MTkyLjE2OC45OS4xMDM6MjM3Ng=="
    },
    {
        "CreateIndex": 1028,
        "Flags": 0,
        "Key": "swarm/docker/swarm/nodes/192.168.xx.104:2376",
        "LockIndex": 1,
        "ModifyIndex": 2805,
        "Session": "b7f19001-14e8-c294-0dde-71f5cf8aa302",
        "Value": "MTkyLjE2OC45OS4xMDQ6MjM3Ng=="
    },
    {
        "CreateIndex": 1042,
        "Flags": 0,
        "Key": "swarm/docker/swarm/nodes/192.168.xx.105:2376",
        "LockIndex": 1,
        "ModifyIndex": 2807,
        "Session": "8f66fdf7-13cd-b91f-e44f-a0049924796a",
        "Value": "MTkyLjE2OC45OS4xMDU6MjM3Ng=="
    }
]

Value にはどんな値が入っているのかしら。

$ bundle exec ./bin/consul_kv_client 127.0.0.1:8500 list
+----------------------------------------------+---------------------+
| Key                                          | Value               |
+----------------------------------------------+---------------------+
| swarm/docker/swarm/nodes/192.168.xx.103:2376 | 192.168.xx.103:2376 |
| swarm/docker/swarm/nodes/192.168.xx.104:2376 | 192.168.xx.104:2376 |
| swarm/docker/swarm/nodes/192.168.xx.105:2376 | 192.168.xx.105:2376 |
+----------------------------------------------+---------------------+

上記のように Docker API のエンドポイントの URL が KVS に記録されている。

次に swarm-master にアクセスする為に以下のように docker-machine env を実行する。

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

docker infoクラスタの状態を確認する。

$ docker info
Containers: 7
Images: 6
Role: primary
Strategy: spread
Filters: affinity, health, constraint, port, dependency
Nodes: 3
 swarm-master: 192.168.xx.103:2376
  └ Containers: 3
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.022 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=4.0.9-boot2docker, operatingsystem=Boot2Docker 1.8.1 (TCL 6.3); master : 7f12e95 - Thu Aug 13 03:24:56 UTC 2015, provider=virtualbox, storagedriver=aufs
 swarm-node01: 192.168.xx.104:2376
  └ Containers: 2
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.022 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=4.0.9-boot2docker, operatingsystem=Boot2Docker 1.8.1 (TCL 6.3); master : 7f12e95 - Thu Aug 13 03:24:56 UTC 2015, provider=virtualbox, storagedriver=aufs
 swarm-node02: 192.168.xx.105:2376
  └ Containers: 2
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.022 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=4.0.9-boot2docker, operatingsystem=Boot2Docker 1.8.1 (TCL 6.3); master : 7f12e95 - Thu Aug 13 03:24:56 UTC 2015, provider=virtualbox, storagedriver=aufs
CPUs: 3
Total Memory: 3.065 GiB
Name: a33c65015af1

各 swarm node の状態を確認したい場合には以下のように確認する。

$ docker $(docker-machine config swarm-master) info
$ docker $(docker-machine config swarm-node01) info
$ docker $(docker-machine config swarm-node02) info

swarm クラスタ内にコンテナを起動する

適当にコンテナを起動すると以下のように各 swarm node 上に 1 コンテナずつ起動している。

# 1 台目のコンテナ
$ docker run -d redis
c67882ce7a72845d7ee228a841fb26521984653ed06f6e5abbee32275061704e
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
c67882ce7a72        redis               "/entrypoint.sh redis"   28 seconds ago      Up 28 seconds       6379/tcp            swarm-node01/loving_jones

# 2 台目のコンテナ
$ docker run -d redis
ff05b6140144512d72b49e7543260ff9203f860835969042f76568e8c2cc4509
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
ff05b6140144        redis               "/entrypoint.sh redis"   34 seconds ago       Up 34 seconds       6379/tcp            swarm-node02/clever_mclean
c67882ce7a72        redis               "/entrypoint.sh redis"   About a minute ago   Up About a minute   6379/tcp            swarm-node01/loving_jones

# 3 台目のコンテナ
$ docker run -d redis
6a5ad23f7ad48a55c1ade85e357443634731aee3594f2418daa8fd4639cd103d
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
6a5ad23f7ad4        redis               "/entrypoint.sh redis"   5 seconds ago        Up 4 seconds        6379/tcp            swarm-master/romantic_engelbart
ff05b6140144        redis               "/entrypoint.sh redis"   About a minute ago   Up About a minute   6379/tcp            swarm-node02/clever_mclean
c67882ce7a72        redis               "/entrypoint.sh redis"   2 minutes ago        Up About a minute   6379/tcp            swarm-node01/loving_jones

おお、それぞれの swarm ノードに 1 コンテナずつ起動しているけど、あたかも 1 つの Docker エンジン上にコンテナを起動しているような気分(気分かい...)。


最後に

Docker Swarm 面白そう

  • 複数の Docker マシンをあたかも 1 台の Docker マシンのように見える、見える、見える(感動)
  • Consul を利用して簡単にクラスタ構築出来た、出来た、出来た(感動)
  • 1 台の Docker マシンに JMeter クライアント、残りに JMeter サーバーも手軽に出来そうな気がしてきた(異なる Docker マシン間での Docker Link 的な事が出来るのか引き続き試す)

ということで

  • ひとまず Docker Swarm with Consul のチュートリアルでした
  • あんまり Consul 関係無かった