As a SW/Ops/DB Engineer

riywo’s technology memo

Awesome Docker!そして環境管理について思うところ

最近個人プロダクトでやってたことは、

  • Myroku
    • private PaaS
    • 社内とかで自由にHerokuっぽいことやりたい
  • Pandler
    • package isolation
    • rpmを完璧に管理した環境を作りたい

みたいな感じなんですが、一人でスキマ時間で頑張ってたものなのでクオリティは最低ですし、全然完成しませんでした。本当に作る才能がない。

というところで、ネットサーフィンしてたら、最近dotCloudがDockerというのをOSSで出したということを知りました。

dotCloudはPaaSをやってる会社で、DockerはLXC(Linux Container)を使った実行環境管理ツールの様です。dotCloudの社内でも使われているものみたいですね。

隔離環境

Pandlerでやりたかったことは、chrootで全く新しいroot filesystemを作ってそこにrpmを完璧に管理してインストールしプロセスを実行することだったんですが、DockerはLXCを使ってそれを実現してます。正確にはパッケージ管理の部分はLXCのイメージ?(実はLXC触ったことない。。。)にしてるのでDSL的な管理はできていないですが、実行環境をホストから隔離して実行するという意味では同じです。というか、Vagrant、ひいてはprivate cloud全般も同じ感じですね。

実際、PaaS的なことをやろうと思うとなにがしかの方法で環境を隔離して管理しないといけなくて、Herokuもdynoという単位でVMを表現していますが、これもLXCの様です。

Myrokuではもっと単純なアプローチで、LLの実行環境(処理系+ライブラリ群)のみを固定化してプロセスを立ち上げればいいかなと思い、自作のllenvを使って、LLの処理系およびLLのライブラリ群を1ディレクトリに入れて実行するという方式を取りました。ついでにそれをcapistranoで配布して、フロントのHTTPリバースプロキシと連携してポート番号を割り当てて、VirtualHostで出し分ける、みたいなところまでやりました。

一方、Pandlerはchrootを使って固定化してみました。chrootの良い点は変なオーバヘッドなくシンプルに使えることと、IPアドレス始めリソースの配分を考える必要が無いということだと思います。Pandlerは利用者にはchrootであることを意識しなくても実行できるような感じをイメージしていたので、そういう面倒事をなるべく排除したかったです(LXC詳しくないので実はそういうことやらなくて済む方法もあるのかも知れません)。あと、rootユーザじゃなくても実行できたらと思ってfakechrootとかも見てました。

環境の隔離をもっとも素直にやるなら、今は各種仮想マシンを利用するのが手っ取り早いですね。XenやVMware、KVMにVirtualBox、果てはそれらをまとめて管理する環境(OpenStackとか)まで、もうすでにたくさんの選択肢がありますが、僕がやってきたようなやり方も環境隔離の一つのやり方だと思います。

なんで必要なの?

僕がどうしてここまでこの分野にこだわってるかというと、別にPaaSがやりたいわけではなくて、プロセスの実行環境(特にファイル資源)を出来る限りホストOSそれ自身から切り離したいからです。

なぜ?それはOSのインストール自体=Kernelを起動するまでと、アプリケーションを動かすレイヤを分けることで、様々なインフラ上で同じアプリケーションを動作させることができるようになるからです。(ただし僕の頭の中ではLinuxのことしか考えてません)

様々なインフラとは、仮想マシンやパブリッククラウド、VPSやオンプレミスなサーバなどです。これらの間でOSおよびパッケージ群を完全に揃えることは大変に困難を極めます。それぞれの環境でサポートしているディストリやバージョンが違ったりしますし、諸々の理由で既にインストールされているものと衝突する場合もあります。ChefやPuppetなどの構成管理ツールでホストOSを管理する方法をとってもこれは解決しません。

じゃあ、JVMの様にそれぞれの環境上にVMを入れてしまえばいいじゃない、つまり、どの環境であれとにかくKVMなりを使える様にしてしまえばイメージの使い回しができる、というのはまぁそのとおりなんですが、それじゃあどの環境も使うメリットがありません。オンプレミスを使いたい場面は大抵ハードウェアのスペックを使い切りたいわけですし、クラウドのサーバで仮想マシンを動かすのはなんかおかしいです(もちろんクラウド自身がそのイメージを使えればいいですが)。

