BizSparkのAzure利用枠を有効に使ってDockerなインスタンスを飼う実験

2014年12月9日火曜日

この記事は、Azure Advent Calendarの8日目のものです。

昨日はjkudoさんのAzureでDockerな話(リンク)でした。

今日のエントリとして、プレビュー版が提供されているAzure Machine Learningの話を書いてみたのですが、信じられないほど中身がぺらっぺらだったので次回(Azure Advent Calendarの中でもう1度担当回あるのです)にして、今回はBizSparkのAzure利用無料枠を有効に使う話をします。
図らずも半分ぐらいはDockerベースの話です。2014年の半ばから終盤にかけて、どこを見てもDockerな日々でしたね。

さて、本日のエントリはたまたま運良くBizSparkのライセンスを持っていてLinuxサーバをそこそこ触れる方向けなので、対象読者はだいぶ絞られます。BizSparkのライセンス持ってねーよ!という方は、ざっと飛ばして後半の性能面の話をお読み下さい。




BizSparkのライセンスを持っていると、月間15,500円分のAzure利用権が付与されています(これはそのうち変わるかもしれません)。
Windows Phoneなどのアプリを作るにしてもWebサービスを作るにしても、とくに開発の初期には様々なミドルウェア構成を試作して組み合わせてみたいものですね。
実サービス段階になってもサービス規模が小さなうちは、そこそこ性能の良いインスタンスをひとつ立ててそこにDockerで複数のサービスを飼っておくのが便利です。

今回は、この枠に収まる範囲でほどよくバランスの良いDocker基盤を作ってみる試行錯誤録を紹介します。

まずは基本筋です。
BizSparkで利用できる月間15,500円の枠を有効に使うには、ひとまず定常的に利用するインスタンスの利用料金は10,000円/月程度に収めておくのがおすすめです。
Azureでは外部向けのネットワーク転送に対する課金がおこなわれるため、このためにある程度の額を残すのが良さそうです。
ここをカツカツにすると、後で停止したけどディスクを一時的に維持したいとか、何か実験をしたくなった時に手足を縛られた状態になるのであまりよくありません。
とはいえ大きな額をいきなり確保しておく必要はありません。外向きのネットワーク帯域は100GBで1,200円ぐらいなので、安全を見ても初期は100GBぐらい分の金額を想定しておけばいいでしょう。
この枠からあふれるぐらいのサービスになるケースのほうが稀なので、その時は半泣きで考えましょう。

これで月に3,000円ぐらいはあれこれとお試しができることになります。
新たに立ち上げっぱなしのインスタンスを用意するには心もとない額ですが、一時的に追加インスタンスを作ったり、モバイルサービスや多様なクラウドサービスを試したりする分には十分でしょう。

さて、前述のようにDockerでいくつかのサービスをホストしようと思うとA2(メモリ3.5GB、2コア、優先度高め)あたりが欲しくなります。
ここで気になるのは日本インスタンスの値段の高さです。
大体のクラウドサービスで日本リージョンの値段は概ね高め(理由を聞いてみるとだいたい「電気代が高いんですよねぇ…」と返ってくる)です。
日本(西)でA2インスタンスは結構お高いです。11,000円/月ぐらいします。
これだと少々予算をオーバーするので、地理的に近い場所のインスタンスで代替できないかを試してみました。

以下でhpingの元はいずれも石狩にあると思しきさくらのクラウドにある環境です。

日本(西)に立てたもの
[email protected]:~$ sudo hping3 -S -p 22 <host1>.cloudapp.net
HPING
<host1>.cloudapp.net (eth0 191.233.x.x): S set, 40 headers + 0 data bytes
len=46 ip=191.233.x.x ttl=51 DF id=0 sport=22 flags=SA seq=0 win=29200 rtt=32.7 ms
len=46 ip=191.233.x.x ttl=51 DF id=0 sport=22 flags=SA seq=1 win=29200 rtt=28.4 ms
len=46 ip=191.233.x.x ttl=52 DF id=0 sport=22 flags=SA seq=2 win=29200 rtt=32.5 ms
len=46 ip=191.233.x.x ttl=51 DF id=0 sport=22 flags=SA seq=3 win=29200 rtt=35.8 ms
len=46 ip=191.233.x.x ttl=51 DF id=0 sport=22 flags=SA seq=4 win=29200 rtt=27.3 ms

