VPC で Amazon ECS サービスを接続するためのベストプラクティス
VPC で Amazon ECS タスクを使用すると、モノリシックアプリケーションを、安全な環境で個別にデプロイおよびスケーリングできる別々の部分に分割できます。このアーキテクチャは、サービス指向アーキテクチャ (SOA) またはマイクロサービスといいます。ただし、VPC の内外両方で、これらのすべての部分が相互に通信できるようにするのが難しい場合があります。通信を促進する方法は複数ありますが、すべてにさまざまな利点と欠点があります。
Service Connect の使用
サービス検出、接続、トラフィックモニタリング用の Amazon ECS 設定を提供する Service Connect をお勧めします。Service Connect を使用すると、アプリケーションは短縮名と標準ポートを使用して、同じクラスターや他のクラスター (同じリージョンの VPC 間を含む) 内のサービスに接続できます。詳細については、「Amazon ECS Service Connect」を参照してください。
Service Connect を使用すると、Amazon ECS がサービス検出のすべての部分を管理します。つまり、検出可能な名前の作成、タスクの開始と終了時に各タスクのエントリを動的に管理すること、名前を検出するように設定された各タスクでのエージェントの実行などです。アプリケーションは DNS 名の標準機能を使用して接続することで名前を検索できます。アプリケーションがすでにこれを実行している場合、Service Connect を使用する際に、アプリケーションを変更する必要はありません。

変更はデプロイ中にのみ発生します
各サービスとタスク定義内で完全な設定を行います。Amazon ECS は、デプロイ内のすべてのタスクが同じように動作するように、サービスデプロイごとにこの設定の変更を管理します。たとえば、サービス検出の DNS でよくある問題は、移行の制御です。新しい IP アドレスを指すように DNS 名を変更すると、すべてのクライアントが新しいサービスの使用を開始するまでに最大 TTL 時間がかかることがあります。Service Connect では、クライアントデプロイメントがクライアントタスクを置き換えて設定を更新します。他のデプロイと同様に、Service Connect の変更に影響するように、デプロイサーキットブレーカーやその他のデプロイ設定を設定できます。
サービス検出の使用
サービス間の通信のもう 1 つのアプローチは、サービス検出を使用する直接的な通信です。このアプローチでは、Amazon ECS との AWS Cloud Map サービス検出の統合を使用できます。Amazon ECS はサービス検出を使用して、起動されたタスクのリストを AWS Cloud Map に同期します。このホスト名は特定のサービスの 1 つ以上のタスクの内部 IP アドレスに解決される DNS ホスト名を保持します。Amazon VPC の他のサービスは、この DNS ホスト名を使用して、内部 IP アドレスを使用してトラフィックを別のコンテナに直接送信できます。詳細については、「サービス検出」を参照してください。

前出の図では、サービスが 3 つあります。service-a-local
はコンテナが 1 つあり、コンテナが 2 つある service-b-local
と通信します。service-b-local
は、コンテナが 1 つある service-c-local
とも通信する必要があります。これら 3 つのサービスすべての各コンテナは、AWS Cloud Map の内部 DNS 名を使用して、通信する必要があるダウンストリームサービスからコンテナの内部 IP アドレスを見つけることができます。
このサービス間通信のアプローチでは、レイテンシが低くなります。一見すると、コンテナ間に余分なコンポーネントがないためシンプルでもあります。トラフィックは 1 つのコンテナから別のコンテナに直接移動します。
この方法は、各タスクに固有の IP アドレスが割り当てられる awsvpc
ネットワークモードを使用する場合に適しています。ほとんどのソフトウェアは、IP アドレスに直接変換される DNS A
レコードの使用のみをサポートしています。awsvpc
ネットワークモードを使用する場合、各タスクの IP アドレスは A
レコードになります。ただし、bridge
ネットワークモードを使用している場合は、複数のコンテナが同じ IP アドレスを共有している可能性があります。さらに、動的ポートマッピングでは、その 1 つの IP アドレスのポート番号がコンテナにランダムに割り当てられます。この時点では、A
レコードだけではサービス検出には不十分です。SRV
レコードも使用する必要があります。このタイプのレコードは IP アドレスとポート番号の両方を記録できますが、アプリケーションを適切に設定する必要があります。使用するビルド済みアプリケーションの中には、SRV
レコードをサポートしていないものもあります。
awsvpc
ネットワークモードのもう 1 つの利点は、サービスごとに固有のセキュリティグループがあることです。このセキュリティ グループを設定して、そのサービスと通信する必要がある特定のアップストリームサービスからの受信接続のみを許可することができます。
サービス検出を使用するサービス間直接的な通信の主な欠点は、再試行や接続障害に対処するためのロジックを追加する必要があることです。DNS レコードには、キャッシュされる時間を制御する有効期限 (TTL) があります。DNS レコードが更新されてキャッシュが期限切れになり、アプリケーションが最新バージョンの DNS レコードを取得できるようになるまでには、ある程度の時間がかかります。そのため、アプリケーションが DNS レコードを解決して、もう存在しない別のコンテナを指すようになってしまう可能性があります。アプリケーションには再試行を処理し、不正なバックエンドを無視するロジックが必要です。
内部ロードバランサーの使用
サービス間通信のもう 1 つの方法は、内部ロードバランサーを使用することです。内部ロードバランサーは完全に VPC 内に存在し、VPC 内のサービスにのみアクセスできます。

ロードバランサーは、冗長リソースを各サブネットにデプロイすることで、高可用性を維持します。serviceA
のコンテナが serviceB
のコンテナと通信する必要がある場合、ロードバランサーへの接続が開きます。次に、ロードバランサーは service B
からコンテナへの接続を開きます。ロードバランサーは、各サービス間のすべての接続を管理するための一元的な場所として機能します。
serviceB
のコンテナが停止すると、ロードバランサーはそのコンテナをプールから削除できます。また、ロードバランサーはそのプール内の各ダウンストリームターゲットに対してヘルスチェックを行い、再び正常になるまでプールから不正なターゲットを自動的に削除できます。アプリケーションは、ダウンストリームコンテナの数を認識する必要がなくなりました。ロードバランサーへの接続を開くだけです。
この方法は、すべてのネットワークモードで有益です。ロードバランサーは、awsvpc
ネットワークモードを使用する場合のタスク IP アドレスと、bridge
ネットワークモードを使用する場合の IP アドレスとポートのより高度な組み合わせを追跡できます。また、実際に複数のコンテナが異なるポートにおいて同じ Amazon EC2 インスタンスでホストされている場合でも、すべての IP アドレスとポートの組み合わせにトラフィックを均等に分散します。
この方法の欠点の 1 つはコストです。可用性を高めるために、ロードバランサーには各アベイラビリティーゾーンにリソースが必要です。この結果、ロードバランサーとロードバランサーを通過するトラフィック量に対して支払うオーバーヘッドにより、追加コストが追加されます。
ただし、複数のサービスでロードバランサーを共有することで、オーバーヘッドコストを削減できます。これは、Application Load Balancer を使用する REST サービスに特に適しています。ユーザーは、異なるサービスにトラフィックをルーティングするパスベースのルーティングルールを作成できます。例えば、/api/user/*
は user
サービスの一部であるコンテナにルーティングし、/api/order/*
は関連付けられた order
サービスにルーティングできます。この方法では、1 つの Application Load Balancer に対してのみ料金が発生し、API の URL が一貫した 1 つになります。ただし、トラフィックをバックエンドのさまざまなマイクロサービスに分割することはできます。