Amazon Web Services ブログ

Amazon ECS サービスディスカバリ

Amazon ECS でサービスディスカバリがサポートされました。これにより、ECS サービスが Amazon Route 53 の予測可能でフレンドリーな DNS 名で自動的に登録することができるようになります。負荷やコンテナの健全状態に対応してサービスがスケールアップまたはダウンすると、Route 53 のホストゾーンは最新の状態が保たれ、他のサービスが各サービスの状態に基づいてコネクションを行う必要がある場所を発見できるようになります。次のアドレスで、架空のソーシャルネットワークアプリでサービスディスカバリのデモを見ることができます。https://servicediscovery.ranman.com/.

サービスディスカバリ


マイクロサービスや最新のアーキテクチャへの移行の一部には、障害や変化する負荷に迅速に対応できるダイナミックで、オートスケーリングでき、そして堅牢であるサービスを持つことが必要とされます。皆さんのサービスはおそらく、依存したり利用されるサービスが複雑に関連した依存関係のグラフ構造を持っているでしょう。最新のアーキテクチャのベストプラクティスは、これらのサービスが独自に依存関係を指定できるようにして疎結合にすることですが、ダイナミックな環境では各サービスが自力で自身が接続する先を見つける必要があるため、複雑になってしまう場合があります。

consul、etcd、またはzookeeperなどのサービスディスカバリの従来のアプローチは、すべてこの問題をうまく解決しますが、追加のインフラストラクチャをプロビジョンして管理する必要や、コンテナやインスタンス上にエージェントをインストールする必要があります。これまでは、サービスが互いに発見して接続できるように、独自のサービスディスカバリーシステムを構成して実行するか、すべてのサービスをロードバランサに接続する必要がありました。これからは、ECS コンソール、AWS CLI、または ECS API を使用して、コンテナ化したサービスのサービスディスカバリが可能になります。

Amazon Route 53 サービスレジストリとAuto Naming API の紹介

Amazon ECS サービスディスカバリは、Amazon Route 53 サービスレジストリと Auto Naming API とコミュニケーションすることにより動作します。このブログではこれまでそれらについて触れていないため、ここでは簡単にこれらの Route 53 API の動作について概説したいと思います。最初に、一部の用語について説明します。

  • 名前空間 – 名前空間は、トラフィックを流すドメイン名を指定します (例: internal、local、corp)。これは、サービスが互いに発見できる論理的境界と考えることができます。名前空間は、 aws servicediscovery create-private-dns-namespace コマンドの呼び出しまたはECS コンソールで作成することができます。名前空間は、Route 53 のホストゾーンとほぼ同じです。名前空間にはサービスが含まれます。これは次に取り上げる用語です。
  • サービス – サービスは「auth」、「timeline」、「worker」などの名前空間にある特定のアプリケーションまたはアプリケーションのセットです。サービスはサービスインスタンスを含みます。
  • サービスインスタンス – サービスインスタンスは、Route 53 がリソースの DNS クエリに応答する方法に関する情報を含みます。

Route 53 は、名前空間、タスクIPごとのAレコード、およびタスクIP+ポートごとの SRVレコードを作成するAPIを提供しています。

Route 53に、例えばworker.corpといった問い合わせをすると、そのリクエストを満たすことができる IP の候補セットが得られるはずです。もし接続するアプリケーションが動的なポートを提供している場合には、アプリケーションの呼び出しはSRVレコードに問い合わせてより詳細な情報を得ることで実現できます。

ECS サービスディスカバリは Route 53 API の上に構築され、関連する全てのAPI コールを管理してくれます。これで、サービスレジストリの動作について理解できましたので、サービスディスカバリの動作を見るために、ECS 側を見ていきましょう。

Amazon ECS サービスディスカバリ

サービスディスカバリを使ったアプリケーションを起動してみましょう! 最初に「flask-backend」と「flask-worker」という2つのタスク定義を作成します。両方共、HTTP リクエストに返答する単一のコンテナをもつ単純な AWS Fargate タスクです。flask-backendは worker.corp を呼び出して仕事をさせてから、そのレスポンスと、workerとしてRoute 53が返してきたアドレスを合わせて返します。コードは下にある様なものです:

@app.route("/")
namespace = os.getenv("namespace")
worker_host = "worker" + namespace
def backend():
    r = requests.get("http://"+worker_host)
    worker = socket.gethostbyname(worker_host)
    return "Worker Message: {]\nFrom: {}".format(r.content, worker)

コンテナとタスク定義ができあがったので、コンソールでサービスを作成します。

サービスウィザードのステップ 2 に移動すると、サービスディスカバリのセクションがあるので、ECS に新しい名前空間を作成させます。

また、ECS にサービスのタスクの健全状態を監視し、必要に応じてRoute 53 にそれらを追加または削除するように指示します。次に、使用する A レコードの TTL を 10 秒に設定します。

同じ手順を「worker」サービスにも繰り返し、1分前後たつと、ほとんどのタスクが開始され、実行中になります。

Route 53 コンソールに、私のタスクのすべてのレコードが表示されてます!

Route 53 サービスディスカバリ API を使用して、すべての利用可能なサービスとタスクをリストして、プログラムからもアクセスすることができます。backend と worker だけでなく、任意の数のサービスに容易に拡大することもできます。私は、「auth」、「feed」、「timeline」、「worker」「user」といったサービスをもつ架空のソーシャルネットワークの簡単なデモを作成しましたのでhttps://servicediscovery.ranman.com/をご覧下さい。GitHub でそのページを実行するために使用されているコードを確認できます。

今すぐ利用可能
Amazon ECS サービスディスカバリは現在、米国東部 (バージニア北部)米国東部 (オハイオ)米国西部 (オレゴン)、および欧州 (アイルランド)で利用できます。AWS Fargate は現在、米国東部 (バージニア北部)でのみ利用可能です。 ECS サービスディスカバリを使用する場合、作成する各ネームスペースを含む、消費する Route 53 リソースと、サービスが行う検索クエリの料金がかかります。コンテナレベルのヘルスチェックは無償で提供されます。料金表の詳細は、ドキュメントを参照してください。

サービスディスカバリを使用して構築またはリファクタリングしているものについて、ぜひコメントまたはツイッターのいずれかでお知らせください!

Randall

追伸: 私が執筆しているすべてのブログ投稿は、数多くの AWS の同僚たちの支援を受けています。チームを越えてサービスディスカバリの構築を助けてくださったすべての方々に感謝いたします:)!