cloud foundryで学ぶ、paasのしくみ講座

125
Cloud Foundryで学ぶ PaaSのしくみ講座

Upload: kazuto-kusama

Post on 15-Jul-2015

1.310 views

Category:

Technology


0 download

TRANSCRIPT

Cloud Foundryで学ぶPaaSのしくみ講座

日本Cloud Foundryグループ

Kazuto Kusama@jacopen

日本Cloud Foundryグループ #cfgrjp

PaaS

1. コードを書く 2. PaaSにデプロイ 3. 動作!

すごく簡単

PaaS

1. コードを書く 2. PaaSにデプロイ 3. 動作!

PaaS

わかる わかる え、どうやったの?

1. コードを書く 2. PaaSにデプロイ 3. 動作!

PaaS

わかる わかる え、どうやったの?

4. スケールアウト

???

PaaSが便利なのは分かる インフラを知らなくとも使える

でも、ブラックボックスなのは嫌だ

今回の目的 • ブラックボックスに思われがちな、PaaSの中身を理解して貰うことで、不安を解いてもらいたい

• Cloud Foundryだけでなく、どのPaaSにも共通して利用できる知識を身につける

PaaS上のアプリの動作を見てみる

PaaS上の アプリの一生を追ってみる

PaaSを支える 仕組みを学ぶ321

教材: Cloud Foundry • オープンソースのPaaSなので、誰でも仕組みを追える

• 多くのベンダーが採用(IBM, HP, NTT Comなど)

• ユーザーが機能を拡張できる、Heroku互換のBuildpackを採用している

PaaS上のアプリの動作を見てみる1

例えば、PHPアプリを構築するとき

• Apache/Nginxをインストール

• PHP(mod_php/php-fpm)をインストール

• 必要に応じてpeclやpearをインストール

例えば、Rubyアプリを構築するとき

• Rubyをインストール

• bundle install • (Railsなら) rake assets:precompile

• (Railsなら) rake db:migrate

DEMO

※DEMOで話した内容

皆さんが普段Apache+PHPの環境を作りたいと思ったとき

たぶんこんな感じでapt-getでインストールすると思います。

するとほら、こんな感じでApacheのプロセスが起動するわけですね。

※DEMOで話した内容

じゃあRubyのアプリの場合はどうか。

ここにSinatraのアプリを用意しましたので、まずは定番のbundle installですね。 その後に起動します。

※DEMOで話した内容

すると、こんな感じで起動するわけです。

ここまでは、皆さんが見慣れた光景ですよね。

Server

OS

Apache

PHP (mod_php/php-fpm)

Application

Server

OS

Ruby

WEBrick

Application

サーバー

OS

ミドルウェア

アプリケーション

手動で構築したときのソフトウェアスタック

では、PaaSの場合は?

DEMO

※DEMOで話した内容

PaaSの場合、中身はどうなるんでしょう。

今回、自前のCloud Foundry環境を用意したので、まずはSinatraアプリを デプロイしてみます。

※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上のソフトウェアスタック

PaaSであってもアプリが動く仕組みは一緒

ポイント①

PaaS上の アプリの一生を追ってみる2

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

※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

Buildpack• Herokuによって作られた、任意の言語やフレームワークを扱えるようにする仕組み

• Cloud FoundryもBuildpackを利用可能

Photo by cgc76 https://www.flickr.com/photos/cgc76/10620451574

Buildpack• Ruby • PHP • Java • Python • Go • Node • etc…

Buildpackの3フェーズ

1. Detect

2. Compile

3. Release Buildpackには、必ずこの3スクリプトが含まれている

1. Detect

2. Compile

3. Release

Buildpackの実行条件に合致するかをチェックするスクリプト。 合致したら0を、合致しなければ1を返す。

1. Detect

2. Compile

3. Release

composer.jsonがあるか

(無ければ次へ)

.phpのファイルがあるか

(無ければ次へ)

$WEBDIRがあるか

PHP Buildpackの場合

1. Detect

2. Compile

3. Release

実行環境を構築するスクリプト

1. Detect

2. Compile

3. Release

Ruby Buildpackの場合

1. Gemfileから指定Rubyバージョンを確認して、バイナリをダウンロード

2. フレームワークを確認(Rails?Sinatra?)

3. bundle install 4. rake assets:precompile(Railsの場合)

1. Detect

2. Compile

3. Release

実行に必要な環境変数などの情報を出力 (今回は説明は割愛)

つまりBuildpackとは• コードがどういう言語で書かれているか検出する

• その言語向けの環境を構築する

Photo by cgc76 https://www.flickr.com/photos/cgc76/10620451574

ここまでの復習を兼ねて一連の流れで考えてみよう

1. ユーザーがアプリをプッシュ

2. Cloud Foundryがアプリを受け取る Inside PaaS

Ruby buildpack

Java buildpack

PHP buildpack

PHP buildpack

3. アプリに対し、内蔵のBuildpackのdetect  スクリプトを順次実行

Inside PaaS

Ruby buildpack

Java buildpack

PHP buildpack

PHP buildpack

4. detectでマッチしたBuildpackの compileスクリプトを実行

Inside PaaS

Java buildpack

PHP buildpack

PHP buildpack

5. ランタイムもアプリも含まれた  実行環境一式が出来上がる

Inside PaaS

Ruby buildpack

Java buildpack

PHP buildpack

PHP buildpack

6. Cloud Foundryの実行ノードで  アプリを起動  (このとき、コンテナで動く)

Inside PaaS

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

※DEMOで話した内容

Cloud Foundryでは、コマンド一発でアプリケーションのインスタンス数を 増やすことができます。それも一瞬で。実際に試してみましょうか。

