ECS の「サービス検出」と「Service Connect」を AWS マネジメントコンソールから作成してみる

記事タイトルとURLをコピーする

こんにちは🐱
カスタマーサクセス部の山本です。
本記事では、ECS の「サービス検出 (サービスディスカバリ)」と「Service Connect」を AWS マネジメントコンソールから作成する方法を記載します。
この 2 つの機能について、AWS マネジメントコンソールでは以下の違いがあります。

  1. 「サービス検出」については、「新しい ECS エクスペリエンス」を無効にしないと設定できない
  2. 「Service Connect」については、「新しい ECS エクスペリエンス」を有効にしないと設定できない

本記事では、AWS マネージメントコンソールでそれぞれの機能を有効にして、ECS サービスを作成する方法について、見ていきます。🐱
前提として、タスク定義、クラスターは作成済みとします。
また、東京リージョンの ECS on Fargate 環境とします。

注意

ECS の古いコンソール画面(クラシックコンソール)で設定できていたのに、新しいコンソール(「新しい ECS エクスペリエンス」)ではできない設定が、いくつかあります。
「サービス検出」もその一つです。Fire Lens や App Mesh もその一つです。

そして、古いコンソール(クラシックコンソール)が 2023 年 12 月 4 日に使用できなくなります。

今までAWS App Mesh や サービスディスカバリ などの設定を、古いコンソール(クラシックコンソール)で実施していた場合には、2023 年 12 月 4 日には別な運用を実施する必要があります。
新しい Amazon ECS コンソール にある情報が今のところはまとまっていそうです。
もちろん、新しいコンソール(「新しい ECS エクスペリエンス」)でしかできないこともあるので、新しい方に移行していくことが推奨されます。
例えば、新しいコンソールでは、Fargate 選択時の CPU アーキテクチャに ARM を選択することができます。

新しいコンソールでは、AWS Distro for OpenTelemetry 統合も設定可能です。

ECS の 「サービス検出」を AWS マネジメントコンソールから作成する(「新しい ECS エクスペリエンス」は無効)

サービス検出 の概要は以下の記事に記載していますので、よろしければご参照ください。
blog.serverworks.co.jp

対象となる ECS クラスターの画面の、「サービス」タブから「作成」ボタンを押します。

「サービス名」に サブドメインを入力します。

次の画面で「サービスの検出 (オプション)」にチェックを入れます。

「名前空間名」はデフォルトで local となります。変更も可能です。
「サービスの検出名」には先程入力したサブドメイン名が入っています。
作成したサービスを表すレコードは、「サブドメイン名.local」になります。(画像の例の場合は service-a.local)

そして、「次のステップへ」を押したら TTL を入れ忘れていてエラーになったので、入れます。 🐱 TTL は必須です。

作成後の確認については、以下ブログの目次「確認」に記載がありますので参照ください。

blog.serverworks.co.jp

サービス検出は、サービス作成時に 1 回しか設定できません。
他、制約等は上記のブログもご参照ください。

ECS の 「Service Connect」を AWS マネジメントコンソールから作成する(「新しい ECS エクスペリエンス」は有効)

Service Connect の概要は以下の記事に記載していますので、よろしければご参照ください。

blog.serverworks.co.jp

名前空間の作成

クラスターの作成時にデフォルトの名前空間を指定します。

クラスターができました。

名前空間も作成できています。この名前空間は CloudMap のサービス画面からも確認可能です。

なお、クラスターを作らずに名前空間のみを作成する場合は、CloudMap のサービス画面から行います。

名前空間名に任意の名前を入れ、「インスタンスの検出」に 「API 呼び出し」を指定して作成します。

作成後は ECS の名前空間からも確認できます。

サービスの作成

クラスターの画面から「サービス」タブを開いて「作成」ボタンを押します。

事前に準備したタスク定義の情報をもとに、ファミリー・リビジョンを入力します。また、任意のサービス名を入れます。このサービス名は 名前解決とは無関係です。運用のしやすさを考えると、下で設定する Service Connect の設定と合わせると良さそうです。

「Service Connect をオンにする」にチェックを入れ、「クライアントとサーバー」にチェックを入れます。(サービスが名前解決をする側になる場合は、「クライアント側のみ」にチェックを入れます。名前解決をされる側、提供側にもなる場合には「クライアントとサーバー」にチェックを入れます。)
「名前空間」には先に作成した名前空間名を選択します。
「ポートマッピングとアプリケーションを追加」を押します。

