« 本日7/22(水)のAWS Black Belt Tech Webinar 2015に関してのお知らせ | メイン | AWS Black Belt Tech Webinar 「AWS CloudTrail & AWS Config」資料公開 »

【和訳】Under the Hood of Amazon EC2 Container Service

SAの岩永です。AmazonのCTOのWernerが、先日非常に興味深いAmazon EC2 Container Service (Amazon ECS)に関する投稿をしていましたので、日本語に訳してみました。Amazon ECSがもたらす価値を感じ取るのに良い記事だと思いますのでぜひご覧ください。

なお、Amazon ECSについて質問や要望がありましたら、どのような手段でも構いませんのでぜひご連絡下さい!


原文: Under the Hood of Amazon EC2 Container Service

過去のAmazon EC2 Container Service (Amazon ECS)に関する投稿の中で、私はクラスタ上でのモダンな分散アプリケーションの実行における2つの鍵となるコンポーネント「信頼できる状態管理」と「柔軟なスケジューリング」についてお話しました。Amazon ECSはコンテナ化したアプリケーションの構築と実行を簡単にしてくれますが、それをどのように実現しているかということがAmazon ECSを興味深いものとしています。今日は、Amazon ECSのアーキテクチャとそれによって何がもたらされているのかを説明したいと思います。以下がAmazon ECSの基本的なコンポーネントの図になります。

Ecs1

クラスタを協調動作させる方法

それではAmazon ECSが実際に何をしているのかについてお話していきましょう。Amazon ECSの中心となるのはクラスタマネージャです。これはクラスタの協調動作と状態管理のためのタスクを扱うバックエンドのサービスになります。クラスタマネージャの上に様々なスケジューラが作られています。クラスタ管理とコンテナスケジューリングはそれぞれ疎結合になっているため、みなさんは自由なスケジューラを使って構築することができます。クラスタとは、皆さんのアプリケーションのために利用可能なコンピュータリソースの単なるプールです。現時点ではAmazon EC2インスタンスのCPU・メモリ・ネットワークというリソースがプールとなっていて、それがコンテナ毎に区切られる形です。Amazon ECSはクラスタ内のそれぞれのEC2インスタンス上で動いているAmazon ECS Container Agentを通じてクラスタを協調動作させています。AgentによってAmazon ECSはクラスタ内のEC2インスタンスと通信をして、ユーザやスケジューラからのリクエストに応じてコンテナを開始、終了、そして監視することができます。AgentはGoで書かれていてフットプリントは最小限で、Apacheライセンスの基でGitHubで利用可能となっています。コントリビューションやフィードバックが最も歓迎されます。

状態を管理する方法

クラスタの協調動作のためには、クラスタ内のEC2インスタンス、その上で動いているタスク、タスクの中のコンテナ、そしてリソース(ネットワークポート、メモリ、CPUなど)が利用可能なのか専有されているのか、といったクラスタ自身について唯一の情報源が必要になります。クラスタの状態について正確な知識無しにコンテナをうまく開始したり停止したりする方法はありません。これを解決するために、状態はどこかに保存されている必要があります。そのため、どのモダンなクラスタマネージャでもその心臓部にはキーバリューストアを持っています。

このキーバリューストアはクラスタの全ての情報の唯一の源として働いていて、状態と全ての状態変化が入力され保存されています。ロバストでスケーラブルな状態を保つために、このキーバリューストアは耐久性と可用性の面で分散されている必要があり、ネットワーク分断やハードウェア障害から守る必要があります。しかしキーバリューストアが分散されているが故に、データの一貫性保証や同時並行する変更の処理はより難しくなります。特に(コンテナが停止したり開始したりするように)状態が絶えず変化するような環境では大変です。そのため、多数の状態変化が競合しないようにある種の並行制御が導入される必要があります。例えば、もし2人の開発者があるEC2インスタンスの残り全てのメモリリソースを使い切る様なコンテナ実行をリクエストした時に、片方のコンテナのみがこれらのリソースを実際に使うことができ、もう一方のリクエストは完了できなかったと教えられるべきです。

