Managed VMs誕生までの歴史を振り返る

[gcp ja night #28] (http://connpass.com/event/8120/) には、みんな大好きBrianが来て、MVMsについて語ってくれる予定です。

また、@ymotongpooさんもGAE/GoとManaged VMについてのSessionです。

今年のGoogle I/Oでも、Sessionがあり、徐々にリリースの足音が聞こえてきているMVMsですが、今まであまり気にしていなかった方や、普段GAEを使っていない方には、なぜMVMsが生まれたのかが、ピンと来ない方もいらっしゃるのではないでしょうか？

そこで、MVMs誕生までの歴史を振り返ってみたいと思います。

# GAEのAppServerについておさらい

まず、歴史を振り返る前に、GAEのAppServerについて、おさらいしておきましょう。

以下がGAEがRequestを受け取った時の大まかな流れです。

Googleのインフラ上にあるFront End ServerがUserからのReuqestを受け取り、htmlなどの静的なリソースの要求であれば、Static Serverへ。動的リソースの要求であればAppServerへとRequestを渡します。
AppServerがRequestを受け取った場合、必要に応じて、Datastoreなどの各種Serviceへremote procedure callを行います。
我々が作成したAppはこのAppServerへdeployされ、動いています。
AppServerは、Requestの数が増えれば、スケールアウトを行うので、図では複数あるように書いています。

## 便利なVersion

AppServerにdeployするAppはVersionを指定します。
Defaultで動くVersionは、Consoleから簡単に切り替えることができます。
また、URLを指定すれば、特定のVersionへアクセスすることもできます。

1つのGAE Appの中にまったく別のものを、別Versionでdeployすることもできます。
例えば、管理者用の機能は別Versionでdeployする。DatastoreのBackupを行なうまったく別のAppをdeployする。といったことも可能です。

deployする言語が異なってもかまいません。Python,Java,GoのAppが混在したGAE Appを作ることもできます。

以下のような3つのversionをdeployするということも、行われていました。

* web : UserからのRequestを受けるgolangのApp
* manager : 管理者用のJavaのApp
* backup : DatastoreのBackupを取るPythonのApp

Versionを分けることは、batch処理や管理者の操作でUserへのRequestを遅延させたくないという狙いもありました。
Versionが違えば、別のAppServer instanceが立ち上がるので、backupなどで重いbatch処理が動いても、webには影響を与えずに済みます。

しかし、GAEでbatch処理を行うには問題もありました。
1Requestで行える処理の時間に制限があったのです。
30秒 (現在は60秒)の制限を超えると、強制的に処理が中断されてしまうので、全データを読み込んで処理を行うなどは、処理を分割してRequestを行なう必要があり、不便に感じることも有りました。

# Backends APIの登場

そこで登場したのが、Backends APIです。
Backends APIは、指定したVersionにdeployしたAppを、特別扱いし、Requestの処理時間制限を無くすというものでした。

これにより、Requestを受け取った後、長時間動作するbatch処理を作ることができるようになりました。

## 貧弱だったBackends API

Backends APIは我々を幸せにしてくれると思っていました。
処理時間の制限無く、処理を行うことができると。
しかし、実際には15分ほどで、頻繁にシャットダウンされてしまうという問題がありました。
30秒に比べれば、15分はかなり長く、ほとんどの処理を終えることができましたが、やはり不便に感じることも有りました。

# Google Compute Engineの登場

GAEはPaaSでしたが、GoogleのIaaSとして、GCEが登場しました。
この頃、GAEでできないことは、GCEでやれば良いという話をよく見るようになります。
元々、GAEには制約がありました。
LocalFileへのアクセス、Socket通信などは制限されており、できませんでした。
そのため、GAEUserはそれらを行いたい時は、その部分だけAWSを利用したりしていました。
GCEの登場で、Googleのインフラ内でGAEとも高速で通信できる。DeveloperAccountの管理やConsoleが1つで済む。などの理由により、GCEを使う人達が増えていきました。

しかし、そんなにGCEに乗り気で無い人もいました。
GAEの温もりに抱かれ、インフラの管理などを行わなくなり、LocalFileとかいじるためだけに、GCEの管理するのめんどくさい・・・と思っている人々です。
そう、私です。

それらの問題を解決するために、VM-based Backendsと呼ばれる仕組みが作られることとなりました。
GAEからGCEのinstanceを簡単に管理できるようなものを作ろうとしたのです。

# Modules APIの登場

VM-based Backendsの正式リリースより前に、Backends APIが抱えていた問題を解決するModules APIが登場しました。
Modules APIにより、Scalingの設定が強化され、15分でシャットダウンされることも無くなりました。
Modules APIはVersion上にもう一つ層を作ろうという仕組みです。
今まで、動いていたVerionがある場所は、default moduleとされ、Backends APIはdeprecatedになりました。
Backends APIはVersionにより区切っていたので、Backends APIで指定したVersion自体の、Version管理はできませんでしたが、Modules APIにより、batch処理などの裏で扱いたいAppもVersionで管理できます。

Modules APIについては、以下に書いてます。

[GAE ModulesをSimpleに使う] (http://www.topgate.co.jp/blog/20140715)

# Managed VMsの登場

Modules APIにより、15分でシャットダウンされる問題は解決しましたが、LocalFileが扱えないなどの制約は残ったままですし、GAEでSupportされていない言語で作られたtoolを使いたいなどの欲求もあります。
それらを解決するために、VM-based BackendsはManaged VMsに名前を変え、GCE上でGAEのinstanceを動かす存在を目指して、進み続けます。

## Dockerの登場

Managed VMsは設定ファイルを書いて、必要な初期化を行っていました。例えば、apt-getするpackage一覧を設定ファイルに書いて、GCE起動時に、それを読み込んでくると言った感じです。
しかし、Dockerの登場により、Managed VMsの中身は一気にDockerに傾きます。
DefaultでもDockerで動くようになり、更にUserがDockerfileを書くことで、カスタマイズできるようになりました。

GitHub/GoogleCloudPlatformにも、続々とMVMs用のProjectが公開され、DockerfileのSampleを見ることができます。

[appengine-java-vm-guestbook-extras] (https://github.com/GoogleCloudPlatform/appengine-java-vm-guestbook-extras/blob/master/stage3/src/main/webapp/Dockerfile)
[appengine-nodejs-quickstart] (https://github.com/GoogleCloudPlatform/appengine-nodejs-quickstart/blob/master/Dockerfile)
[appengine-vm-fortunespeak-python] (https://github.com/GoogleCloudPlatform/appengine-vm-fortunespeak-python/blob/master/Dockerfile)

開発中にLocalで動かすDevServerも、Dockerを用いるように、動き始めました。
[Google I/O 2014 - Zero to hero with Google Cloud Platform] (https://www.youtube.com/watch?v=1jcgYI7rlCg) はまさしく、それのためのSessionでした。
「GoogleのProduction環境を、あなたのマシンに」

# Managed VMsが目指している未来

MVMsはGCE上にGAEのinstanceを建てるという仕組みですが、それを行なうために使われているであろう仕組みに以下があります。

[Load Balancing](https://developers.google.com/compute/docs/load-balancing/)
[Compute Engine Autoscaler](https://developers.google.com/compute/docs/autoscaler/) (Limited Preview)
[Replica Pools](https://developers.google.com/compute/docs/replica-pool/) (Limited Preview)

いずれもGCEの仕組みです。名前からだいたいの機能は推測できるかと思います。Load Balancingは、Requestをどのinstanceに割り振るかのを決めます。Replica Poolsは、instanceのひな形を作り、poolさせておきます。AutoscalerはLoad BalancingとReplicaPoolsを扱い自動でスケールアウトを行ないます。

これを見て、まるでGAEのようだと感じた人もいるかと思います。MVMsはIaaS上にカスタマイズ可能なPaaSを構築しようとしているので、その感覚は合っていると思います。

PaaSが持っているヘルスチェックやスケールアウト、deploy supportなどの機能と、IaaSの自由さを、どちらも持った世界です。