cloud foundryで学ぶ、paasのしくみ講座
TRANSCRIPT
今回の目的 • ブラックボックスに思われがちな、PaaSの中身を理解して貰うことで、不安を解いてもらいたい
• Cloud Foundryだけでなく、どのPaaSにも共通して利用できる知識を身につける
教材: Cloud Foundry • オープンソースのPaaSなので、誰でも仕組みを追える
• 多くのベンダーが採用(IBM, HP, NTT Comなど)
• ユーザーが機能を拡張できる、Heroku互換のBuildpackを採用している
例えば、Rubyアプリを構築するとき
• Rubyをインストール
• bundle install • (Railsなら) rake assets:precompile
• (Railsなら) rake db:migrate
※DEMOで話した内容
皆さんが普段Apache+PHPの環境を作りたいと思ったとき
たぶんこんな感じでapt-getでインストールすると思います。
するとほら、こんな感じでApacheのプロセスが起動するわけですね。
Server
OS
Apache
PHP (mod_php/php-fpm)
Application
Server
OS
Ruby
WEBrick
Application
サーバー
OS
ミドルウェア
アプリケーション
手動で構築したときのソフトウェアスタック
※DEMOで話した内容
デプロイ出来たので、実際にPaaS環境の中に入って、どんな感じにアプリが 上がっているか見てみましょうか。
Rubyのプロセスが上がっているのが分かりますよね。さっきと殆ど同じという ことが分かるでしょう。
※DEMOで話した内容
次にPHPアプリをデプロイしてみました。
httpd となっていますが、さっき手動で上げたときのapache2のバイナリの
名前が違うだけです。単純にApacheのプロセスが上がっているだけ、 と言うことです。 つまり、皆さんが普段自前で組んでる環境も、PaaSで組まれる環境も、 中身は殆ど同じ、というわけです。
Server
OS
Apache
PHP (mod_php/php-fpm)
Application
Server
OS
Ruby
WEBrick
Application
サーバー
OS
ミドルウェア
アプリケーション
PaaS上のソフトウェアスタック
Server
OS
Apache PHP
/usr/sbin/apache2 /etc/apache2/ …
/usr/bin/php5 /etc/php5/ …
apt-get yum source…
手動で構築する時
• aptやyumなどのパッケージマネージャ
• ソースからコンパイル
• どちらの場合も、サーバーの特定の場所にランタイムが配置される
Server
OS
?
6u45 7u79 8u45
5.4.39 5.5.23 5.6.7
1.9.3-p551 2.1.6 2.2.2
PaaSの場合
• 様々な言語、それも様々なバージョンに対応しなければいけない
• どこにどうインストールされているのだろう?
※DEMOで話した内容
さっき上げたアプリをもう一度見てみましょうか。 /home/vcap/app~の下に、何かコンフィグがあるようですね。見てみましょうか
あれ、おかしいですね。/home/vcapに居るはずなのに、そもそもappなんて ディレクトリが存在しないように見えます。
※DEMOで話した内容
Rubyの場合も、/home/vcap/app配下のファイルを読んでいるようですが、
やはりPaaS環境上に、そんなファイルは存在しないように見えます。 どういうことでしょうか。
※DEMOで話した内容
ここで皆さんに覚えておいて欲しいのが、コンテナという仕組みです。 この後説明しますが、アプリはコンテナの中で動いています。実際にアプリの コンテナの中に入ってみますね。
コンテナの中で、Rubyプロセスが上がっているのが確認出来ます。 ファイルはどうでしょうか。
※DEMOで話した内容
はい、確かにファイルが存在することが確認出来ました。 これはさっきアップロードした、Sinatraアプリですね。
bin/ の中を見てみると、rubyやgemなど、実行に必要なバイナリが既に
設置されていることが分かります。実際にRubyバイナリを実行して、 バージョン情報を見てみましょうか。
※DEMOで話した内容
では、PHPアプリのほうを見てみましょうか。
こちらも/home/vcap/app が存在しますね。ここで重要なのは、さっきのRubyと 同じパスなのにも関わらず、設置してあるファイルは全く別物ということです。 アプリケーションに応じて、必要なものが、適切に設置してあるわけです。
✓ PaaSの実行環境では、アプリごとにコンテナが作られ、マルチテナントで動いている
✓ コンテナの中には、実行に必要なバイナリが全て含まれている
✓ その他実行に必要な作業も全て実施済(Rubyのbundle installなど)
Photo by Enokson https://www.flickr.com/photos/vblibrary/4385390248/
Server
OS
Apache Ruby 2.1.4 Ruby 1.9.3-p551 Java7
php-fpmTomcat
app A app B app C app D
それぞれがコンテナ
ApplicationApplication Application
Application
コンテナ技術• Cloud Foundryの場合、Wardenという独自のコンテナ機構を使っている
• HerokuはLXCを利用
• 最近はDockerが流行り
いずれもLinuxのcgroupsやnamespaceという機能を活用しており、得られるメリットは似通っている
Photo by Dirk Dallas https://www.flickr.com/photos/dirkdallas/
コンテナによるメリット
• 異なる環境をアプリに提供出来る • JavaならJava、RubyならRuby
• アプリ同士を隔離出来る • セキュリティの担保、リソースの制限
• 素早く立ち上げることがきる • VMを使うと数分、コンテナなら数秒
Photo by Dirk Dallas https://www.flickr.com/photos/dirkdallas/
ApplicationApplication Application
Application
Server
OS
Apache Ruby 2.1.4 Ruby 1.9.3-p551 Java7
php-fpmTomcat
このコンテナイメージは、 誰が、いつ用意したのか?
Buildpack• Herokuによって作られた、任意の言語やフレームワークを扱えるようにする仕組み
• Cloud FoundryもBuildpackを利用可能
Photo by cgc76 https://www.flickr.com/photos/cgc76/10620451574
1. Detect
2. Compile
3. Release
composer.jsonがあるか
(無ければ次へ)
.phpのファイルがあるか
(無ければ次へ)
$WEBDIRがあるか
PHP Buildpackの場合
1. Detect
2. Compile
3. Release
Ruby Buildpackの場合
1. Gemfileから指定Rubyバージョンを確認して、バイナリをダウンロード
2. フレームワークを確認(Rails?Sinatra?)
3. bundle install 4. rake assets:precompile(Railsの場合)
つまりBuildpackとは• コードがどういう言語で書かれているか検出する
• その言語向けの環境を構築する
Photo by cgc76 https://www.flickr.com/photos/cgc76/10620451574
3. アプリに対し、内蔵のBuildpackのdetect スクリプトを順次実行
Inside PaaS
Ruby buildpack
Java buildpack
PHP buildpack
PHP buildpack
5. ランタイムもアプリも含まれた 実行環境一式が出来上がる
Inside PaaS
Ruby buildpack
Java buildpack
PHP buildpack
PHP buildpack
Buildpackの適用を中心とした、 アプリの準備作業を「ステージング」と呼ぶ
Inside PaaS
Ruby buildpack
Java buildpack
PHP buildpack
PHP buildpack
PaaSへの「デプロイ」は「アップロード」「ステージング」「実行」の3フェーズで構成される
Inside PaaS
Ruby buildpack
Java buildpack
PHP buildpack
PHP buildpack
これまで手動で行ってきたインストール作業を コードから自動判別して行っているに過ぎない
Inside PaaS
Ruby buildpack
Java buildpack
PHP buildpack
PHP buildpack
※DEMOで話した内容
Cloud Foundryでは、コマンド一発でアプリケーションのインスタンス数を 増やすことができます。それも一瞬で。実際に試してみましょうか。
一瞬で起動しましたね。手動でサーバーをスケールアウトするのと比べると、 数百倍、数千倍速いですね。これはどういう仕組みなんでしょうか。
←だいたい数秒
Inside PaaS
Ruby buildpack
Java buildpack
PHP buildpack
PHP buildpack
・ ・ ・
buildpackをたくさん実行? 時間がかかるし、負荷も高そう
appA appA appAappBappB
appA.example.comは192.168.10.2:52341で上がってます
appB.example.comは192.168.10.2:52313で上がってます
各DEAは、自分の持つ
アプリのポートとIPアドレス、URLをRouterに通知
appA appA appAappBappB
appA.example.comは192.168.10.4:64341で上がってます
appA.example.comは192.168.10.5:23591で上がってます
各DEAは、自分の持つ
アプリのポートとIPアドレス、URLをRouterに通知
appA appA appAappBappB
これで、Routerは
どこのIPのどのPortに、どのアプリが動いているか 知ることが出来る
appA.example.com 192.168.10.4:64341 192.168.10.5:23591 192.168.10.2:52341
appB.example.com 192.168.10.3:32563 192.168.10.2:52313
✓ Cloud FoundryのRouterは、アプリへのリクエストを解釈して正しい場所に転送する、L7のリクエストルーター
✓ Routerが利用する情報は、各DEAからもたらされる
✓ 一般的に使われる、L3の「ルーター」とは異なるので注意
Photo by Enokson https://www.flickr.com/photos/vblibrary/4385390248/
appA appA appAappBappB
ところで、先ほど「DEAはRouterに通知する」と表現した。
つまり、Routerの数が増えると、通知数も増えてしまう?
Router数 x DEA数=通知数・・・
Publish-Subscribeモデル
• メッセージの送信側(Publisher) と受信側(Subscriber)が存在
• Publisherはトピックを付けてメッセージを送信する。どれだけのSubscriberが居るかは関知しない。
• Subscriberは、指定しているトピックのメッセージを自動的に受信する
Publisher Subscriber
appA appA appAappBappB
Subscribe router.register
Publish router.register {“uris”:[“appA.example.com”],”host”:"192.168.10.2","port":35155}
NATS
appA appA appAappBappB
Subscribe router.register
Publish router.register
NATS
Publish dea.start
Subscribe staging.start
Subscribe dea.start
Subscribe dea.advertise
Publish dea.advertise
CC-DEA間もNATS
NATS
• NATSを通じて疎結合に構成されている • どこに何が存在するか、各コンポーネントが把握しておく必要が無い(NATS
のアドレスさえ分かっていればいい) • そのため、柔軟にコンポーネントの追加・削除が行える
appA appB
アプリのクラッシュ時
ぬるぽ
NATSPublish droplet.exited
Subscribe droplet.exited
appB
dropletが終了した旨をpublish。HMはそれをsubscribeしている
appA appB
アプリのクラッシュ時
NATSPublish hm9000.start
appB
Subscribe hm9000.start
HMはCCにクラッシュしたアプリを 再度上げるよう通知
appA appB
ホストのクラッシュ時
NATS
appB
DEAは普段から、heartbeatを定期的にpublishしている
Publish dea.heartbeat Running appA, appB
Publish dea.heartbeat Running appB
Subscribe dea.heartbeat
appA appB
ホストのクラッシュ時
NATS
appB
ホストがクラッシュした場合、heartbeatが来なくなるので HMはクラッシュに気づく
Publish dea.heartbeat Running appB
?
その裏には、多くの人に便利なサービスを提供できるよう、考え抜かれた仕掛けが存在する
Inside PaaS
Ruby buildpack
Java buildpack
PHP buildpack
PHP buildpack
もちろん、PaaSに必要なものは他にもある• ユーザーの管理・認証・認可 • ログの管理 • メトリクスの管理 • 課金
• Web GUI • データベース等のサービス
これらの話は、またの機会に。
今後もPaaSは変わりつづけるけれど
• Buildpack <=> Dockerfile • Droplet <=> Docker image • NATS <=> etcd
と置き換えて考えることも出来る(同一ではないけど)
新しい仕組みを取り入れたからといって、 これまでの知識が無駄になるわけではない
参考情報• はじめてのCF Buildpack http://www.slideshare.net/jacopen/cf-buildpack
• Cloud Foundryは何故動くのか http://www.slideshare.net/jacopen/cloud-foundry-33851040
• Cloud Foundry V2を、もうちょっと深掘りしよう http://www.slideshare.net/jacopen/c-fv2
• 日本Cloud Foundryグループ http://cloudfoundry.gr.jp/
• PaaS勉強会 http://paas.connpass.com/