タイトルの英語綴りが正しいか気になる。
tl;dr
JMeter のクラスタ構成を Docker でなんとか出来ないかなと思ったら Docker Swarm というものがあるらしいのでチュートリアルしてみた。
Docker Swarm とは
参考
イメージ
Docker Swarm とは複数 Docker ホストをクラスタリングして個々の Docker エンジンを一つの Docker エンジンとして扱えるツール(という認識)で以下のようなイメージを頭に描いた。
チュートリアルしてみて上記のイメージは大体合っている気がしたが、実際に構築する場合には以下のように swarm クラスタ内には swarm manager という役割を持ったクラスタの master ノードが必要になる。
swarm manager となるノードについてはクラスタのオーケストレーションやコンテナのスケジューリングを行う役割がある。
バックエンド
クラスタ構成やコンテナ内のサービスを動的に管理する為に etcd や Consul や Zookeeper 等を利用することが出来るとのこと。(Docker Hub も利用出来る)
フィルター
コンテナのスケジューリングに以下のようなフィルタを利用することが出来る。
- Constraint
- Affinity
- Port
- Dependency
- Health
例えば、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 ノード上で起動している。
チュートリアル
やること
- Consul の起動
- docker-machine を利用して swarm クラスタ用の VM を VirtualBox 環境に起動する
- swarm クラスタが構成されていることを確認する
- swarm クラスタ内にコンテナを起動してみる
チュートリアルの環境
# 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 関係無かった