オリジナルのCloud Foundryサイトを構築する:CloudFoundryで始めるPaaS構築入門(2)(2/2 ページ)
この連載では3回に分けて、「Cloud Foundry」というオープンソースパッケージを用いて、Platform as a Service(PaaS)のためのインフラストラクチャを構築する方法について解説します。
Cloud Foundry のアーキテクチャ
Cloud Foundryのソフトウェアスタック
図1は、Cloud Foundryが提供するソフトウェアスタックを表したものです。Cloud Foundryサイトは1台のサーバで構築することもできますが、実体は複数のサーバコンポーネントで構成され、複数台のオペレーティングシステムの上で仮想的な1つのシステムを提供します。
Cloud Foundryのソフトウェアとしての位置付けを誤解を恐れずに表現するならば、「Platform as a Serviceを構成するシステムのカーネル」といえるでしょう。LinuxカーネルとLinuxディストリビューションの関係のように、Cloud Foundryカーネル(OSSで公開されているソースコード一式)とCloud Foundryサイト(cloudfoundry.comなどのようなサービス提供サイトやStackatoのようなパッケージ製品)が位置付けられます。
Cloud Foundryカーネル(以下Cloud Foundryと呼びます)が提供するのは、大きく分けて次の4つです。
- Webアプリケーションコンテナおよび(データ)サービスのリソースプール
- リソースプールに対するインスタンスのプロビジョニング
- プロビジョニングされたアプリケーションインスタンスに対するHTTP(S)トラフィックのルーティング
- プロビジョニングされたアプリケーションインスタンスとサービスインスタンスを結びつけるバインディング
プロダクションレベルのCloud Foundryサイトを構築する場合は、これらの機能だけではPaaSと呼ぶには不十分な点が多々ありますが、まずはCloud Foundryの担当範囲を知ることで、何が不足しているかを認識しましょう。
Cloud Foundryの内部アーキテクチャ
図2はネットワークの視点で、Cloud Foundryのそれぞれの内部コンポーネントの関連を表したものです(注6)。枠で囲われた箱がサーバコンポーネント、つまり何らかのポートで待ち受けを行うプロセスを表しています。3重に重ねられたコンポーネントは、1つのCloud Foundryで複数インスタンスの起動によるスケールアウトが可能なコンポーネントを表しています。コンポーネント間を結ぶ線は、ネットワーク上で実際にパケットのやりとりが必要なことを表しています。
注6:Cloud Foundryのアーキテクチャは視点によりさまざまな議論が可能です。ここで挙げたもの以外に、アプリケーションコンテナへのデプロイを実行する「Stager」、アプリケーション実行環境に提供するLinux Containerを管理する「warden」、外部のデータサービスとの連携を行うための「Service Broker」などもコンポーネントとして存在します。ただしこれらは、最小要件のCloud Foundryサイト環境の構築および動作に必須ではないため割愛しています。
Cloud Foundryのアプリケーションコンテナを構成するコンポーネントは以下の通りです。
・ロードバランサ(Load Balancer)
Cloud Foundryサイトに流れるすべてのHTTP(S)トラフィックの負荷分散機能を提供します。HTTP(S)トラフィックを負荷分散できるものであれば、任意のものを使用可能です。従って、このコンポーネントの実装はソースコードに含まれておらず、サードパーティのプロダクトを自分自身で構築します。オールインワン構成の場合は、nginxが利用されるように構成されます。
・ルータ(Router)
(名称はルータですが)Cloud Foundryに特化したL7ロードバランサのような動作をするコンポーネントです。ロードバランサから受け取ったHTTPトラフィックを受け取り(注7)、適切なサーバ(後述するDEA上のユーザーアプリケーションインスタンスやクラウドコントローラのインスタンス)にトラフィックをルーティングする機能を提供します。実装はhttps://github.com/cloudfoundry/routerにあります。
注7:HTTPSには対応していないため、構築するCloud FoundryサイトでHTTPSに対応するにはロードバランサでHTTPSをHTTPに変換する必要があります。
・クラウドコントローラ(Cloud Controller)
Cloud Foundryサイトの管理機能をWeb APIで提供するWebアプリケーションで、Ruby on Railsを使って実装されています。vmcコマンドで行われる操作はすべて、HTTPリクエストとしてこのコンポーネントで処理されます。実装はhttps://github.com/cloudfoundry/cloud_controller/tree/master/cloud_controllerにあります。
・クラウドコントローラデータベース(Cloud Controller Database)
アプリケーションのメタデータが格納されるリレーショナルデータベースです。開発用にはSQLite3が利用され、本番システム用にはPostgreSQLが利用できるように、クラウドコントローラの設定が記述されています。このコンポーネントの実装は、ソースコードに含まれていません。
筆者が検証した限りでは、MySQLを使うこともできるようですが、Cloud Foundryが使用しているRubyのMySQLクライアントではいくつかの問題があるため、PostgreSQLの利用をお勧めします。
・共有ファイルシステム(Shared File System)
クラウドコントローラにアップロードされたアプリケーションのソースコードを、クラウドコントローラのインスタンス間で保管しておく共有ファイルシステムです。オールインワン構成では必要ありません。マルチノード構成で、クラウドコントローラを複数サーバにまたがって並べるときは、NFSなどによる共有ファイルシステムの実装が必要になります。このコンポーネントの実装は、ソースコードに含まれていません。
・DEA
Droplet Execution Agentの略です。クラウドコントローラから指令を受け取り、各サーバ上のユーザーのアプリケーション(Droplet)の起動/停止を制御するエージェント機能を提供します。実装はhttps://github.com/cloudfoundry/deaにあります。
・ヘルスマネージャ(Health Manager)
クラウドコントローラデータベースを参照し、DEAに対してハートビートを行いながら、デプロイされたアプリケーションの死活確認を行い、必要に応じてリカバリを要求する機能を提供します。実装はhttps://github.com/cloudfoundry/cloud_controller/tree/master/health_managerにあります。
・メッセージバス(Message Bus)
Cloud Foundry内部のコンポーネント間のメッセージのやりとりを仲介するメッセージングサーバの機能を提供します。NATSと呼ばれる独自のメッセージングミドルウェアを使う必要があります。このコンポーネントの実装は、ソースコードに含まれていません。
これらのコンポーネントで構成されるアプリケーションコンテナに対し、必要に応じてサービスブロックを追加していくことができます(追加しない、という選択も可能です)。サービスブロックの構成に必要なコンポーネントは以下の通りで、サービスの実装(例えばMongoDBやRedisなど)の分だけ追加します。オールインワン構成ではMySQL、MongoDB、Redis、Neo4Jなどのサービスが追加されるようになっています。
・サービスゲートウェイ(Service Gateway)
クラウドコントローラに対して、サービスブロックが提供するデータサービスの情報を登録し、プロビジョニング、デプロビジョニングなどの指令をクラウドコントローラから受け取るためのゲートウェイ機能を提供します。実装例はhttps://github.com/cloudfoundry/vcap-services/blob/master/mongodb/lib/mongodb_service/mongodb_provisioner.rbなどです。
・サービスノード(Service Node)
サービスゲートウェイから指令を受け取り、実際のサービスインスタンスを起動/停止する機能を提供します。実装例はhttps://github.com/cloudfoundry/vcap-services/blob/master/mongodb/lib/mongodb_service/mongodb_node.rbなどです。
・メッセージバス(Message Bus)
Cloud Foundry内部のコンポーネント間のメッセージのやりとりを仲介するバスの機能を提供します。NATSと呼ばれる独自のメッセージングミドルウェアを使う必要があります。オールインワン構成では、クラウドコントローラやルータなどが利用するメッセージバスと共有されます。このコンポーネントの実装は、ソースコードに含まれていません。
スケーラビリティとフォルトトレランスの確保
Cloud Foundryサイト上のインスタンスに対して
Cloud Foundryサイト上で動作するアプリケーションの開発者は、Cloud Foundryサイトを使うことでスケーラビリティやフォルトトレランスの管理から逃れられることを期待するでしょう。一方、Cloud Foundryサイトの管理者にとっては、内部的にスケーラビリティとフォルトトレランスを確保する手段を講じておく必要があるでしょう。
ここではCloud Foundryサイト上で動作するアプリケーションインスタンスとサービスインスタンスのスケーラビリティとフォルトトレランスについて言及します。
Cloud Foundryサイト上で動くアプリケーションのスケールアウト機能は、vmc instanceコマンドによって提供されます。このコマンドを発行することで、Cloud Foundry内部では、DEAで管理されるアプリケーションプロセス数を変更します。
Cloud Foundryサイトの管理者は、DEAが起動可能なアプリケーション数に随時注意を払っておき、必要に応じてDEAを追加・削除できるように準備しておく必要があります。また、トラフィック量の多いアプリケーションを想定して、ロードバランサおよびルータも必要に応じて追加・削除できるように準備しておく必要があります。
Cloud Foundryサイト上で動くアプリケーションのフォルトトレランスは、ヘルスマネージャによって保障されます。具体的には、アプリケーションインスタンスが動いているノードの障害をヘルスマネージャが検知し、別のDEA上で起動するようにクラウドコントローラにメッセージを投げることで、わずかな時間で回復するように設計されています。Cloud Foundryサイトの管理者は、ヘルスマネージャノード自体がダウンした場合は速やかに別のサーバ上で起動できるようにしておくなどの事前準備が必要です。
なお、ヘルスマネージャ自体が停止しても、DEA上で稼働するアプリケーションには影響がありません。また、ヘルスマネージャの現在の実装は、プロセス管理のみを責任範囲としており、アプリケーションのパフォーマンス管理までは責任を持っていません。つまり、アプリケーションの応答が低下したときに、自動的にアプリケーションのインスタンス数を増やすなどの機能は提供されません。
Cloud Foundryサイト上で動くサービスインスタンスのスケールアウト機能は、Cloud Foundryには含まれていません。そしてサービスインスタンスのハードウェア障害発生時などにノードをフェールオーバーさせるフォルトトレランス機能も、Cloud Foundryには含まれていません。いくつかのサービスの実装にはデータのバックアップ機能が含まれているので、その機能を使って定期的にバックアップを取得し、障害時には手動でリストアしてあげる必要があります。
Cloud Foundryサイト自体に対して
最後に、Cloud Foundryサイト上のユーザー数やアプリケーション数、トラフィック量の増加に備えたスケーラビリティや、Cloud Foundryサイト自体のフォルトトレランスについて言及します。
こちらは少し複雑で、Cloud Foundryのソースに含まれないものについては、利用するプロダクトに完全に依存します。ここではCloud Foundryのソースに含まれるもの、およびCloud Foundryが強く依存するメッセージングミドルウェアのNATSに言及します。
ルータ、クラウドコントローラ、DEAおよびサービスノードは基本的に、ノード数を追加することでスケールアウトできます。クラウドコントローラやDEAを追加・削除したとき(またはサービスノードを追加・削除したとき)は、それらがルータ(またはサービスゲートウェイ)に通知され、自動的にトラフィックが制御されるように設計・実装されています。なお、ここでいう「削除」は、障害による停止の場合も同様で、フォルトトレランスが保障されます。
ルータの追加・削除はロードバランサと協調するように制御する必要があり、フォルトトレランスもロードバランサとして利用する製品に依存します。
ヘルスマネージャおよびサービスゲートウェイは1つのプロセスで機能を提供するコンポーネントです。これらにスケールアウトさせるための設計や実装は、現在のところありません。スケールアップさせることで対応する必要があります。特に、ヘルスマネージャはアプリケーション数の増加に伴って徐々にパフォーマンスが低下していき、障害の検知まで時間がかかるようになるので、注意してください。
これらのコンポーネントで障害が発生した場合は、アプリケーションの監視やサービスのプロビジョニング機能が動作しなくなりますが、アプリケーションそのものが停止するような重要な障害には至りません。速やかに再起動を試みてください。コンポーネント自体はデータを持たないため、コールドスタンバイの状態にしておけば問題ありません。
NATSも、1つのプロセスで機能を提供するコンポーネントです。現在、スケールアウトさせるためのクラスタリング機能が開発されていますが、Cloud Foundryの各コンポーネントはこれらに未対応です。従って、スケールアップさせることで対応する必要があります。
NATSで障害が発生した場合には、ルータやDEAなどをはじめとしてアプリケーションを正常に動作させるための多くのコンポーネントのプロセスが停止し、サイト全体がダウンします。この問題の回避方法はいまのところ実装されていないため、Cloud Foundryとは別のレイヤでソリューションを検討する必要があります(注8)。
注8:筆者らがこの問題についてMLで議論をしたところ、LinuxのkeepalivedやheartbeatなどのHAソフトウェアを使って、IPアドレスを移動させる方式で実現するのが最も現実的な解のようです。
サポートされていないインフラストラクチャ
Cloud Foundryが提供するのはHTTPのトラフィックのルーティングとデータサービスのプロビジョニングです。例えば、以下のような機能は提供されないため、プロダクションレベルのCloud Foundryサイトを構築する際には、Cloud Foundryとうまく連携するように自動化されたシステムを構築する必要があるでしょう。
- 分散ストレージ
- メールサービス
- プロキシサービス
- DNSサービス
- リソース監視/管理サービス
- ログ管理サービス
- Cloud Foundryサイト自体のディザスタリカバリ機能
別の見方をすれば、これらの付加的な価値を提供することができれば、OSSであるCloud Foundryを使ったビジネスモデルも見えてくるでしょう。
次回予告
今回はCloud FoundryのソースコードからCloud Foundryサイトをセットアップし、アプリケーションをデプロイするとともに、内部のアーキテクチャ概要について解説しました。本格的なCloud Foundryサイトを構築する場合はCloud Foundryでカバーされていない領域について、サイト構築担当者自身がCloud Foundry自体のソースコードを修正するか、補完するソリューションによる実装を検討する必要があります。
次回は連載の最後に、Cloud Foundry自体のソースコードを修正して、機能を追加する方法を、例を挙げて紹介します。
Copyright © ITmedia, Inc. All Rights Reserved.