Hatena::ブログ(Diary)

naoyaのはてなダイアリー

December 04, 2013

ポータブルなWebアプリケーション

140文字で書ききれなかったのでブログに殴り書き。

Heroku のアプリケーションを人に渡す

昨日、「naoyaさんが作ってるiOSアプリのバックエンドサーバーに相乗りさせてもらえないか」という話をいただいた。自分でも同じようなAndroidアプリを作っているけど、サーバーサイドは作ってないからということらしい。

対して「githubにコードあるからgit cloneしてheroku pushすれば動くし、自分で heroku にデプロイしてよ」と応えた。相乗りしてもらってもよかったのだけど、こちらでコードを書き換えたりメンテしたときに先方のアプリが停止することを考えると同じコードベースでサーバーは自分で立ててもらう方が何かと良い。

対象になったソフトウェアは Heroku で動かしていたので、Heroku Ready な形、つまり、必要な外部パッケージの一覧やサーバーの起動手順なんかはすべてプログラマブルに構成されていて・・・大袈裟に言ってるけど要するに Bundler に gem 一覧を書いて Procfile にコマンド引数が書いてるってこと (実際は Node.js だけど) になっている。だから、そのソフトウェアを動かすのに「これこれこういう手順で〜」と説明しなくても、"git push heroku master" すれば OK ですよ、で済む。

Heroku を使ったことがある人なら分かる通り、Heroku は git push するだけでアプリケーションのデプロイが可能だが、その都度、内部では新しい環境・・・ コンテナを立ち上げてアプリケーションを構成し直し、準備が整ったら古いコンテナは廃棄され、新しいものがトラフィックを受け取る、という仕組みになっている。

従って、Heroku で動かす Web アプリケーションはこの仕組みで廃棄されたり、新しく立ち上げ直すことができる前提で作る必要がある。必要があるというか、Heroku のアーキテクチャ側から Web アプリケーションをどう構成すべきかということが自動的に決まる。すなわち、アプリケーションがポータブルになるよう構成させられることになる。ただし、Heroku は特にこの辺りで独自仕様を要求してくることはなく、Ruby であれば Bundler や Foreman を、Node.js であれば npm をと行った形で各プラットフォームでデファクトスタンダードな道具を使って構成すればよい。

結果的に、Heroku のアーキテクチャが Webアプリケーションのポータビリティを要求し、それによって、冒頭のケースのように、他人に Webアプリケーションをそっくりそのまま渡すという副次的な利益が得られている。この Webアプリケーションのポータビリティは、そっくりそのまま同じ物がすぐ構成できるということで、例えばサーバーを自動でスケールアウトしたいとか、そういうときに威力を発揮するし、同じ Web アプリケーションを Heroku で動かすのではなく Test as a Service、例えば Travis とか Circle CI のようなクラウドサービスに放り込んでテストしてもらう時の前提にもなっている。

Immutable/Disposable Infrastructure

Immutable Infrastructure、あるいは Disposable Infrastructure という考え方が昨今話題だ。

Webアプリケーションサーバーのように状態を持つ必要がないサーバーは、それが状態を持たないということを制約にし、いつでも廃棄可能であるという前提で扱うと運用コストが下がり、いろんな可能性が見えてくるよという議論。昨今のプロビジョニングフレームワークや DevOps への注目の集まりとか、そういうものの集大成としての概念、ということもあって盛り上がっている。

いま Immutable Infrastructure について議論したり、何かを作ったりしている人たちというのは基本的にクラウドサービスの裏側、あるいは多数のサーバー運用をしている大規模 Web サービスの裏側の人たちが主だったところである。(自分も含め) 彼らには、彼らが日々管理しなければならない大量のサーバーあるいはインスタンスの運用コストを下げることにとても強いモチベーションや経済合理性がある。

一方、単に自分の Web アプリケーションを動かすサーバーがあればそれでいい、というようなもう少しエンドよりのデベロッパーにとってはどうか。まだ、いまいちピンと来ていないかもしれない。そういう人は Immutable Infrastructure 的なインフラが実現された後の世界のイメージとして、Heroku を想像しておけばいい。

Heroku に git push するデベロッパーから見た場合、Heroku で動かしているアプリケーション環境はデプロイの度に廃棄されるし、紛れもなく Disposable Infrastructure である。Heroku のインフラストラクチャが廃棄される前提という制約が、そこで動かす Web アプリケーションにどういう副次的利益を及ぼすかということは先に見た通りである。

Docker

