ECS コンテナ間通信のベストプラクティス
こちらのAWS公式のドキュメントではECSコンテナ間通信のベストプラクティスとして、3つの方法が紹介されています。
自分の備忘録として、それぞれの特徴、どのような場面で使用するべきかまとめたいと思います。
サービス検出
特徴
サービス検出は、動的に変化するコンテナのIPアドレスを管理し、サービス間通信を行います。Amazon ECSでは、サービス検出のためにAWS Cloud Mapを使用します。Cloud Mapは、サービス名をIPアドレスにマッピングし、DNS名前解決を行います。
イメージ
設定例
解説
-
example
という名前空間がCloud Map上に作成され、app-example
という名前で、サービスが紐づけられます - Route53ではプライベートホストゾーン
example
が作成され、レコードとしてapp-example.example
が設定されます - ECSのコンテナから
app-example.example
ドメインに接続すると、このサービス検出が設定されたサービスに接続することができます
デメリット
- サービス検出に関してのトラフィックのログが収集できません
- これがどの程度のデメリットになるかは正直よくわかっていませんが、サービス検出を起因とした障害が起きた場合はトラブルシューティングが困難になる可能性があります
Service Connect
特徴
Service Connectは、ECSサービス間の通信を簡素化し、管理を容易にするための機能です。Service Connectでは、サービスのエンドポイントを定義し、そのエンドポイントを通じて通信を行うことができるため、サービスのアドレスやポート番号を直接管理する必要がなくなります。
イメージ
サービスへのエンドポイントに接続するための、プロキシが別途コンテナとして立ち上がるイメージです。
ポートでタスク内のコンテナに振り分けることができます。
設定例
クライアントとサーバー
クライアント側
解説
- Cloud Map上に
example
という名前空間を先に作成しておきます - クライアントとサーバー
- Service Connectの設定は
クライアントとサーバー
を選択します - 名前空間
example
にサーバー側のサービスをapp
として登録します - サービスがデプロイされるとタスクの中にプロキシコンテナが立ち上がります
- Service Connectの設定は
- クライアント側
- Service Connectの設定は
クライアント側のみ
を選択します - 名前空間
example
を選択して、example
にあるコンテナに接続できるようにします - サービスがデプロイされるとタスクの中にプロキシコンテナが立ち上がります
- この例では http://app:4000 で接続することができます
- Service Connectの設定は
クライアント側のhostsファイル
# cat /etc/hosts
127.0.0.1 localhost
10.20.10.30 ip-10-20-10-30.ap-northeast-1.compute.internal
127.255.0.1 app
2600:f0f0:0:0:0:0:0:1 app
appが登録されていることがわかります
デメリット
- こちらに記載されている通り、Service Connect でサポートされるのは、ローリングデプロイを使用するサービスのみなので、Blue/Greenデプロイは使用できません
- プロキシコンテナを立ち上げるためにリソースを追加する必要があるため、それに応じてコストが増えます
内部ロードバランサーの使用
English版のドキュメントだとなくなっているので、さっくり説明・・・
特徴
内部ロードバランサーは、サービス間のトラフィックを分散させ、負荷分散を行うために使用されます。ロードバランサーを内部的に使用して、コンテナ間接続を実現できます。
イメージ
解説
- ロードバランサーをサブネットに配置します
- イメージ図ではサブネットとの間にありますが、実際はサブネットに属しています
- ターゲットグループを作成して、サービスタスクのコンテナを紐づけます
- コンテナには http://[ロードバランサーのドメイン名]:[ポート番号] で接続できます
- 1つのロードバランサーで複数コンテナに振り分ける場合は、ポート番号が重複しないようにする必要があります
デメリット
- 内部ロードバランサーの使用には追加のコストが発生します。
補足
こちらの方のようにサービス検出やService Connectの導入が難しい場面でロードバランサーを使うのは有効だと思います。
おまけ
localhostでの通信
同じタスク内で起動しているコンテナはlocahostで接続できます。
もちろんポートは分ける必要があります。
まとめ
個人的な感覚としては
- 基本的にサービス検出、Service Connectを使う
- コストが気になったり、Blue/Greenデプロイをしたい場合はサービス検出を使う
- サービス検出、Service Connectを使うことができない場面ではロードバランサーの使用を考える
という感じです。
Service ConnectがBlue/Greenデプロイに対応したら、サービス検出もほぼ使わなくてよくなりそうなので、今後のAWSの動向に注目です。
参考
参考にさせていただきました、ありがとうございます!
Discussion