並行制御のために、我々はAmazonのコアな分散システムのプリミティブな部分の1つを利用してAmazon ECSを実装しました。それはPaxosベースでトランザクションなジャーナルを利用したデータストアで、データエントリの全ての変更をレコードとして保存しています。全てのデータストアへの書き込みは、特定の順序ベースのIDを用いたジャーナルのトランザクションとしてコミットされます。データストア内の現在の値というのは、ジャーナルに記録された全てのトランザクションを足しあわせたものになります。データストアからの全ての読み出しは、その時点でのジャーナルのただのスナップショットです。書き込みが成功するためには、書き込もうとしている内容が最後の読み出し以降の最新のトランザクションである必要があります。このプリミティブさによって、Amazon ECSはクラスタの状態の情報を楽観的並行性のもとに保存することができ、それは継続的に変化している情報が共有されているような環境(Amazon ECSの様に共有の計算リソースプールの状態を代表するような時)に理想的なものです。このアーキテクチャによってデータストアが決して悲観的ロックされることがないために、Amazon ECSは高い可用性、低いレイテンシ、そして高いスループットを持ち合わせることができています。

APIを使ったプログラム的なアクセス

キーバリューストアを持つことができ、クラスタの状態を安定して保存し取り出すことができるので、クラスタを協調動作させ必要な数のコンテナの稼働を保証することができるようになります。前に書いた様に、皆さんがAmazon ECSの状態管理能力の利点を活かせる様にするため、我々はコンテナスケジューリングをクラスタ管理とは疎結合にしました。Amazon ECSのクラスタ管理はAPIアクションの集合として開かれており、皆さんは体系だった手段で我々のキーバリューストアに保存されているクラスタの状態の情報全てにアクセスすることができます。

‘list’系のコマンドでは、管理下にあるクラスタや、特定のクラスタで動いているEC2インスタンス、実行しているタスク、そしてタスクの元となるコンテナの設定(タスク定義)を取得することができます。’describe’系のコマンドでは、特定のEC2インスタンスや利用可能なリソースについての詳細が得られます。最後に、皆さんはクラスタのどこにでもタスクを開始したり停止したりできます。我々は最近Amazon ECSに一連の負荷試験を行いましたが、皆さんがAmazon ECS上でアプリケーションを構築する時に期待される様ないくつかのパフォーマンスの特徴を共有したいと思います。

Ecs2

上のグラフはAmazon ECSのクラスタにインスタンスを足したり削除したりしながら、’DescribeTask’ API呼び出しのレイテンシの50パーセンタイルと99パーセンタイルを72時間に渡って計測したものです。見て分かる通り、クラスタサイズに急激な変動があっても、レイテンシは比較的変動のない状態を維持しています。Amazon ECSは、クラスタ管理を運用したりスケールさせることを全くせずに、どんなに大きいクラスタのサイズにでもスケールすることができます。

このAPIアクション群は、Amazon ECS上に皆さんが構築できるソリューションの基本的な形となっています。スケジューラは単純に、どうやって、いつ、どこでコンテナを開始し停止するかについてのロジックだけを提供します。Amazon ECSのアーキテクチャはクラスタの状態を共有するためにデザインされていて、みなさんはアプリケーションの需要に応じていくらでも多様なスケジューラ(ビンパッキングやスプレッドなど)を走らせることができます。このアーキテクチャによってスケジューラはクラスタの正確な状態を見ることができ、共有プールからリソースを割り当てることができます。楽観的並行制御によってそれぞれのスケジューラはリソース競合の可能性無しに要求したリソースを受け取ることができます。既にいくつかのお客様は多様な興味深いソリューションをAmazon ECS上で作り上げているので、おもしろいいくつかの例を共有したいと思います。

Hailo - 弾力性のあるリソースプールのためのカスタムスケジューリング