一瞬で起動しましたね。手動でサーバーをスケールアウトするのと比べると、 数百倍、数千倍速いですね。これはどういう仕組みなんでしょうか。

←だいたい数秒

スケールアウト• コマンド一発で、たくさんのインスタンスを展開出来る

• しかも速い

Inside PaaS

Ruby buildpack

Java buildpack

PHP buildpack

PHP buildpack

・ ・ ・

buildpackをたくさん実行? 時間がかかるし、負荷も高そう

Inside PaaS

Ruby buildpack

Java buildpack

PHP buildpack

PHP buildpack

Dropletと言う形で、保存しています

Droplet

Cloud Controller DEA (Droplet Execution Agent)

Inside PaaS

Ruby buildpack

Java buildpack

PHP buildpack

PHP buildpack

アップロードを受け取るのは、CCの仕事

Inside PaaS

Ruby buildpack

Java buildpack

PHP buildpack

PHP buildpack

CCからDEAに、ステージングの依頼

PHP buildpack

DEAは成果物(Droplet)を返す。CCはそれを保存。

CCはDropletを各DEAに配布して実行を依頼する

スケールアウト時は、ステージングは行わずDropletの配布のみで済む

PaaSを支える 仕組みを学ぶ3

appA appA appAappBappB

Internet

? アプリは複数台に跨がっているだけでなく、関係ないアプリと同居しているという状態。

目的のアプリにどうやってアクセスすればよいか。

リクエストルーティング

Router

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

appA appA appAappBappB

実際にリクエストが来たら、リストを元にアクセスを分配

♪appA.example.com

✓ Cloud FoundryのRouterは、アプリへのリクエストを解釈して正しい場所に転送する、L7のリクエストルーター

✓ Routerが利用する情報は、各DEAからもたらされる

✓ 一般的に使われる、L3の「ルーター」とは異なるので注意

Photo by Enokson https://www.flickr.com/photos/vblibrary/4385390248/

メッセージングバス

appA appA appAappBappB

負荷が高くなっても対応できるよう、Routerは複数台で負荷分散できるようになっている。

appA appA appAappBappB

ところで、先ほど「DEAはRouterに通知する」と表現した。

つまり、Routerの数が増えると、通知数も増えてしまう?

Router数 x DEA数=通知数・・・

appA appA appAappBappB

もちろん、そうはならない。メッセージのやり取りは、NATSというPub-Sub型メッセージングバスを通じて行う

NATS

Publish-Subscribeモデル

• メッセージの送信側(Publisher) と受信側(Subscriber)が存在

• Publisherはトピックを付けてメッセージを送信する。どれだけのSubscriberが居るかは関知しない。

• Subscriberは、指定しているトピックのメッセージを自動的に受信する

Publisher Subscriber

Publish-SubscribeモデルSubscribe ENL

ENL

RES

Subscribe ENL and RES

Subscribe RES

NATS

Publish

Publish

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 appA appAappBappB

運用していると、必ず障害は起こる

ぬるぽ

ソフトウェアのバグで アプリがクラッシュ

ハードウェア障害で DEAホストがダウン

Health Manager

appA appB

アプリのクラッシュ時

ぬるぽ

NATS

Σ

appB

DEAがアプリのクラッシュを検出

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

Publish dea.start

Subscribe dea.start

CCはDEAにアプリの立ち上げ メッセージを通知

appA appB

アプリのクラッシュ時

NATS

appB appA

アプリが復旧する

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

?

appA appB

ホストのクラッシュ時

NATS

appB

足りなくなった分を増やすよう通知

Publish hm9000.start

Subscribe hm9000.start

appA appB

ホストのクラッシュ時

NATS

appB

アプリが復旧する

appA

appB

Publish dea.start

Subscribe dea.start

まとめ

ユーザーが書いたコードは

PaaS上でよしなに実行される

PaaS

アプリ自体は、ごく一般的な仕組みで動いている

OS

Runtime

Framework

その裏には、多くの人に便利なサービスを提供できるよう、考え抜かれた仕掛けが存在する

Inside PaaS

Ruby buildpack

Java buildpack

PHP buildpack

PHP buildpack

Cloud Controllerはユーザーからのリクエストを受け取り

Buildpackにより実行可能なDropletが作成され

Ruby buildpack

Java buildpack

PHP buildpack

DropletはCCのコントロールにより、素早くDEA上で実行される

Routerはアプリがどこで動いていても適切なアクセス手段を提供する

アプリはDEAとHealth Managerにより監視され、問題が起きてもすぐに復旧される

全てのコンポーネントはNATSにより疎結合に結ばれており、柔軟に構築ができる

NATS

これがPaaSの仕組み

もちろん、PaaSに必要なものは他にもある• ユーザーの管理・認証・認可 • ログの管理 • メトリクスの管理 • 課金

• Web GUI • データベース等のサービス

これらの話は、またの機会に。

おまけ: これからのPaaS

最近のトレンド

OpenShift

DockerベースのPaaSが増えつつあるDeis

Flynn

Cloud Foundryも、

次期アーキテクチャ”Diego”でDockerに対応する予定

Diego

Diegoでは、NATSではなくCoreOSが開発するetcdを利用する(現在も一部にはetcdを使っている)

今後もPaaSは変わりつづけるけれど

• Buildpack <=> Dockerfile • Droplet <=> Docker image • NATS <=> etcd

と置き換えて考えることも出来る(同一ではないけど)

新しい仕組みを取り入れたからといって、 これまでの知識が無駄になるわけではない

日本Cloud Foundryグループ #cfgrjp

PaaS勉強会 #paasjp http://paas.connpass.com/

参考情報• はじめての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/