tech.guitarrapc.cóm

Technical updates

Disposable にする時に考慮するべきこと

先日neueccと話していて「サーバーをDisposableにする時って何が問題になるの?」

といわれたので、その時に答えた内容を備忘録も兼ねて。

Disposable にするとは

まずコンテキストを合わせるために、Disposableをどう考えるかです。

Disposableというからには、破棄するわけです。何をか? というと、この文脈では「サーバー」が対象です。

そこで、ここでは以下をDisposableな状態とします。

サーバーをいつでも捨てられる、再構築できる状態にし運用する

なるべくOSを問わないように考えていますが、前提はWindowsでも。とします。

なぜDisposableにするのかは、散々議論になっているのでこの場では触れません。Chefに面白い記事があるので、参考にどうぞ。

https://www.getchef.com/blog/2014/06/23/immutable-infrastructure-practical-or-not/

捨てられるサーバーと捨てられないサーバー

では、全サーバーをDisposableにできるのか、捨てられるのかというとそうではありません。捨ててもいいサーバーが捨てられると考えています。

サーバーを捨てるということは、そのサーバーが持っていた情報を捨て去るということです。情報とは、そのサーバーに施されていた設定/構成、状態、ログ、データなど全てです。

つまり、そのサーバーにあるデータがすべてなくなることを許容できるサーバーのみが対象となります。

よくあるWebアプリケーションのサーバー役割ごとに考えると、次のように大雑把に分類できるでしょう。*1

役割 データの維持が必要かどうか
DBサーバー
Cacheサーバー 要(場合による)
Webサーバー 不要
プロキシサーバー 不要

捨てられないサーバー

共通しているのは、状態をもっている = Statefull であるということです。

  • データ/サービス状態の保持

DBやCacheは、サービスの要となるデータを維持しています。サービスデータ、状態がここに集約しているといえるでしょう。このサーバーを消すということはありえません。

Cacheは微妙です。通常はDBのオーバーヘッドが大きいため、頻繁に参照する情報をCacheにつめてDBに変化がない限りはCacheを参照するようにするのが多いでしょう。この場合は、データの本体はDBにあるのでCacheが消えてもデータの本質は失われていません。とはいえ、サービス上はCacheを含めてパフォーマンス計算されているでしょうから、Cacheを作りなおしてデータをつめなおすのは少しコンテキストがずれた話になります。そのため、ここではCacheはStatefullなサーバーであると見なそうと思います。

捨てられるサーバー

共通しているのは、状態を持っていない = Stateless であるということです。

  • リクエストの仲介

Webサーバーもプロキシサーバーも、リクエストを仲介することが本質です。

プロキシサーバーであれば、アップストリームからのリクエストをルールに基づき適切なダウンストリームに分配、返却する役目。

Webサーバーは、リクエストをWebアプリケーションで処理し、適切に応答する役目。

このように、リクエスト処理をアプリケーションで行うものの、必要に応じてDBやCacheに問い合わせはしても状態を維持することはありません。

  • スケーラブル

スケーラブルに同一の構成でサーバーを展開しているのも特徴といえるでしょう。Webサーバーは1台ではなく、数台、数十台、数百台.... とどれだけあってもどんどんスケールが容易です。

サーバーを捨てる時の問題点

考えやすいようにWebサーバーを例にとって、何がサーバーをDisposableにするときに問題になるのかを考えてみましょう。

ログ

捨てられるサーバーとはいえ、何も情報を持っていないわけではありません。

リクエストログ (IISやApache/nginx)、アプリケーションログ、イベントログ(/var/log/security, /var/log/message) などは代表的かつ重要な情報です。とくにリクエストログやアプリケーションログはサービスの健全な運営には必須といえるでしょう。

「サーバーを捨ててもログは維持するのか?」あるいは、「随時ログを外部に集約するのか」を選択することになるでしょう。

fluentd や Semantic Logging Application Block を使うと、外部にログを集約することが容易になり、Webサーバーからまた1つ状態を取り除くことができます。

http://slab.codeplex.com/

http://www.fluentd.org/

集約したログを任意で投げ分析するには、BigQueryRedShiftなどが有力でしょう。

https://cloud.google.com/bigquery/?hl=ja

http://aws.amazon.com/jp/redshift/

もしデータ解析のUI提供まで含めたサービスがいい場合は、Sumo LogicSplunkがありますね。

http://www.splunk.com/

http://www.sumologic.com/

OS構成の自動化

WebサーバーがWebサーバーとしてあるべき状態で動くためには。当然ですがOS設定が必要です。