Immutable/Disposable Infrastructure を実現するミドルウェアとして注目が集まっているのが Docker (https://www.docker.io)。Docker は LXC と AUFS を組み合わせて Heroku のような PaaS バックエンド、すなわちコンテナ型の仮想環境をカジュアルに運用維持できるようにするソフトウェアだけれども、最近 RHEL に搭載されたかと思いきや、つい昨日、Google Compute Engine が一般公開とともに Docker サポートを発表 したりして、非常に勢いがある。Docker 面白いなと思っていた自分も、まさかこんな勢いで普及するとは思っていなかった。

Docker の重要な特徴に、Docker コンテナとして構築したアプリケーションは、そのままイメージとしてエクスポートして別のホストに持っていって、Docker コンテナとしてそっくりそのまま再度立ち上げることができる、というものがある。これも Immutable/Disposable Infrastructure の文脈で語られる機能というか、その辺の制約が前提となって実現された機能である。

Google Compute Engine のような大規模クラウドプラットフォームが Docker をサポートしたということは、例えば自分の手元の OSX 内の Vagrant で立ち上げた VM で動いていた Docker コンテナを、ある日大規模計算リソースが必要になったからとかそういう理由で、Google のクラウドに移して動かすなんてことが、デベロッパから見た場合にほぼノーコストで実現できる、ということである。これもアプリケーションのポータビリティという文脈で考察すると色々と面白い。単に自分のアプリケーションの動作環境をスケールアップということに留まらず、他人にアプリケーションを配布するとか、Test as a Service その他よりレイヤの高いクラウドサービスに放り込むとか、いろんなユースケースが考えられる。

Webアプリケーションを配布する ・・・ Movable Type

ところで、Webアプリケーションを配布するというと自分が思い出してしまうのは、10年前のブログブームの火付け役になった Movable Type というブログツールである。Movable Type は Perl で書かれたサーバーインストール型のソフトウェアで、ダウンロードして自分のサーバーに自ら設置して動作させる必要があった。当時は周囲のブログツールに比較してずっと高機能かつ洗練されていたので、Movable Type を動かしたいがために、慣れない Linux サーバーと悪戦苦闘するエンドユーザーが大勢いた。

Movable Type よりもずっと前から、例えば掲示板やアクセスカウンターのようなスクリプトなんかをインターネット上で配布して、「プログラムは配布するから自分で設置設定して自分の計算機リソースで使ってね」という形でアプリケーションを配布するという形態は良くあった。良くあったけれども、Movable Type はそれらのプログラムの配布が簡単であろう一枚岩のスクリプトに比較するとずっと複雑且つ高機能で、中にはデータベース関連、テンプレートエンジンその他多種多様なライブラリなんかも含まれており、最初にみた印象としては「こんなに大きなプログラムを配布してもいいのか」と驚いたくらいで、その他の類のものとは一線を画していた。Movable Type は高度なアプリケーションにも関わらずダウンロード配布型のソフトウェアであることを維持するのにそれなりの開発コストを支払って、それを実現していた。

ただ、当然の流れだけれども、設置にはサーバーは必要だし実際動かすまでに色んな苦労があるしで、多くのユーザーはその後あちこちで立ち上がったブログサービス、つまり SaaS 系のサービスに移っていった。

この時自分が思ったのは、配布型の Movable Type をそれぞれ自分の計算機リソースで動かすというのは責務や負荷の分散という意味ではよりWeb的な分散の考え方だけれども、エンドユーザーが支払うコストが大きすぎるので、そのコストを一手に引き受けましょうというのがブログサービスだということだった。多数のユーザーそれぞれが支払っていた小さなコストをまとめて一手に引き受けるわけだから、そのコストもそれなりに大きなものになるのは当然で、それがサーバーリソースに過負荷をもたらして、サーバーが落ちたり、ストレージが壊れたりで大障害になるという話も後を絶たなかった。分散から集中を行った結果のトレードオフである。

分散から集中、集中から分散へ

分散から集中とくれば、次は集中から分散である、というのはこの分野のセオリーで、じゃあいつどういう契機でこれがまた分散型の考え方に移行していくのかなとこの10年生暖かくみてきたのだが、ここでようやく冒頭の話と繋がって、いままさに盛んに議論されている Immutable/Disposable Infrastructure が、集中から分散へのきっかけになっていくのではないかと思った、というのが本エントリで言いたいことであった。やっとここまで辿り着いた。

もちろん、Immutable/Disposable Infrastructure は、前述のとおりクラウドプロバイダ、大規模Webサービスプロバイダのような集中側の世界で議論されているしその達成主眼がそこにあるのは間違いない。一方で、Heroku が Webアプリケーションのポータビリティを強制することによって、それが副次的に第三者とのアプリケーションの交換を可能にしたのと同じように、廃棄可能なインフラストラクチャを追求していった結果、まるでデスクトップやスマートフォンのアプリケーションを配布するかのように、Webアプリケーションを第三者に配布し、エンドユーザーはそれを自分の好みの好きなクラウドプラットフォームにデプロイして使う・・・というような世界がいずれ実現されるかもしれないな、ということを妄想したりしている昨今で、例えばこのまま色んなクラウドプロバイダが Dokcer をサポートしていったら・・・そういうことは容易に想像できるのであります。

・・・どうやら、140文字で書こうとして書き始めたら 5,000 文字になっていたようです。