Kodingがコンテナをやめてdockerから仮想マシンに移行したのはなぜ?


## はじめに
Dockerが流行っている一方で、このような事例もあるんだ、ということで参考になればと思います。Quoraの[Why did Koding move away from containers and Docker to virtual machines?](http://www.quora.com/Why-did-Koding-move-away-from-containers-and-Docker-to-virtual-machines) というポストの翻訳です。

[Koding](https://koding.com/)というのはオンラインIDEで、Go, Python, Ruby, node.js, PHPなどの開発環境をオンラインで使えるというものです。ユーザごとに仮想マシンを丸々与えられているので、シェルを開いてroot権限で色々することもできます。さらにはDockerも使えます。いかにもコンテナ型仮想化が向いていそうですが、最近バックエンドをLXCからAWSに移行したので、その経緯が解説されています。


かなり長いのでまとめると:

- `cgroups`によるリソース制限は完璧ではなく、Bitcoinマイニング、Fork爆弾、カーネルクラッシュなどで他のコンテナが影響を受けることがあった。
- ユーザのファイルを収めるバックエンドの分散ストレージ (CEPH) がスケールしなくなった。
- 上記の理由で運用やメンテナンスのコストが極めて高くなった。
- これってEC2とかS3の再発明だからAWSで良かったんじゃ…

という流れです。


## 翻訳
Kodingがコンテナをやめてdockerから仮想マシンに移行したのはなぜ?

>PS: これまでKodingは安定性に問題があり、私たちを苦しめていました。今、KodingのバックエンドはAWSになり、ユーザのみなさんに提供されるVMは全てAWSのVMになりました。LXCではなくなり、ハックしたりdockerを使わないことで、ダウンタイムがなくなりました。今月私たちは100,000台以上のVMを稼働させました--そう、100,000台のVMを99.9%の稼働率で動かしたのです。まだ、試していないならぜひ試してみてください…きっと気に入ってもらえると思います。

「スケールできるエンジニアリング」というテーマでブログの記事を書こうと思っていたので、ちょうどこれはこのテーマに分類できると思うので書きます。私たちが2011年末にLXCの社内テストをしていたとき、とてもわくわくしていました。というのも、LXCを使えば極めて低いコストでroot権限のあるVMをユーザに提供することが可能になるからです。この低いコストにより、VMがみんなにとって(開発、サンドボックス、コラボレーションなど)手軽になれば、諸々のコンピューティング関連の問題を解決するポテンシャルがあると考えました。

というわけでさらに深く細かく試し、社内テストの結果はとても良いものでした。実際、2012年初めにはSolomon Hykes (dotcloudのファウンダにしてDockerの生みの親) とともに、DotcloudとKodingの2つのプラットフォームを統合し、近づけることについて考えていました。その頃、DotcloudもLXCをいじくり回していて、数ヶ月後にはLXCベースであるDockerを思いついたわけです。

Dockerはびっくりするほど素晴らしくて成功しているプロダクトです。LXCはとても興味深い技術でしたし、今でもそうです。しかしLXCを何十万人というユーザの開発環境を提供するために使うと、スケールしなかったのです。これはLXC自体や、Dockerの問題ではなく、スケーリングの問題です。一般的に、DockerやLXCはXenのようなオーケストレーションツールを備えていないため、私たちは自分たちでこのようなツールを開発する必要がありました。

16GB/8CPU/1TBのマシンを持っている状況を考えてみてください。このよううなホストには、ほとんど無制限にコンテナを立ち上げることができます。例えば1台のホストに100個のコンテナをデプロイしたとしましょう。前提として、これらはプロダクション用のサーバではなく、CPU/RAMを全て使い切らないとします。私たちは、1つのコンテナがホスト全体をブロックしないようにLXCのCPUとRAMの制限機能 (`cgroups`) を使っていました。理論上はこれは素晴らしいのですが、現実には--LXCのリミッタは必ずしも上手く動くとは限らなかったのです。1つのコンテナがホスト全体を落としてしまうことは様々な原因からありえ、結果的に同じホストの上で動くコンテナを使用している残り99人がサーバが不安定だと訴えることになります。

さらに、私たちは`username.kd.io`ドメインへのアクセスを (Go言語で) 自作したプロキシでプロキシする必要がありました。そうでなければ、DNSサーバを自作してコンテナにパブリックIPを付与しなければいけませんでしたが、最新のDNSサーバでも更新は何年も前で、現実的ではありませんでした。その代わりに、私たちはSSHとFTPをプロキシするソフトを自作し、ユーザがホスト名でインターネットからアクセスできるようにしました。 (詳細については触れません。というのもあなたのスタートアップで自作のSSHやFTPプロキシをデプロイし、メンテナンスしたいとは思わないでしょうから。)これに加えて、そのホストを利用している100人のユーザはファイルを使用し、gitリポジトリをクローンし、時にはLXCベースのVMはGB単位の大きさに膨らみました。これらのユーザがセッションを終了したときには、私たちは効率的に (かつコスト低く) これら全てのGBサイズのファイルを保存する必要がありました。結果的に、私たちのユーザファイルはペタバイト級になりました。私たちはGlusterFSと他にいくつかのネットワークファイルシステムを評価しましたが、結果的にCEPHを選びました。これは、ファイルシステムを直接コンテナにマウントできるため、存在するネットワークファイルシステムの中では一番適したものだったからです。CEPHは素晴らしいソフトウェアですが、20,000個のブートドライブをマウントするために使うと、どこが故障するか予期できないシステムとなってしまいました。繰り返すと、これはCEPHの問題ではなく、スケールの問題なのです。サーバでI/Oがあふれ、ネットワークケーブルがこれ以上データを転送できない状態で、新しいディスクをマウントしようとすると、NICに処理不能なほどのTCPパケットが叩き込まれるわけです。そして障害が起きます。このような状況では、ストレージが利用できなくなり、 **全て** のホストで障害が発生します。

ここまでの全てはホスティングサーバで起きていたので、私たちは自分たちでネットワークケーブルを管理できる、自分のサーバを使ったデータセンタにデプロイすることに決めました。最終的には、2TB以上のRAMと数PBのストレージを持ったネットワークアーキテクチャに落ち着きました。これは素晴らしく動作したものの、Kodingに並行して50,000人のユーザがアクエスし、アカウントやVMを要求するような状況では、私たちが構築したネットワークアーキテクチャは期待通りにはスケールしませんでした。

私たちのアーキテクチャは64台以上の高性能なホストを持っていましたが、常にその内2〜3台は、ユーザがどのようにシステムを (不正) 利用するか制御できないために、Bitcoin採掘、Fork爆弾やカーネルパニックなどで落ちていました。最初のOpenVZベースのハイパーバイザを書き、2010年の投資以前からGoをバックエンドを使用していた、かなり技術派のCEOとしては、このシステムは既に私の能力を超えていました。このシステムを継続して運用することは、チームメンバの誰であっても1人では無理でした。もしなにか障害が発生したときは、大体3〜4人の人間が協力して対処する必要がありました。さらに話がややこしいことに、チームメンバは世界中に散らばっていたのです。

設計段階に立ち戻ったところ、Kodingはインフラストラクチャ系の企業になっていることに気づきました。確かに、私たちはLXCをオーケストレートするやり方や、各LXCコンテナにパブリックIPを割り当てる方法、コンテナをあるホストから別のホストに移動する方法、などなどを解決してきました。もしかしたら私たちはLXCのコアチームと、これらのセキュリティ問題を解決するために協力するべきだったのかもしれません。しかし、これらの問題全ては既にAmazonにより解決されており、それらはEC2, EBS, S3, Route53, Cloudwatch, Snapshotsなどと呼ばれています。私たちはLXCを使いたいがためだけにこれらを再発明していたのです。私たちのユーザは開発用に、ただ信頼出来るVMが欲しかっただけなのに、私たちがこれらを再発明することで、ユーザのワークフローを妨げてしまっていたのです。この決断のためのもう1つの重要な理由は、LXCによって提供されるコンテナは真のVM環境ではないということです。例えば、LXCコンテナの中では別のコンテナ (Dockerなど) を走らせることは難しいです。さらに、新しい戦略では、私たちのVMは真に違いに独立したもので、自分自身に対してのみ責任を持ち、VMとホストのシステムとは真に分離したものです。こういうわけで、私たちは再発明をやめることにしました。

Kodingのミッションは、裏側の技術を気にさせることなく (もちろん一部の人が気にしているのは知っていますよ!) 、開発者に信頼出来る開発環境を提供することです。さらに、Dockerコンテナの素晴らしい流行とともに、私たちのAmazonのVMを使うという決断は、私たちのユーザに提供するVMの中でDockerを用いるという、LXCベースのVMではできなかったことを可能にしたのです。

これは私たちの、LXCの代わりにAmazonのVMを用いるという決断に至ったストーリーです。これがあなたの疑問に対する答えになっていることを期待します。コメント歓迎です。