DockerとWeaveを使って1台のマシンでConsulを複数動かしてみる

軽くConsulを試してみたくて、でもVagrantで複数台仮想マシンを立ち上げるのはちょっと気が重い…ということでUbuntu14.10 on MacBookAirにDockerコンテナを複数立ち上げてクラスタを構築してみるテストをしました。

Dockerfileとか簡単な動かし方(を適当英語で書いたもの)をgithubにあげてあります

Docker内のプロセスがLISTENするポートに対してコンテナ外から接続する場合、-pでホストのポートにひもづけるか、--linkでコンテナ同士をつなぐのが最も手軽な方法です。が、consulは複数のポート(HTTP API用、DNS用、ゴシッププロトコル用等)を使うため、この手軽な方法でクラスタを構築することができません。

Dockerコンテナの接続パターンとしてはいくつかあって、deeeetさんのブログ記事に詳しく書かれています。

今回は手元のMacBook Airだけで完結させたかったので、weaveを使ったコンテナ間ネットワークを利用することにしました。

weave

dockerコンテナ間の内部ネットワークを構築するものです。詳しくはjacopenさんのSlideShareを。

使い方はとても簡単で、weaveコンテナを立ち上げて、weaveコマンド経由でdockerコマンドを実行するだけ。 これならVagrantのような仮想マシンのためにメモリとディスク容量を割く必要もなくなります。

1
2
3
4
$ sudo weave launch
$ sudo docker ps
CONTAINER ID        IMAGE                COMMAND                CREATED             STATUS              PORTS                                            NAMES
2eda921c011e        zettio/weave:0.9.0   "/home/weave/weaver    31 seconds ago      Up 30 seconds       0.0.0.0:6783->6783/tcp, 0.0.0.0:6783->6783/udp   weave

これだけで仮想ネットワークができあがります。ホストOSで必要なポートは6783だけです。

あとはweaveコマンドにIPを指定しつつdockerコマンドのオプションを付けて起動すればOK。

1
2
$ C=$(sudo weave run 10.0.0.1/24 -it ubuntu)
$ sudo docker exec $C -it /bin/bash

ただ、さくらVPSのCentOS6では動きませんでした。面倒なので深く追ってません。。。

1
2
3
4
$ sudo /usr/local/bin/weave launch
WARNING: Linux kernel version 3.5 or newer is required (you have 2.6)
ERROR: ip utility, iproute2-ss091226 does not support network namespaces.
       Please install iproute2-ss111010 or later.

consul

Hashicorp謹製クラスタのオーケストレーションツール。今更説明する必要もないと思うので詳細は省略します。 consul(と周辺ツールのconsul-templateやenvconsul)を使えば複数のホスト間で設定を共有できる、というのを試すのが今回の目的でしたが、とりあえず複数のconsulを動かすところまでを書きます。

consulを起動してクラスタを構築する

weaveネットワークに接続したコンテナを4台立ち上げて、consul1, consul2をserverとして、consul3, consul4をclientとして起動します。

1
2
3
4
$ sudo weave run 10.0.0.1/24 -it -v $(pwd -P):/opt --name=consul1 restartr/consul-ready
$ sudo weave run 10.0.0.2/24 -it -v $(pwd -P):/opt --name=consul2 restartr/consul-ready
$ sudo weave run 10.0.0.3/24 -it -v $(pwd -P):/opt --name=consul3 restartr/consul-ready
$ sudo weave run 10.0.0.4/24 -it -v $(pwd -P):/opt --name=consul4 restartr/consul-ready

あとはconsul agentを順に起動するだけ。

ここで注意するのが-bindオプション。 これを指定しないとdockerデフォルトのeth0のでクラスタにjoinすることになってしまい、このネットワークは他のコンテナとつながっていないためにクラスタ構築に失敗します。 必ずweave run 10.0.0.X/24で指定したIPにbindしておきましょう。

1
2
3
4
$ sudo docker exec -d consul1 consul agent -server -data-dir=/tmp/consul -bootstrap-expect 1 -bind 10.0.0.1
$ sudo docker exec -d consul2 consul agent -server -data-dir=/tmp/consul -config-dir=/opt/consul.d/web.json -bind 10.0.0.2
$ sudo docker exec -d consul3 consul agent -data-dir=/tmp/consul -config-dir=/opt/consul.d/web.json -bind 10.0.0.3
$ sudo docker exec -d consul4 consul agent -data-dir=/tmp/consul -config-dir=/opt/consul.d/web.json -bind 10.0.0.4

