このgistは Open PaaS Advent Calendar 2014 の5日目の記事です。前日の記事は,jacopen さんの「cf-sshでCloud Foundryのコンテナ内に潜り込む)」でした。
#完全に1日遅れました。もうしわけありません。
今日は,Herokuや Cloud Foundry で使われているアプリケーションの実行環境を作る仕組み「buildpack」について書くつもりだったのですが,buildpackを説明する前に,まず「buildpackがアプリケーションのデプロイ全体の中でどこに使われているか」から説明した方が良いと思い直し,「Cloud Foundry でアプリケーションをデプロイする時の全体の流れ」について書くことにしました。Herokuはproprietaryなので,「buildpackがアプリケーションのデプロイ全体の中でどこに使われているか」については推測しかできないのですが,Cloud Foundry ならオープンソースなので,ソースを読めばその辺りもわかります。この辺が open paas ならではですね,と強引に advent calendar の趣旨に話を持っていってみました。
では,さっそく行ってみましょう。私の前回の記事同様,資料は以前作ったものの修正版(使い回しともいう)です。
まずは全体像から。図が外部リンクになっているのは,諸般の事情によりご容赦ください。
概要図
Cloud Foundry では,ユーザーはアプリケーションをデプロイするのに必要なのはたった一つのコマンド cf push
だけなのですが,図を見てわかるように,その裏では,これだけのステップ数の処理が行われています。ちなみにこの図は,多少の省略(例えば,デプロイ時のログの表示はアプリケーションのデプロイに必須の機能ではないので,省略しています;つまり実際はもっと複雑です)と,日々積まれるコミットにより,最新の Cloud Foundry の処理の流れと完全には一致していません。予めご了承ください。
この図に登場するエンティティは7種類です。うち Cloud Foundry のコンポーネントが5種類,残りはデータベースと,Cloud Foundry にアクセスするクライアントです。
それぞれのエンティティについて簡単に説明します。
-
Router
Cloud Foundry システムに対する外からのアクセスを中継するプロキシー兼ロード・バランサーです。 -
Cloud Controller
Cloud Foundry システムの外部APIを提供するWebアプリケーションです。Cloud Foudry 内部のエンティティも,このAPIを経由して処理を行うことがあります。 -
DEA
Droplet Execution Agent の略称。Dropletとは,とりあえずはデプロイ対象のアプリケーションだと考えてもらえばだいたい合っています。DEAは,その Droplet = アプリケーションの実行を制御/監視するエンティティです。 -
Health Manager
アプリケーションのあるべき状態と現状を比較して,差分があればその是正を要求するエンティティです。例えば,ユーザーがあるアプリケーションを2インスタンス(=並列度2)起動するよう指示しているのに,当該アプリケーションのインスタンスが(何らかの理由で)1つしか起動していない場合,Health Manager はインスタンスをもう一つ起動するよう Cloud Controller にリクエストします。 -
NATS server
Cloud Foundry システム内の各エンティティ間のメッセージのやりとりを,publish/subscribe方式で仲介するエンティティです。RabbitMQをすごくシンプルにしたものと考えてもらってもいいかもしれません。 -
CCDB
Cloud Controller Database の略称。Cloud Foundry システムについて永続化すべき情報(例えば,ユーザーがアプリケーションに割り当てたメモリやインスタンス数など)を保管するデータベースです。 -
CF CLI / HTTP Client
ユーザーが Cloud Foundry システムを操作するためのクライアント。先程述べた通り,基本的に全ての操作APIは Cloud Controller の Web API として提供されているので,HTTPリクエストが投げられるクライアントであればなんでもかまいません。Cloud Foundry では,それらの Web API を組み合わせて叩く操作をコマンド化して利便性を高めたcf
というCLIが公式に提供されています。以下では、これらをまとめて「CFクライアント」と呼びます。
- 1: アプリケーションの作成要求 図
CFクライアントから Cloud Foundry API (以下「CF API」)に,アプリケーションの作成要求が送られる - 2: アプリケーション作成要求の転送 図
アプリケーションの作成要求がRouterから Cloud Controller (以下CC)に転送される - 3: アプリケーション情報の保存 図
CCはCCDBにアプリケーションの情報(名前,メモリ使用量,インスタンス数等)を保存する - 4: アプリケーション作成の成功応答 図
アプリケーション作成要求の成功応答がCCからRouterに送られる - 5: アプリケーション作成成功応答の転送 図
アプリケーションの作成要求がRouterからCFクライアントに転送される - 6: アプリケーションのアップロード 図
アプリケーション本体(ソースコード,設定ファイル,画像ファイル等)が CF API に送られる - 7: アプリケーションの転送 図
アプリケーション本体がRouterからCCに転送される - 8: アプリケーション・アップロードの成功応答 図
受信したアプリケーション本体をCCが保存し,アップロード成功の応答を返す
CCが複数台でクラスター化されている場合は,アプリケーション本体の保存先としてNFSやオブジェクト・ストレージが用いられる - 9: アプリケーション・アップロードの成功応答の転送 図
アプリケーション・アップロードの成功応答が,RouterからCFクライアントに転送される - 10: アプリケーションの起動要求 図
CFクライアントから Cloud Foundry API (以下「CF API」)に,アプリケーションの起動要求が送られる - (11): Stager Advertisement の定期的な送信 図
DEAから Stager Advertisement が定期的に送信される
Stager Advertisement とは,自分が現在どういうstaging能力を持っているのかを表明する情報である (Stagingについては第19ステップの説明を参照)
この処理はDEAの起動中に定期的に行われるので,本処理フローの中でこの順序で行われるものではないが,わかりやすくするためにこの位置に置くことにした - (12): 定期的な Stager Advertisement の転送 図
Stager Advertisement が NATS server (以下「NATS」)を介してCCに転送される
この処理もDEA起動中に定期的に行われるので,本処理フローの中でこの順序で行われるものではない - 13: アプリケーションのstaging要求の送信 図
CCは,各DEAから送られてきた Stager Advertisement をもとに,どのDEAでアプリケーションのstagingを行うかを決定し,選んだDEAにstaging要求を送る - 14: Staging要求の転送 図
アプリケーションのstaging要求が,NATSを介してDEAに転送される - 15: アプリケーションのダウンロード要求 図 → 図
DEAは,受信したstaging要求を見て,CCに保存されたアプリケーション本体(ソースコード,設定ファイル,画像ファイル等)のダウンロード要求を CF API に送る - 16: アプリケーションのダウンロード要求の転送 図
アプリケーション本体のダウンロード要求が,Routerを介してCCに転送される - 17: アプリケーションの返送 図
CCは,要求されたアプリケーション本体を送り返す - 18: アプリケーションの転送 図 → 図
Routerは,CCから返送されたアプリケーション本体を,要求元のDEAに転送する - 19: アプリケーションのstaging 図
DEAは,受信したアプリケーション本体を使ってアプリケーションのstagingを行う
アプリケーションのstagingは,おおよそ以下の手順で行われる- アプリケーション本体の情報とStaging要求をもとに,そのアプリケーションに必要なbuildpackを決める
- (optional) 当該buildpackが無ければダウンロードする
- アプリケーション本体とbuildpackを使って,アプリケーションを実行する環境を構築する
具体的には,ソースコードの配置,依存ライブラリーの取得と配置,(必要ならば)ソースコードのコンパイル,等を行う - 作成したアプリケーション実行環境のtarball化
できあがったアプリケーション実行環境をtarballにして1ファイルにまとめる
このtarballをdropletと呼ぶ
- 20: Dropletのアップロード 図 → 図
できあがったdropletが CF API に送られる - 21: Dropletの転送 図
送られたdropletが,Routerを介してCCに転送され,CCで保存される - (22): DEA Advertisement の定期的な送信 図
DEAから DEA Advertisement が定期的に送信される
DEA Advertisement とは,自分が現在どういうアプリケーション実行能力を持っているのかを表明する情報である
この処理はDEAの起動中に定期的に行われるので,本処理フローの中でこの順序で行われるものではないが,わかりやすくするためにこの位置に置くことにした - (23): 定期的な DEA Advertisement の転送 図
DEA Advertisement がNATSを介してCCに転送される
この処理もDEA起動中に定期的に行われるので,本処理フローの中でこの順序で行われるものではない - 24: Droplet起動要求の送信 図
CCは,各DEAから送られてきた DEA Advertisement をもとに,どのDEAでdropletの起動を行うかを決定し,選んだDEAに,アップロードされたdropletの起動要求を送る - 25: Droplet起動要求の転送 図
Droplet起動要求がNATSを介してCCに転送される - 26: Dropletのダウンロード 図 → 図
DEAは,受信した起動要求をもとに,CCに保存されたdropletのダウンロード要求を CF API に送る
Droplet起動要求にdropletを含めて送らないのは,NATSのメッセージ・サイズの制限によるものである - 27: Dropletのダウンロード要求の転送 図
Dropletのダウンロード要求が,Routerを介してCCに転送される - 28: Dropletの返送 図
CCは,要求されたdropletを送り返す - 29: Dropletの転送 図 → 図
Routerは,CCから返送されたdropletを,要求元のDEAに転送する - 30: Dropletの起動 図
DEAは受信したdropletを展開し,そこに含まれたアプリケーションを起動する - 31: Droplet起動の通知 図
DEAは,dropletが起動したら,その通知をNATSに送る - 32: Droplet起動通知の配信 図, 図
NATSは,droplet起動通知を Health Manager とCCに配信する - 33: アプリケーション状態の変更 図
CCは,CCDBに保存されたアプリケーションの実行状態を変更する - 34: アプリケーション起動の通知 図
CCは,CFクライアントにアプリケーションの起動を知らせる - 35: アプリケーション起動通知の転送 図
アプリケーション起動通知が,RouterからCFクライアントに転送される - 36: アプリケーションの待ち受け情報の登録 図
DEAは,アプリケーションのURLと,アプリケーションが実際に待ち受けている<ホスト:ポート>の情報の登録要求を送信する
この処理は,実際には第31ステップ(Droplet起動の通知)とほぼ同時に行われるので,第32〜35ステップと実行順序は前後する - 37: アプリケーションの待ち受け情報の登録要求の転送 図
アプリケーションの待ち受け情報の登録要求が,NATSを介してRouterに転送される Routerは,この登録要求に含まれるURLのアクセスが来たら,指定された<ホスト:ポート>に転送するよう,自身を設定する
以上です。
もともと書くつもりだった「buildpack」は,この中の一ステップ「19: アプリケーションのstaging」で使われるものなのですが,それを説明したいがためにこれだけ書くのは何か本末転倒感がありますね。
ではまた次回に。
#次こそはちゃんと間に合わせたい。