@IT編集部の西村賢がRuby/Rails関連を中心に書いています。

開発環境と本番環境の違いを埋めるHeroku、Engine Yardの新機能

»

 「でも、ステージング環境ではちゃんと動いています!」

 こう言われてブチ切れた経験があります。業務アプリのバギーな動作を社内のエンジニアに指摘したところ、テスト用の環境では動いているというのです。「いや、ぼくら本番環境のアプリを使っていて現に困っているので、それを直してほしいだけなんですけど」というと、「でも、ちゃんとステージング環境では動いています。お使いになっているのがChromeのようですが、Chromeでの動作検証はしていません(キリッ」というようなやり取りに絶望しました。原因はブラウザではなく、バージョンアップしたアプリ自体にあったのですが、ステージング環境では問題が発現しなかったんですね。

 というように、開発環境、ステージング環境、プロダクション環境(本番環境)の3つは、大小いろいろな違いがあって、完全に一致させることは難しいものです。手元の環境で動いているアプリが、プロダクション環境にデプロイしたらなぜか動かない、というような経験はアプリ開発者ならお持ちだったりするのではないでしょうか。

 「手元と本番でDBのバージョンが違ってて、マイナーバージョンの違いだから大丈夫だろうと思ったら挙動がビミョーに違ったし! うぎゃー」とか、「本番のデータだと負荷が高まったときに、このパッチでタイムアウトの例外が多発するようになっていた! ウキーッ」とか、「Rubyを最新のパッチレベルにしたら、実はマーシャリングのフォーマットが変更になっていて、DBをダンプしてリモート環境にロードするgemが動かなくなっていたよ! むぎゅぅ」とか、「サードパーティ製のJavaScriptがなぜかHTMLの最後にスペースを勝手に入れてくれていて、おかげでフッターのレイアウト崩れてたし! そんな忍びの術みたいなもん気付かんし!」とか、「手元では昔設定した環境変数を参照してたまたま言語設定がうまく動いているだけだった…… 本番は文字が化け化け! ていうか、DBのマイグレーション失敗だし、オレもう終電逃し確定だし!」とか、「動かねぇ……。うごご、本番環境はLinuxなのに、MacのUnixコマンドの出力前提に初期化スクリプト書いたの誰だよ! リバート、プリーズ!」とか、「ローカルのWebサーバはオッケーでも、サーバ上のNginxではリバースプロキシがRailsのBasic認証と相性が悪かった! サノバビッチ、スパシーバ!」

とか、そういうことです。

●12ファクターアップとは?

 こうした悲しい事態を避けるために必要となるのが、「開発・本番等価」という考え方です。できる限り、両者の環境を一致させろということです。

 「開発、ステージング、プロダクションをできる限り近づける」というのは、“12ファクター・アップ”が掲げるマントラの1つです。12ファクターアップというのは、ネット経由で配布・提供される現代のモダンなアプリ(ソフトウェア)が満たしているべき12個の原則を書きだした一種の宣言文のことです。12ファクターアップは、ちょうどアジャイル宣言のように、原則を並べた宣言文書なので、特定のプラットフォームや開発言語などを想定はしていません。ただ、この文書をまとめたのはHeroku創業者メンバーの1人、アダム・ウィギンズ氏で、Herokuプラットフォームの開発や、Herokuがホストする数多くのアプリケーションを観察していて到達した原則集ということですから、意地悪な見方をするとHerokuの宣伝文書、もしくは目標宣言のように読めなくもありません。例えば、アーキテクチャやツール、開発スタイルに大幅な変更を加えることなくスケールが可能なことというのは、HerokuのDynoを想起させます。スライダーバーをググっと上げれば、ハイ終わりという。実際、@ITが提供・運営しているQ&AサイトのQA@ITはHerokuで動かしていますが、.初期に想定以上のトラフィックが来たために慌ててDynoの数を2つから5つに上げた、ということがあります。

 ともあれ、やや宣伝めいたところのある12ファクターアップの文書ですが、これをまとめた背景に明記されているように、12ファクターアップという文書は、モダンなアプリ開発に関わる課題を論じるための「共通語彙」、もしくは「方法論」を定義するものでもあります。そういう意味では議論のスタートとしても良いものではないかと思います。

●「開発・本番等価」というルール

 どうやって開発・プロダクション環境の等価性を高めるのでしょうか?

 例えば、Web系開発者の間で、開発用端末としてMacが人気なのは、デプロイ先がLinuxサーバであることが多く、同じPOSIXならミドルウェアや言語処理系、ツール類で、ほぼ同じ環境が再現できることが挙げられると思います。iOS開発がプラットフォームを選ぶ(Macのみ)一方、Androidは何でも良いということも影響しているかもしれません。また、Linuxサーバで作業することが増えた結果、viやcurl、tailなどのコマンドラインツールの価値が見直されているというトレンドもあるように個人的には感じています。だったらなぜRuby on Rails開発者はあまりUbuntuを使っていないんだというツッコミもあるかもしれませんが、それは「設定がしたいんじゃなくて開発がしたいから」というのが1つの答えだと思います。

 さて、このブログに本論に移る前に、12ファクターアップの12の原則を和訳しておきます。

  1. コードベース:バージョン管理された単一のコードベース、多数のデプロイ
  2. 依存管理:依存は明示的に宣言して分離する
  3. 設定:設定は環境に保存する
  4. 補助サービス:補助サービスはリソースとしてアプリに付随させる
  5. ビルド、リリース、実行:ビルドと実行は完全に別ステップとして分離する
  6. プロセス:アプリは1つ、もしくは複数のステートレスなプロセスとして実行する
  7. ポートバインディング:ポートバインディングを通してサービスを露出する
  8. 並行性:プロセスモデルを使ってスケールアウトする
  9. 廃棄できること:速いスタートアップタイムと優雅なシャットダウンによって堅牢性を最大化
  10. 開発・本番等価性:開発、ステージング、本番をできる限り近づける
  11. ログ:ログはイベントストリームとして扱う
  12. 管理プロセス:管理者・管理のタスクは、(起動して実行したら終了する)1回きりのプロセスとして走らせる

 Rails開発者なら、ああ、1はGitのmasterのことだな、2はGemfileだななどと思うかもしれませんが、ほかのフレームワークでも似たような仕組みがありますよね。6~8番あたりはUnicornを思わせますが、いやいやプロセスじゃなくてスレッドが答えだという人たちもいることでしょう。そういえば、大量のUnicornが走っている某社のRailsアプリでは、個々のUnicornの寿命が数分という話を聞いたことがあります。メモリリークがひどくて、少し動かすと反応しなくなるので、ガンガン殺してまたリスタートさせるという話です。これは6番の極端な例かもしれません。外部からそのアプリにアクセスして見ている分には、別に問題なく動いているように見えるということです(現場の人には当然それが良いという認識はなく、何とかしないと、という話でした)。

●Herokuが「データベースのフォーク」を実現

 さて、12ファクターアップという文書は洞察に富んでいるので、一読の価値はあると思うのですが、ここでは開発・本番等価性の話をしたいと思います。

 というのも、HerokuとEngine Yardが、前後して開発・本番等価性を高める新機能をリリースしたからです。それぞれに見ると、「へぇ、便利」という程度のことかもしれませんが、ともに12ファクターアップがうたうモダンな開発スタイルを前進させる「PaaS進化の最前線」だと思うからです。

 1つは、2012年11月8日にHerokuがリリースしたデータベースのフォーク機能です(Herokuの関連ブログ)。Herokuが指摘するとおり、GitとGitHubは「フォーク」(分岐)という、時としてネガティブなニュアンスさえあったアクションを、この上なくカジュアルに手軽にしてしまいました。Gitでブランチを切るのはSHA-1の生成と、その40バイトのデータのファイルへの書き込みだけなので動作としても一瞬です。分散レポジトリなので名前の衝突問題も小さく、ガンガン好きなだけブランチが作れます。GitHub以前は“フォーク”といえばコードの所有権やコミットの場(リポジトリ)、その主体がある日を境に分岐するという話でした。意見や目的意識の違いや、開発者間の仲違いによってフォークは起こりました。しかし、GitHubでは、フォークはもっと気軽なもので、別の意味も帯びています。とりあえず、自分のところへコードベースを持ってきて、そこで何か作業をして、その結果を元へ戻すというようなときにフォークしてしまいます。こうすることで、いきなり本家のレポジトリでブランチを切ったりすることなく自由に実験的な開発とコミットができるのです。これはGitがもともと持っているDVCの性質ですが、GitHubはボタン一発でフォークできる手軽さを実現したところがスゴイと思います。

 Herokuがリリースしたデータベースのフォーク機能も、GitHubのフォークに近いニュアンスです。HerokuはPostgreSQLをサービスとして提供していますが、本番環境のデータベースをボタンのワンクリックでフォークできるようになりました。例えば、本番環境のデータを、ステージングへとクローンすれば、「ステージング環境ではマイグレーションが通ったのに本番環境で失敗した」ということが減るはずです。負荷テストをするにしても、本番環境のデータをフォークして流用すれば精度が高いでしょう。ステージングのほうのデータベースは、検証が終われば破棄すればよく、使った分以上に課金されることもありません。クラウドっぽいですね。

 データベースのフォーク機能は、また一歩、12ファクターアップを体現した機能と言えると思います。GitHubのフォーク機能と同じで、「それ、これまでにもダンプしてロードすればできたやん」という議論があるかもしれません。でも、ちょっと違うと思うのですよね。ボタン一発(あるいはCUIのコマンド一発)でできる手軽さがいいのだと思います。

●Engine Yardは仮想環境向けの開発環境を提供

 さて、もう1つ。

 Herokuの競合であるEngine Yardは「Engine Yard Local」を2012年11月16日に無償でリリースしました。Engine YardはRailsやNode.jsの開発環境として、ミドルウェア、フレームワークを全て含む独自のスタックを提供していますが、これをローカルの仮想環境で動かすことができるそうです。仮想環境に開発環境をセットアップする「Vagrant」と、OSSの仮想化ソフトウェアの「VirtualBox」を組み合わせてEngine Yard Localは実現されています。Engine Yard Localを使うと、同社のクラウドインフラと同様のOS、Webサーバ、アプリケーションサーバ、ロードバランサなどが手元に再現されます。

 Vagrant(ベイグラント:意味は「放浪者、浮浪者」)の公式サイトに行くと、ズバリ「開発・本番等価」という言葉が書いてあり、12ファクターアップのサイトへのリンクが貼られています。いまや本番環境では、DBサーバだけでなく、0mqのようなメッセージングサービスが動いていたり、Redisのようなインメモリのキャッシュクラスタが動いていたりするわけですが、いくらMac OS Xが「POSIXだから、まあ動きますよ」と言っても、こうした個別のアプリ依存のソフトウェアをMacPortsやHomebrew、あるいは手動で手元のマシンにインストールして設定・管理するのがだんだんつらくなってきているように思います。特に複数アプリに関わっていて設定の切り替えが必要だと絶望的になるのではないでしょうか。

 最近のマシンは高速なので、開発環境は、それ専用の仮想環境に入れてしまえばいい、というのがVagrantの発想です。確かにスッキリ! サーバ側と全く同じ環境を実現! すばらしい! もうMacPortsじゃなくて、apt-getでいいんや! とも思えますが、もちろんマイナス面もあります。

 例えば、現実の開発者というのは、熱風を吹き出しうなり続けるMacBook Airをなだめすかしたり、ぐるぐる回る虹色バルーンを呆然と見つめながらメモリ2GBのマシンで開発していたりするわけです。そういう環境で「仮想環境にOSとミドルウェア一式をぶち込めば万事解決!」と言われても、そんな重たそうなもの……、何のために軽快な動的言語やviを使ってるのかワカランぞということになりかねません。なんだかんだ言ってPC上ではゲストOSは二級市民です。ゲストOSが動いていると、なぜかホストOSのレジュームが失敗して、延々と黒い画面を見つめて祈った経験があるという嫌な思い出がある人もいるかもしれません(私ですが)。

 Vagrantでは、IaaSにおけるChefのように、ローカルの仮想環境に対してChefやPuppetが使えるそうです。「ちょっと手元にHadoopクラスタを作って実験してみたい」というような用途でも使われているといいます。あるいは、チーム開発の場合でも新メンバーに対してMacBook Proを買い与えて「さあ、以下の手順に従ってRuby、Rails、Postgres、Redisあたりを入れてください。おっと、PostgreSQLは以下のエクステンションのビルドも忘れずに」とやるよりも、仮想環境にポコンとその開発環境を再現できるようにVagrantを使うほうが良いかもしれません。

 Engine Yard Localは、Virtual Boxを前提としたVagrantの設定レシピ+CLIツールということですが、無償で利用できるので、これまで「Engine Yardのスタックって試してみたいけど、Herokuと違って無償で手軽にというのがないしなぁ」と思っていたRails開発者にとっては、試用してみるいい機会かもしれません。気に入らなくても、スッキリと跡形なく消せるのも仮想環境を使うメリットですよね。もしかすると、これからRuby on Railsの開発をやってみたいという開発者にとっても、「とりあえず全部入りのRails開発環境を作ってくれる選択肢」として、Engine Yard Localは使えるかもしれません。RubyもRailsも、バージョン管理ツール、ライブラリ管理ツールなどの周辺ツールの知識が結構必要で、とりあえずやってみたい人にとってそれがハードルになっているようなことがあると思うのですよね。

●継続的デリバリー実現のためにPaaSは進化中

 ずいぶん長々と書いてきましたが、HerokuもEngine Yardも、ともに「開発・本番等価」という課題に取り組んでいて、これは偶然の一致ではなくPaaS市場のトレンドと言えそうです。次のステップは開発環境がクラウドに移る(元々のHerokuの事業はそうでしたが)ということかもしれませんが、ネットワークのコネクティビティの問題が解決しない限りはそれはなさそうです。

 言うまでもないかもしれませんが、「何のために開発・本番等価を目指すのか?」ということですが、それはアジャイル宣言の背後にある原則の先頭に書いてあるとおり、「価値のあるソフトウェアを早く継続的に提供します」という“継続的デリバリー”の実現のためかと思います。

Comment(0)

コメント

コメントを投稿する