で、先に起動したconsul1に対して残りのコンテナ内のconsul agentをjoinさせていきます。

1
2
3
$ sudo docker exec consul2 consul join 10.0.0.1
$ sudo docker exec consul3 consul join 10.0.0.1
$ sudo docker exec consul4 consul join 10.0.0.1

と、consul membersでjoinしている一覧が見えるようになります。

1
2
3
4
5
6
$ sudo docker exec consul1 consul members
Node          Address        Status  Type    Build  Protocol
725dca3980ea  10.0.0.1:8301  alive   server  0.5.0  2
f82001d6a7b4  10.0.0.2:8301  alive   server  0.5.0  2
dcf304f77fdf  10.0.0.3:8301  alive   client  0.5.0  2
3be672bd18b1  10.0.0.4:8301  alive   client  0.5.0  2

クラスタから離れるときはconsul leaveです。

1
2
3
4
5
6
7
8
9
$ sudo docker exec consul4 consul leave
Graceful leave complete

$ sudo docker exec consul1 consul members
Node          Address        Status  Type    Build  Protocol
dcf304f77fdf  10.0.0.3:8301  alive   client  0.5.0  2
3be672bd18b1  10.0.0.4:8301  left    client  0.5.0  2       # <- Statusが'alive'から'left'に変わる
725dca3980ea  10.0.0.1:8301  alive   server  0.5.0  2
f82001d6a7b4  10.0.0.2:8301  alive   server  0.5.0  2

という感じで、複数のマシンをいじってる感じがまったくしないくらいweave & docker execは便利です。 weaveがプロダクション環境で使えるか、という点については未知ですが。

次回(があれば)consulを使った設定の管理について試したメモを書きたいと思います。

Peek - Railsアプリのプロファイリングツール

Peekという、Railsアプリケーションに組み込めるプロファイリングツール(群)があります。 How we keep Github fastでも言及されているツールです。(2012年なので少し古いですが。)

プロファイリングツールと適正

プロファイリング用のツールはたくさんあって、時間がかかる特定の処理を改善するために使うものもあれば、常時記録して特異な変化を監視するものもあります。

今回は後者寄りの要件であり、これに見合うものとしてPeekを取り上げました。

Railsでこれ以外のツールとしては、rack-mini-profilernewrelic/rpmなどがあり、それらについて今回の要件と照合してみました。

newrelic rpm

newrelicのサービス上で結果が確認出来るだけではなく、デベロッパーモードの場合に”/newrelic”にアクセスするとリクエストごとのプロファイル結果が見れます。 ただ、別途”/newrelic”のURLを開く必要があり、パフォーマンスチェックを忘れがちになる可能性があります。

rack-mini-profiler

トータルの処理時間は画面隅に表示されるけれど、個々の処理時間については画面隅のボックスをクリックして詳細を開かないといけません。

peek

Peekは適切な粒度で常に目に入れることができるツールであり、常用するのにちょうど良いのでは、という印象です。

先のGihtubのブログでは”Mission controll bar”いう、スタッフがプロダクション環境でも常にパフォーマンスを確認できる仕組みが整えられています。

Peekのしくみ

しくみは以下ブログ記事が詳しいです。

リクエストごとにIDを発行し、そのリクエストごとに各種計測値をデータストア(ファイル、Redis、Memcached等)に保存。 ページ表示後に別リクエスト(“/peek/…“)として非同期で計測値を取得して、画面の要素を置換する、というしくみ。

Peekの拡張

Peek自体はプラットフォームを提供するだけで、実際の個々の値を記録したりするのはそのプラグイン。

対応しているのはAvailable Peek views に記載されています。仮にほしいものが見つからなかったとしても、わりと手軽に追加できるような仕組みになっています。

ということでmemcached用のプラグインをつくりました。

evan/memcachedという、cで実装されたruby用memcachedクライアントがあって、それを使ったmemcachedアクセスを記録するプラグインです。

このプラグインではMemcached#getMemcached#setメソッドにモンキーパッチあてて、回数と時間を記録しています。

  • 呼び出し回数(calls)
  • 総処理時間(duration)

に加えて、下記も記録できるようになっています。

  • キャッシュヒット数(Get[HIT])
  • キャッシュミス数(Get[MISS])
  • キャッシュ更新数(Set)

Peekの惜しいところ

要素が増えるとブラウザの横幅に収まりきらなくなって、折り返し&はみ出します。本当に必要な要素に絞る抑止力にはなりますが、もう少しコンパクトに収められるとよりよいかな、と。