hogepiyoエンジニアリング

トラブルシューティングからノウハウ、作ってみた系まで扱う情報系ブログ

Docker(とその他ツール)でつくるなんちゃってオートスケーリングシステム

最近dockerが流行ってきてて自分もdocker使ってなんかやりたいなーと思ってなんちゃってオートスケーリングシステムを作ってみた。

全体図

最初にざっと全体図
システム全体の概要はこんな感じ
f:id:marshi:20140706143545j:plain

ツールの役割は以下のとおり。ちなみにOSはCens OS

役割 ツール 今回使用したバージョン
Load Barancer HAProxy 1.4.24
リソース管理 Mesos 0.19.0
仮想マシン Docker 0.11.1
負荷監視 Zabbix 2.2

簡単にいうとZabbixでDocker上で動いているサーバの平均CPU使用率を監視して、負荷が一定以上になったらサーバを増加、一定以下になったらサーバを減少させる。
どの物理サーバに新しいdockerコンテナを作成するかはMesosに任せる。

各部品の説明

HAProxy
webサーバのロードバランサー
設定ファイルにIPを追加することでバックエンドサーバを増やせる。
お手軽なので今回はこれで。

Mesos
物理サーバで構成されたクラスタから空いているリソースにジョブを依頼できるツール
Mesos Masterに依頼することでMesos Slaveサーバの中から空いているリソースを提供してくれる
全体図中のMarathonはMesos経由で永続的なジョブを走らせるためのMesos Frameworkというものらしい

Docker
いわずもがな

Zabbix
リソース監視ツール
監視対象のリソースの使用状況をトリガにして任意のスクリプトを実行させることができる

構築手順

ツールそのものの導入については割愛
Mesosの導入についてはsonots:blogさんの下記エントリが詳しい。実際かなり参考にさせていただきました。
http://blog.livedoor.jp/sonots/archives/35421955.html
http://blog.livedoor.jp/sonots/archives/35451869.html

ZooKeeperの起動(sonots:blogより引用)

# cd /path/to/mesos
cd 3rdparty/zookeeper-3.3.4
cp conf/zoo_sample.cfg  conf/zoo.cfg
sudo ./bin/zkServer.sh start
cd -

Mesosの起動

cd mesos/build/
bin/mesos-master.sh --zk=zk://{zookeeperのサーバIP}:2181/mesos --work_dir=work_dir --quorum=1
bin/mesos-slave.sh --master=zk://{zookeeperのサーバIP}:2181/mesos --isolation=cgroups/cpu --cgroups_hierarchy=/cgroup/cpu --ip=${slaveサーバ自身のIP}

Marathonの起動

cd marathon
bin/start --master zk://${zookeeperのサーバIP}:2181/mesos --zk_hosts ${zookeeperのサーバIP}:2181

Zabbixの設定(これが一番めんどくさかったりする)

監視対象(アイテム)の追加
設定 -> テンプレート -> テンプレートの作成 から新規テンプレートを作成
テンプレートを作成したらテンプレートからアイテムに移動して、各サーバのCPU負荷を監視するためのアイテムの追加を行う
このとき、zabbixトラッパーにしておくことで、zabbix APIを使って送信された値をZabbixで受け取れるようにする
f:id:marshi:20140706160615p:plain

さらに、各サーバのCPU負荷の平均を監視するためのアイテム追加を行う。
これにはZabbixアグリゲートを指定する
f:id:marshi:20140706160937p:plain

トリガの追加
さらに、CPU負荷に反応するためのトリガを設定
CPUが30%以上の場合と15%以下の場合に反応するようなトリガをつくる
f:id:marshi:20140706162741p:plain
f:id:marshi:20140706163007p:plain

アクションの追加
トリガの条件を満たしたときに実行するアクションを設定する
CPU使用率30%を超えたときにはスケールアウト、15%を下回ったときにはスケールインするスクリプトを実行するように設定する
スクリプトについては後述

スクリプト

作ったスクリプトについてざっと説明。

https://github.com/marshi/autoscaling

cpu.sh
dockerコンテナ上で動作する仮想マシンCPU使用率を取得する。
引数としてコンテナIDを指定することで該当コンテナ上の使用率のみ取得する。
http://qiita.com/marshi@github/items/e8db79c43abf2fca8d72
ちなみにDockerのメトリクス収集に関してはつい昨日参加していた"Docker Meetup Tokyo #3"で@stanakaさんがお話されていた。「タイムリーな話きた!これでqiitaのストックも伸びる!」とか思ってたら全然そんなことなかった。世の中甘くない。

send_zabbix_cpu.sh
zabbixサーバからクラスタのコンテナID一覧を取得し、cpu.shを使って各コンテナ上のCPU使用率を取得したうえでzabbixサーバへ送信する。
各ホストサーバ上で定期実行する必要がある。

send_node_num.sh
クラスタ上で動作する仮想マシンの台数をMESOSから取得し、zabbixサーバへ送信する。
いずれかのサーバ上で定期実行する必要がある。

zabbix_host.sh
docker eventによって、dockerの起動の検知とHAProxyへの登録、docker終了の検知とHAProxyからの削除を行う。
各ホストサーバ上で常時起動しておく必要がある。

scaleout.sh
実行するたびにクラスタ上のサーバ台数を1台増やす。
zabbixで負荷が閾値を超えるとこのスクリプトを実行する。

scalein.sh
実行するたびにクラスタ上のサーバ台数を1台減らす。
zabbixで負荷が閾値を下回るとこのスクリプトを実行する。

動作確認

Zabbixの監視対象にDockerで作ったサーバのノード数も追加して、CPU平均使用率とノード数を見てみた
CPU使用率にまぁ追随してそう
f:id:marshi:20140706164455j:plain
ただし、実行条件をチェックするタイミングによっては過剰なノード数の増加・減少が発生しているため、タイミングの調整やノードの下限の設定などが更に必要そう。

まとめ

Docker、Zabbix、Mesos、HAProxyを使用してオートスケーリングシステムの構築をしてみた
実際の動作確認ではCPU使用率の増減に応じてクラスタのノード数も増減していることを確認できた
ただ、調整の必要がある点として、CPU使用率に対する極端なノード数の増減、最低動作台数の保証がありますね
さらに、各スクリプトを手動で実行する必要があるので、これらを包括的に管理・実行するための仕組みも用意できればなおよし

オートスケーリングって監視間隔が短くないとスパイクに対応できないし、かといって監視間隔が短すぎるとロードバランシングされて負荷が減少する前に一気にノード数が増えそうだし、どういう監視の仕方がいいんでしょうね。
リソースが潤沢にあるなら別に短い間隔で監視して増え過ぎたら後で減らすッて感じでもいいんでしょうけども。

あと最近知ったけどflynnっていうのがあってそれで今回つかったMesosとか置き換えられるんじゃないのかーと思ったり。むしろオートスケーリングがもっと簡単にできるんじゃ・・と思ったり。
ちょっとした絶望感を覚えつつも触ったことないものにいっぱい触れる機会を持てたからいいかと前向きに捉えることにする。