Hailoは無料のスマートフォンアプリで、ユーザはライセンスのあるタクシーを今いる場所に直接呼ぶことができます。Hailoは世界中で60,000以上の運転手と繋がっていて100万人以上の乗客がいます。Hailoは2011年に創立して、Day 1からAWS上で構築してきました。過去数年で、Hailoは1つのAWSリージョンで稼働するモノリシックなアプリケーションから、複数のリージョンにまたがったマイクロサービスベースのアーキテクチャに進化してきました。以前は、各マイクロサービスは静的に分割されたインスタンス群によるクラスタで動いていました。Hailoが経験した問題はそれぞれのパーティションでリソースの利用率が低いというものでした。このアーキテクチャは超スケーラブルではなく、Hailoはエンジニア達にインフラの詳細やマイクロサービスの配置について悩みをもたせたくありませんでした。

Hailoはサービスの優先度や弾力性のあるリソースプール上のその他のランタイムのメトリクスに基いてコンテナをスケジュールしたいと思いました。彼らはAmazon ECSをクラスタ管理として選択しましたが、その理由はマネージドサービスであり、タスクの状態を簡単に強制できてクラスタの状態はAPI呼び出しによって丸見えになっているからでした。これによって、Hailoは彼らのアプリケーション特有の要件にあうロジックを持ったカスタムスケジューラの構築が可能になりました。

Remind - Platform as a Service

Remindはwebとモバイルのアプリケーションで、教師が生徒にテキストメッセージを送ることができ、親とも連絡することができます。Remindはプラットフォーム上に2400万のユーザと150万以上の教師を抱えています。毎月1億5000万件以上のメッセージを配信しています。Remindは初期にはHerokuを利用していて、メッセージ配信のエンジンやフロントエンドのAPI、webのクライアントから、チャットのバックエンドまで全てのアプリケーションのインフラを実行していました。このインフラの多くは巨大なモノリシックアプリケーションとしてデプロイされていました。

ユーザが増えるにつれて、Remindは水平にスケールできるようにしたくなりました。そこで2014年の終わり頃にエンジニアチームはコンテナを使ったマイクロサービスアーキテクチャへの移行を検討し始めました。チームはAWSの上にHeroku APIと互換性のあるPlatform as a Service (PaaS)を作りたいと思っていました。初め、チームはクラスタ状態とコンテナのオーケストレーションをするためにいくつかのオープンソースのソリューション(CoreOSやKubernetes)を見ていましたが、エンジニアチームは小さく、彼らにはクラスタのインフラを管理したりクラスタの高可用性を保つための時間はありませんでした。

Amazon ECSを少し評価してみた後で、チームはこのサービスの上にPaaSを構築することを決めました。Amazon ECSは完全にマネージドで効率的な運用を提供してくれるので、エンジニアのリソースをアプリケーションの開発とデプロイだけに集中させることができます。クラスタを管理したりスケールさせる必要がありません。6月にはRemindは彼らのECS上のPaaSソリューションを”Empire"としてオープンソースにしました。Remindはセキュリティ上の利点に加えて、大きなパフォーマンス改善(レイテンシと安定性)をEmpireによって手に入れました。彼らのこのさき数ヶ月のプランでは、90%以上のコアインフラをEmpire上へと移行することになっています。

Amazon ECS - 完全マネージドプラットフォーム

これらはお客さんから学んだユースケースのうちの数個にすぎません。Amazon ECSのアーキテクチャによって高いスケーラビリティ、高い可用性、低いレイテンシを持ったコンテナ管理サービスを提供することができます。共有のクラスタの状態にAPIを通じて楽観的並行性でアクセスできることにより、必要にあわせてどのようなカスタムのコンテナソリューションでも作ることができます。我々はお客様から差別化に役立たない重石を取り除くことにフォーカスし続けています。Amazon ECSでは、いかなるクラスタ管理もインストールしたり運用したりする必要はありません。お客様は素晴らしいアプリケーションの開発だけに集中することができますし、そうすべきです。

昨年11月のプレビュー以来、たくさんの機能を追加してきました。この1年で我々が追加してきた機能についての振り返りはJeff Barrのブログをご覧ください。手始めにドキュメントを読み、コンソールを訪れて下さい。まだまだ沢山の機能がロードマップとして控えており皆さんのフィードバックを心待ちにしています。質問や要望をぜひフォーラムRedditのAWSに投稿して下さい。

コメント

Twitter, Facebook

このブログの最新情報はTwitterFacebookでもお知らせしています。お気軽にフォローください。

2018年4 月

1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30