「ポートエイリアス」「検出」「DNS」「ポート」を入力します。

  • 「ポートエイリアス」はタスク定義の「ポートマッピング」に指定した「ポート名」です。
  • 「検出」は CloudMap の名前空間内のサービス名です。作成する ECS サービス名と合わせるのが良いでしょう。同じ名前空間内でサービス名は重複できません。
  • 「DNS」は実際に名前解決に用いるレコードです。任意の値を指定します。
  • 「ポート」は追加の接続ポートです。このポート番号への接続を、コンテナの待受ポート(タスク定義の「ポートマッピング」に指定したポート)に転送してくれます。

名前解決のログ収集にはチェックを入れておきましょう。

サービスを作成します。

Service Connect の動作確認

作成後には ECS サービスの「設定」タブから設定内容を確認できます。

ECS Exec でコンテナにログインし、/etc/hosts を確認したところ、DNS 登録した「test1-service1.test」のレコードがあります。

Service Connect の設定時に決めた「DNS名:ポート番号」(http://test1-service1.test:8080)に curl すると、コンテナの待ち受けポート(タスク定義の「ポートマッピング」に指定したポート)に転送してくれました。

また、コンテナの待受ポートである 80 番には、「DNS名:ポート番号」(http://test1-service1.test:80)では接続できませんでした。

コンテナの IP アドレスを直接指定すると コンテナの待ち受けポートでも接続可能です。(使わないとは思います。一応確認しました。)

複数サービス間で相互に名前解決できるか確認してみる

上(「サービスの作成」)と同じ手順で Service Connect が有効な ECS サービスをもう一つ作り、相互に名前解決できるか確認してみます。

test1-service2 という名前にしました。(DNS名:ポート番号は http://test1-service2.test:8080

test1-service2 の hosts ファイルには、test1-service1 と test1-service2 のレコードがあります。

test1-service2 のコンテナから test1-service2.test に curl すると接続できました。

また、test1-service2 のコンテナから test1-service1.test に curl すると接続できました。

このタイミングで、test1-service1 のタスクを停止して、新しいタスクを起動してみます。

test1-service2.test のコンテナから test1-service1.test に curl すると接続できました。

test1-service1.test のコンテナで hosts ファイルを見てみると、test1-service2 のレコードがありません。
既存の test1-service1.test のサービスで新しいタスクを起動しても、新しいサービス (test1-service2.test )の名前は解決できません。

公式ドキュメントを見ると、これは仕様のようです。 複数のサービスから名前解決が必要なバックエンドのサービスから先に、Service Connect の設定をしてデプロイするように公式ドキュメントに記載があります。

既存のタスクを解決して新しいエンドポイントに接続することはできません。このエンドポイントを解決して接続できるのは、同じ名前空間に Service Connect 設定があり、このデプロイ後に実行を開始した新しい Amazon ECS タスクだけです。例えば、クライアントアプリケーションを実行する Amazon ECS サービスは、新しいデータベースサーバーエンドポイントに接続するために再デプロイする必要があります。サーバーのデプロイが完了したら、クライアントのデプロイを開始します。

Service Connect concepts - Amazon Elastic Container Service

発見したこと (2023/9/26 追記)

上(「複数サービス間で相互に名前解決できるか確認してみる」)の状態で以下を実施すると、相互に名前解決できるようになりました。
困ったときに使えるかもしれません。

  1. test1-service1 の ECS サービスを更新して、Service Connect の設定を「クライアント側のみ」にしてデプロイ
  2. test1-service1 の ECS サービスを更にもう一回更新して、Service Connect の設定を「クライアントとサーバー」にし、以前と同じ値でデプロイ

「サービスを更新」します。

「クライアント側のみ」にしてデプロイします。

「クライアントとサーバー」にし、以前と同じ値でデプロイします。

「test1-service1」のコンテナの hosts に「test1-service2.test」のレコードが追加になっています。

「test1-service2.test」に名前解決できています。

test1-service2 のコンテナの hosts は特に変更ありません。

test1-service2 のコンテナからも「test1-service1.test」に名前解決できています。

おまけ

Service connect の AWS CLI でのチュートリアルが公式ドキュメントにございます。こちらもご参照ください。
参考:チュートリアル: AWS CLI を使用した Fargate での Service Connect の使用 - Amazon Elastic Container Service

余談

リフレッシュに近所の山を歩いてきました。風が気持ち良かったです。

山本 哲也 (記事一覧)

カスタマーサクセス部のエンジニア(一応)

好きなサービス:ECS、ALB

趣味:トレラン、登山(たまに)