東南アジア(シンガポール)に立てたもの
[email protected]:~$ sudo hping3 -S -p 22 <host2>.cloudapp.net
HPING 
<host2>.cloudapp.net (eth0 168.63.x.x): S set, 40 headers + 0 data bytes
len=46 ip=168.63.x.x ttl=51 DF id=0 sport=22 flags=SA seq=0 win=29200 rtt=88.3 ms
len=46 ip=168.63.x.x ttl=52 DF id=0 sport=22 flags=SA seq=1 win=29200 rtt=91.9 ms
len=46 ip=168.63.x.x ttl=51 DF id=0 sport=22 flags=SA seq=2 win=29200 rtt=92.0 ms
len=46 ip=168.63.x.x ttl=52 DF id=0 sport=22 flags=SA seq=3 win=29200 rtt=91.6 ms
len=46 ip=168.63.x.x ttl=51 DF id=0 sport=22 flags=SA seq=4 win=29200 rtt=86.8 ms

東アジア(香港)に立てたもの
$ sudo hping3 -S -p 22 <host3>.cloudapp.net
HPING <host3>.cloudapp.net (eth0 168.63.x.x): S set, 40 headers + 0 data bytes
len=46 ip=168.63.x.x ttl=50 DF id=0 sport=22 flags=SA seq=0 win=29200 rtt=71.9 ms
len=46 ip=168.63.x.x ttl=49 DF id=0 sport=22 flags=SA seq=1 win=29200 rtt=72.0 ms
len=46 ip=168.63.x.x ttl=50 DF id=0 sport=22 flags=SA seq=2 win=29200 rtt=71.8 ms
len=46 ip=168.63.x.x ttl=50 DF id=0 sport=22 flags=SA seq=3 win=29200 rtt=72.3 ms
len=46 ip=168.63.x.x ttl=49 DF id=0 sport=22 flags=SA seq=4 win=29200 rtt=75.7 ms

日本はさすがの早さで、これと同レベルを海外リージョンへ求めるのはハナから無理とわかっています。
しかし想像よりも香港リージョンからの応答が早いですね。レイテンシが極端に問題となるようなことはひとまずAzureではやらない(それこそ、今なら小規模で価格とレイテンシ重視するならさくらのVPSかクラウドが強いです)ことにして、性能と値段のバランスが良い香港へ置くことにします。
さて、続けてDockerなお話です。ホスト側OSとしてCoreOSよりも普段から使い慣れたUbuntuを使いたい派なので、さっくりと通常のUbuntuインスタンスを立てます。

  • azureuserというユーザは放置して自分のユーザを作成
  • adminグループに追加してsudoできることを確認
  • .sshを掘ってauthorized_keys突っ込み
  • 同ディレクトリ丸ごとgoのパーミッションを落とす
 このへんまでは一呼吸でやります。
あとは多少セキュリティ上の懸念への対応。立ち上げたばかりのUbuntuインスタンスは、平然とSSHのパスワード認証がonになってるので設定を切ったりとちまちまやります。
/etc/init.d/ssh restart
では反映されないのでインスタンスごと再起動(force-reloadならいけたかもしらん)。

仕上げにlocaltimeを置き換えてtmux起動したらターミナルでの完結準備完了。
Dockerをインストールしていい感じにします。今回はDockerのインストールあたりは扱いません。
Ubuntuの場合はdockerではなくdocker.ioをインストールするのを忘れないように、ぐらいでしょう。

さて、Docker環境ができたら簡単にパフォーマンスを計測していきます。
Docker hubからイメージを拾ってくるのにかかる時間が体感的にさくらのクラウドの倍近くかかっていましたが、これはネットワーク環境差なのかVM性能差なのかいまひとつ読みきれませんでした(イメージの検証しながらダウンロードするはずだから、そこそこCPUも食いますし)。