どのようにそのサーバーを構成、設定していますか? 手動でGUIなどからマウス操作で作っていたら? 恐怖です。同一サーバーを作ろうと思っても、人間の手が操作に混じるので何か抜けることがぬぐえません。だって人間だもの、Shoganai。

しかし、構成がどのサーバーも同一であれば? コードにすることで、あるべき状態をプログラマブルに明確にとらえることができます。

Infrastructure as Code は、インフラを暗黙知から形式知に、構成の修正、反映を自動化する前提となります。

わかりやすいのは、Ito Naoyaさんの記事や資料ですが、多くの方が先例を示してくれています。

http://d.hatena.ne.jp/naoya/20131215/1387090668

さらに、GitHubにPushで、CIしてテストしてデプロイ。ここまで来れば安心できて気分が楽ですね。

OS状態の維持

構成が仮にコードにできたとしても、Webサーバーがあるべき状態になっていることを保証してくれないと怖くないでしょうか?

一度PowerShell(あるいはCapistranoなど)で構成を組んだら、それで終わり?

あるいはあるべき状態を指示して、その状態に維持し続ける?

Configuration Management Tool で、あるべき状態に収束するということは、そのサーバーの状態を自動的に構成し、維持してくれます。

これは、サーバーがDisposableだからといって変わるものではありません。

現在なら、DSC、Chef、Puppet、Ansibleなどなど多くの仕組みがあります。

http://www.atmarkit.co.jp/ait/articles/1405/22/news131.html

http://www.ansible.com/home

https://www.getchef.com/chef/

http://puppetlabs.com/

デプロイ

デプロイなど、複数のインスタンスに操作が必要な場合は、Orchestration Toolが必要になります。

Capistranoやvalentiaはデプロイだけでなく、複数サーバーへの並列なコマンド実行をサポートします。AppRollaはデプロイを助けてくれるでしょう。

https://github.com/capistrano/capistrano

https://github.com/guitarrapc/valentia

https://github.com/appveyor/AppRolla

また、SerfやConsulは、Disposableにしていても、いいようにホストの生存を管理しサービスとして成り立たせてくれます。

https://github.com/hashicorp/serf

http://www.consul.io/

クラウド構成の自動化

Disposableにするという話は、サーバーをクラウドで展開していると特に良く聞く話です。

http://aws.amazon.com/jp/

http://azure.microsoft.com/ja-jp/

https://cloud.google.com/

サーバー調達が容易で、時間課金なのもそうでしょうが、Disposableにする上で大事なのが、API によるサーバー調達の自動化です。

Amazon Web Service (AWS) にしても、Microsoft Azureにしても、Google Computing Cloudにしても必ずAPIとSDKがあります。

http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/available-apis.html

もし自動構成のサービス(AWSのAutoscalingなど) がない場合にクラウドの構成を自動化する時は、プログラムからAPIコールするのが手早く簡単でしょう。これにより、任意でサーバー自体を他のサービスと連動させることができます。

もちろん、サービスに任せられるなら、さらに他サービスとの連携もできるので任せるのがいいと考えています。

クラウド構成のカプセル化

クラウド上でサーバーを管理する上で、物理と変わらないのがIPやタグなどクラウド構成が重複しないようにすることです。

でもそんなの管理せず自動的にやってほしいですよね?

これには、AWS AutoScalingに任せるか、APIである程度作りこむことが必要になります。

クラウド構成をうまくカプセル化できれば、

scale web:80

など、スケーリング結果を指示するだけで簡単に構成されることもできるようになります。

破棄/構成速度

Dockerが流行ですね。ただし、このDisposableのコンテキストでは、欲しいが必須ではありません。欲しい理由は、速やかに破棄、構成するためです。*2

一日に何度もデプロイするのに、1回に一時間もかかっていられないのです。

コンテナ仮想化の詳細は不要でしょうが、AWSにおいてWindowsサーバーをAPIコールしてイメージからインスタンスを作成、必要な構成が終わりサービスに投入までは15分余りかかります。

この内90%は、カスタムイメージからのインスタンスの起動に時間を費やしており、より高速に起動することが求められます。Windowsはこの点において、圧倒的に不利です。もぉ。

まとめ

軽いメモのつもりが長くなりすぎたのでここまでで。

  • ログ
  • OS構成の自動化
  • OS状態の維持 ー デプロイ
  • クラウド構成の自動化
  • クラウド構成のカプセル化
  • 破棄/構成速度

これらが、Disposableに運用したいと思った時に障害となるだろうポイントかなぁと思います。

他にもあった気がしますが、なんだっけ。

*1:サービス形態によっては、当然同じではありません

*2:本質はリソースの最適化ですが、ここでは触れません