最近は、LLの処理系は**env的なツールを使って一般ユーザでビルドからやってしまえば、ホストOSに依存せずにどこでも同じ環境が再現できる!という意見も出てきそうですが、結局ホストOSに入っているライブラリ(libなんとかとか)は使っちゃうわけで、そのバージョンが違えば当然挙動が変わってしまいます。これは処理系だけじゃなくて、その後インストールするLL自身のパッケージも同様で、C拡張系のパッケージは激しくホストOSに依存しますので、BundlerやCartonを使った管理も100%完璧ではありません。

僕が最近思ってるよさげな妥協点としては、Dockerの様にKernelは環境によって差異があるかもしれないけど、アプリケーションのファイル資源はホストOSとは完全に切り離されていて、libなんとかも全部自前で揃えている環境と必ずセットで管理するのがいいと思ってます。

Bundled application

ファイル資源をアプリケーションとセットにすることで、このファイルをコピーして実行するだけで、アプリケーションを簡単にどこでも再現できます。もちろんLXCを使うならLXCが使えるKernelじゃないとダメですが、逆にいうとそこさえクリアすればいいわけです。実際、DockerはEC2でも動くみたいです。

で、こうすることでなにがいいのか?例えばあるサービスをEC2で始めたとして、成長に伴い次はVPS、最後はオンプレミスへと移行するというケースや、反対にオンプレミスのサービスの縮小に伴いEC2に移行したいといったケースで威力を発揮します。こうした移行は大抵ものすごい労力を伴います。ただでさえ開発に忙しいのに、コスト計算・比較もしなくちゃいけないし、いろんな他のシステム(DNSとかLBとか)も一式移さなきゃいけない。その上、移行したらOSのバージョン相違やライブラリの相違で動かなくなるかもしれない恐怖と戦うには、相当の体力が必要になります。実行環境がある程度切り離せていれば、そこまで苦もなく移せる可能性が高まります。

また、開発環境と本番環境の差異も減らせます。開発環境は仮想マシン、本番環境はオンプレミスみたいなケースはよくあると思いますが、どうしてもいろんな差分が生まれてしまい、それを綺麗に揃えることに労力を割けるのはこれまた相当な体力がないと続きません。Bundledであれば、(もちろん設定ファイルとかは出し分けますが)一式同じライブラリで開発から本番に持っていくことができますし、テストもしやすくなります。

Ops的にも利点があります。モニタリングに必要なツール一式をBundledできれば、それをとにかく配布すればどんな環境であれおなじ監視ツールがすぐ使える(cgroupsで他のプロセス見えないとかどうすんだろ)とか、アプリケーションがなんであれOSインストール時は自由に作ることができるから、その環境特有の設定や監視を統一的に管理できるとかもできそうです。例えばこのデータセンタはこのネットワークの設定が必要、みたいなのってアプリケーションからはなるべく切り離したいですよね。

DockerとかTravisとかMesos

で、まぁこういうことをそもそも既にやってるのがPaaSなんですが、中々その中の仕組みが実装レベルで外に出てくることはなかったので、Dockerはちょっと参考にしたいと思います。もしくは使ってみたい。

あと、Travis CIみたいなテスト環境系も実は同じようなことをやっているなと思って、前に手元で動かしてみようと試みたことがあることを書いておきます。萎えてやめましたが。

おまけで、MesosってのがLXCをもっと高度に抽象化して、クラスタで並べたnodeのmemoryとcpuリソースをアプリケーションに適切に配分するとかやってるみたいですが、詳しくは知りません。Twitterはガシガシ使っているそうです。

おわりに

Dockerが良さそうだなぁと思ったので、ここ最近考えてることを合わせて言語化しておきました。英語で書くには英語力が足りないのと誰にも読んでもらえないorz

問題はこれが所詮POCで、こういうことを実際にやるモチベーションは特にないので、机上の空論感がとても強いこと。多少の環境の差異はなんとなく乗りきれちゃったりするしそもそも完璧に管理する必要ないことが多い。もしくは寿命ギリギリまで環境を出来る限り変えずにやり過ごすのが一番簡単なやり方なので、今頑張る必要なくて、そしてずっと頑張る必要がないような話題だったりもします。この辺はサービスのライフサイクルとかも絡めて話をしたいところです。

ただ夢を見続けることはした方がいいのかなと思うのと、そもそもその夢間違ってるよってのも言って欲しくてとりあえず書きなぐっておきました。

Comments