今回は、ASP.NET vNextと呼ばれていたバージョンを使ってベアなHTTPリクエストへの返答パフォーマンスを見てみました。
用途によって計測の方法はがらりと変わるはずです。

Azure: A2インスタンス
[email protected]:~$ ab -n 50000 -c 200 http://localhost:5000/
This is ApacheBench, Version 2.3 <$Revision: 1528965 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Completed 25000 requests
Completed 30000 requests
Completed 35000 requests
Completed 40000 requests
Completed 45000 requests
Completed 50000 requests
Finished 50000 requests


Server Software:        Nowin
Server Hostname:        localhost
Server Port:            5000

Document Path:          /
Document Length:        11 bytes

Concurrency Level:      200
Time taken for tests:   23.722 seconds
Complete requests:      50000
Failed requests:        0
Total transferred:      5900000 bytes
HTML transferred:       550000 bytes
Requests per second:    2107.71 [#/sec] (mean)
Time per request:       94.890 [ms] (mean)
Time per request:       0.474 [ms] (mean, across all concurrent requests)
Transfer rate:          242.88 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    2   2.5      1      21
Processing:    16   93 112.2     77    1199
Waiting:       11   71 111.5     55    1150
Total:         19   95 112.3     79    1200

Percentage of the requests served within a certain time (ms)
  50%     79
  66%     87
  75%     93
  80%     98
  90%    118
  95%    169
  98%    199
  99%   1061
 100%   1200 (longest request)

さくら:(2Core-2GBプラン)
[email protected]:~/workspace/docker-asp.net$ ab -n 50000 -c 200 http://localhost:5000/
This is ApacheBench, Version 2.3 <$Revision: 1528965 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Completed 25000 requests
Completed 30000 requests
Completed 35000 requests
Completed 40000 requests
Completed 45000 requests
Completed 50000 requests
Finished 50000 requests


Server Software:        Nowin
Server Hostname:        localhost
Server Port:            5000

Document Path:          /
Document Length:        11 bytes

Concurrency Level:      200
Time taken for tests:   15.585 seconds
Complete requests:      50000
Failed requests:        0
Total transferred:      5900000 bytes
HTML transferred:       550000 bytes
Requests per second:    3208.27 [#/sec] (mean)
Time per request:       62.339 [ms] (mean)
Time per request:       0.312 [ms] (mean, across all concurrent requests)
Transfer rate:          369.70 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0  17.8      0     999
Processing:    13   62 127.6     44    3038
Waiting:        7   49 127.0     32    3024
Total:         13   62 128.8     44    3039

Percentage of the requests served within a certain time (ms)
  50%     44
  66%     52
  75%     57
  80%     60
  90%     67
  95%     81
  98%    168
  99%   1035
 100%   3039 (longest request)

さばけるqpsで1.5倍差をつけてさくらのほうが速いですね。
ここまで差がつくとは思っていませんでした。条件は互角にlocalhost計測なので、CPU差か与えられてるCPUスライス差が出ている格好です。

さて、AzureではD1かD2のインスタンスを使うと単コア性能が60%ほど引き上げられるようでよさげなのですがいかんせん高いです。
しかしBizSparkの利用権があれば(ry せっかく手軽に試せるのでひとまず試してみましょう。
2014年中は安めで使えるけど年をまたいで3割増しの値段になった時の処理が面倒なので、使うにしてもD1。メモリ量は同じなんだけどさてこれでいかほどいけるかな…。

Standard_A2での実行中top状態。
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                         
 3519 root      20   0  847312 368936   7208 S  77.6 10.5   2:27.17 docker.io                                                                                                      
 4408 root      20   0  216280 126232  13188 S  64.7  3.6   0:32.18 mono                                                                                                           
 4878 muo       20   0   34828   4688   1788 S  29.8  0.1   0:05.44 ab           

一方のさくら。
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                         
10574 root      20   0  230744 118476  13264 S  77.1  5.8   0:18.00 mono                                                                                                           
 1254 root      20   0 1268328  63928   6408 S  70.5  3.1  15:24.62 docker.io                                                                                                      
10826 muo       20   0   34828   3952   1856 S  23.9  0.2   0:01.12 ab       

傾向差はそこまで大きくありませんが、Azureだと概してDocker自体がCPUを食う割合のほうが高いですね。--net hostオプションを付けない状態なので、NAPTがかなり食っているようでした(このベンチをした時にはそもそも--net hostオプションを知りませんでした。図らずもDockerの苦手な箇所に特化したベンチになっています。つまり、ベンチの方法が悪い😇 CPUでの処理性能の傾向把握には役立ちますが、今度やり直します)。

AzureのD2インスタンスだとどうなるのかなーという話に戻ります。
価格は米国中南部がやたらと安いので、ワンチャンここにD2置いてどうにかやりくりいけないかな、というのはやはり気になるので試してみましょう。
本番利用向けの検証ではなく、あくまでも性能を確認したいという意味でのインスタンス作成です。


$ sudo hping3 -S -p 22 <host4>.cloudapp.net
HPING <host4>.cloudapp.net (eth0 23.102.x.x): S set, 40 headers + 0 data bytes
len=46 ip=23.102.x.x ttl=47 DF id=0 sport=22 flags=SA seq=0 win=29200 rtt=164.1 ms
len=46 ip=23.102.x.x ttl=47 DF id=0 sport=22 flags=SA seq=1 win=29200 rtt=156.1 ms
len=46 ip=23.102.x.x ttl=47 DF id=0 sport=22 flags=SA seq=2 win=29200 rtt=155.0 ms
len=46 ip=23.102.x.x ttl=47 DF id=0 sport=22 flags=SA seq=3 win=29200 rtt=151.7 ms
len=46 ip=23.102.x.x ttl=47 DF id=0 sport=22 flags=SA seq=4 win=29200 rtt=151.2 ms

うおお、さすがに遠い。
しかしDockerイメージの取得はさすがに速い。確かな近さ。

topはこんな感じ。
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                         
 3099 root      20   0  855488 412256   7204 S  66.7  5.8   1:19.15 docker.io                                                                                                       
 3931 root      20   0  223416 105700  13264 S  62.1  1.5   0:07.52 mono                                                                                                            
 3953 root      20   0   34828   3932   1840 S  26.8  0.1   0:01.92 ab    

結果。

[email protected]:~# ab -n 50000 -c 200 http://localhost:5000/                                                                                                                      
This is ApacheBench, Version 2.3 <$Revision: 1528965 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Completed 25000 requests
Completed 30000 requests
Completed 35000 requests
Completed 40000 requests
Completed 45000 requests
Completed 50000 requests
Finished 50000 requests


Server Software:        Nowin
Server Hostname:        localhost
Server Port:            5000

Document Path:          /
Document Length:        11 bytes

Concurrency Level:      200
Time taken for tests:   18.913 seconds
Complete requests:      50000
Failed requests:        0
Total transferred:      5900000 bytes
HTML transferred:       550000 bytes
Requests per second:    2643.73 [#/sec] (mean)
Time per request:       75.651 [ms] (mean)
Time per request:       0.378 [ms] (mean, across all concurrent requests)
Transfer rate:          304.65 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   6.5      0     997
Processing:    11   75 127.8     57    1089
Waiting:        4   58 127.0     41    1064
Total:         13   75 128.1     58    1090

Percentage of the requests served within a certain time (ms)
  50%     58
  66%     68
  75%     74
  80%     77
  90%     88
  95%     97
  98%    162
  99%   1053
 100%   1090 (longest request)


およ、あんまり向上してませんね。20コアのうち、その他のロールが2コアを持っていってる状態だったので、そっちがCPUがっつり使ってるのかもしれません。

念のためもう少し測る。
Requests per second:    2735.69 [#/sec] (mean)
Requests per second:    2803.95 [#/sec] (mean)
Requests per second:    2673.07 [#/sec] (mean)

こういう感じなので、Dockerベースで小さなサービスをいくつかホストしようという用途において、D2インスタンス利用はネットワークの遠さを受け入れてまでやるほどのことじゃないというのが今回の結論でした。

明日の担当はishisakaさんです。

0 件のコメント:

コメントを投稿