はじめに
Amazon ECSでのサービス間通信の手法について調べていると、最終的にECS Service Connectに辿り着きました。ただ、こちらは既存の複数の手法を踏襲しており、知らない概念もいくつかありました。この記事では個人的な備忘録もかねてこのECS Service Connectを使用する際に押さえておくべき基本的な概念や実際の通信の流れについて説明します。
ECS Service Connectの概要
ECS Service ConnectはECSのサービス間通信を管理するための機能です。Amazon ECSでサービス間を実現する方法として、従来はELBを用いた方法、ECS Service Discoveryを用いた方法、App Meshを用いたものがありましたが、これらの手法のいいとこどりをしたような手法となっています。
ECS Service Connectのざっくりとした動作原理としては、タスク同士が直接通信するのではなく、ECSタスク内にService Connect Agentというコンテナをサイドカーとして追加し、これをプロキシとしてサービス間の通信を制御する仕組みとなっています。
なお、このECS Service Connectはサービスディスカバリとサービスメッシュという概念が背後にあるので、これらの概念について先に見ていきます。
サービスディスカバリとは
サービスディスカバリとは、分散システムやマイクロサービスにおいて、サービス同士が動的に相手を見つけて通信できるようにするための仕組みです。マイクロサービス環境下で多数のコンテナ上で稼働している場合、コンテナの起動や停止が起きるたびに新しいアドレスを持つことになり、アドレスの管理が困難となります。サービスディスカバリでは、従来のように固定のIPアドレスや手動設定を使うのではなく、サービスのエンドポイントが自動的にレジストリに登録され、他のサービスはレジストリを通じて動的にエンドポイントを取得し、通信を行います。 これにより、サービスのスケールや変更に柔軟に対応できるようになります。
ECS Service Discoveryでの通信
Amazon ECSではECS Service Discoveryという機能があり、これによってサービスディスカバリの実装が可能です。なお、サービスディスカバリを利用する際には、各コンテナやインスタンスの起動時にそれらが自身のサービス情報を自動的に登録するサービスレジストリが必要となります。AWSでは、この役割をAWS Cloud Mapが担っています。
ECS Service Discoveryでは、ECSサービスの作成時に指定した名前空間名に対応するCloud Mapの名前空間及びRoute53のプライベートホストゾーンが自動的に作成されます。ECS内のタスクが増減すると、Cloud Mapによってタスク動的に検出され、Aレコード(DNSレコード)がこのプライベートホストゾーンに自動的に登録されます。通信時には、このAレコードに対して名前解決が行われます。
なお、この手法ではRoute53のプライベートホストゾーンを使用して名前解決が行われるので、異なるVPC間での名前解決を行う際は、対象のVPCのプライベートホストゾーンへの紐づけが必要になります。また、タスク同士が直接通信しているので、テレメトリデータを取得することは出来ません。
サービスメッシュとは
サービスメッシュとは、各マイクロサービスにプロキシを配置し、サービス間通信をこのプロキシを経由させることでトラフィックの制御やセキュリティ、可観測性の向上を行う仕組みです。マイクロサービス環境下では、サービスごとに異なるプログラミング言語や実行環境を使用することが多く、統一した方法での通信制御やエラーハンドリングの実装が複雑になります。サービスメッシュではこれらの処理をプロキシに任せることで、アプリケーションからエラーハンドリングやリトライ処理などのネットワーク関連のロジックを切り離すという狙いがあります。
AWS App Meshでの通信
App Meshは2026年9月30日でサポート終了予定となっています。
https://aws.amazon.com/jp/blogs/news/migrating-from-aws-app-mesh-to-amazon-ecs-service-connect/
AWSではApp Meshというサービスメッシュを構築するためのマネージドサービスが存在します。App MeshではEnvoyプロキシというものを使用して各コンテナ間の通信を処理し、メトリクスの収集や通信の制御を行います。 EnvoyはOSSのプロキシソフトで、Istioという有名なOSSのサービスメッシュの実装においても使われています。
ECSでApp Meshを使う場合、ECS Service Discoveryの場合と同様にCloud Mapによるサービスの検出を行った上での名前解決が可能ですが、通信自体はEnvoyプロキシ経由で行われます。また、App MeshではDNSによる名前解決以外にもgRPCやHTTPヘッダーベースの通信も可能です。
App Meshないしはサービスメッシュ全般の実装はかなり複雑なので、実装のこれ以上の説明はここでは割愛します。
App Meshでは自前でコードを実装せずともサービス間通信に関するメトリクスやログを収集出来たり、E2Eの暗号化を実施することが可能です。ただし、App Meshやサービスメッシュ固有の概念も多く、設定も複雑になるといったデメリットがあります。
ECS Service Connectでの通信
ECS Service Connectはこれまで述べたECS Service DiscoveryとApp Meshを統合したy手法になっています。
最初に述べたように、ECS Service Connectではサービス内にEnvoyを含むコンテナをサイドカーとして追加し、これをプロキシとして通信を制御します。より具体的には、タスク内にEnvoyとAgentの2つのコンポーネントを持つService Connect Agentが追加されます。これにより、サービスメッシュの利点であるテレメトリデータの取得および、エラーハンドリングやリトライ処理といった通信の制御が可能となります。ただし、ECS Service ConnectではApp Meshとは異なり、プロキシの設定や管理をAWSが自動的に行います。そのため、ユーザーはプロキシの設定を意識せずともサービス間通信を利用できます。また、Serivce Discoveryとは異なりRoute 53のプライベートホストゾーンを経由しないので、異なるECSクラスターやVPC間であっても名前空間が同じであれば通信が可能となります。
なお、このサイドカーしてデプロイされるコンテナにはタスク定義が存在せず、ユーザーが設定することはできません。良くも悪くも、このプロキシによる通信はブラックボックス化されています。
実際にAWS上で作成した際は、ecs-service-connect-XXXXXXX
のような形でコンテナが追加されます。以下はnginxのタスクをデプロイしてみた際の例です。
まとめ
クラウドの進化に伴って通信方法も色々試行錯誤されているのが伺えました。今回は概念的な部分での調査しか出来ていないので、今後はもう少し実際のワークロードで適用する際の設定などについても調べたいです。