☕️

ECSタスク操作に便利な ecsta - fujiwara-ware advent calendar 2024 day 4

2024/12/04に公開

この記事は fujiwara-ware advent calendar 2024 の4日目です。

ecsta とは

https://github.com/fujiwara/ecsta

ecsta は、Amazon Elastic Container Service (ECS) のタスク(task)を操作するためのツールです。「エクスタ」と読みます。

なぜ作ったのか

ecsta は、ecspresso の一部機能を独立させたものです。

元々 ecspresso には ECS タスク定義とサービスを管理する機能のみがありました。

2021年4月にリリースされた ecspresso v1.5 で、ECSタスク(起動している個別のタスク)を操作する機能が追加されました。

  • ECSタスクにログインするための ECS Exec を行う ecspresso exec コマンド
  • ECSサービスで起動しているタスクの一覧や詳細を表示する ecspresso tasks コマンド

https://sfujiwara.hatenablog.com/entry/ecspresso-v1.5

ecspresso はタスク操作を行うためのツールとしても使えるようになりましたが、その後この機能は ecspresso で管理しているかどうかに関わらず、任意のタスクを操作するツールとして独立していてよいのでは? と思うようになりました。

そこで ecspresso v2 の開発時に ecsta を独立させることにしました。

つまり、以下のようにツールのスタンスを明確化したことになります。

  • ecspresso:「タスク定義」と「サービス」を管理するためのツール
  • ecsta:「タスク」を操作するためのツール

とはいえ ecspresso v1 との互換性もありますし、ecspresso から管理下のタスクを操作できること自体は単純に便利なため、ecspresso 側の機能は削除していません。ecspresso v2 からは ecsta のコードを分離し、ライブラリとして呼び出す形で実装しています。

ecspresso からタスク操作関連の機能を利用する場合には ecsta コマンドがインストールされている必要はありません。

ecsta の基本操作

ecsta は zero config で使えるように設計されています。設定ファイルは不要です。AWS の認証情報やリージョンは環境変数などから取得します。

ecsta の操作対象は ECS タスク(Exec関連のコマンドではタスク内のコンテナ)です。特に引数を指定しないで各コマンドを実行した場合、対話形式でクラスタ名とタスクIDを選択する UI が表示されます。

cluster-foo
my-cluster
Enter cluster name: 

AWSアカウントに存在するECSクラスタ (例: cluster-foo, my-cluster) が表示され、その中から選択できます。この入力は前方一致で選択できるので、例えば m と入力するだけで my-cluster が選択されます(対象を一つに特定できる最小の文字列を入力する必要があります)。

次に選択したクラスタに存在するタスクが表示され、タスクIDを選択する UI が表示されます。この入力も前方一致で選択可能です。

cluster name=my-cluster
472ddad8667247ae9dc728479163de42  dev-admin:1511  RUNNING    RUNNING 2024-12-03T14:45:43+09:00 service:admin       FARGATE
538bd6346f66464f92ebbb9a01e2f2f6  dev-app:1573    ACTIVATING RUNNING 2024-12-03T16:54:23+09:00 service:app FARGATE
5cc4e95a5bc24904abf757e1a2b7d811  dev-app:1572    RUNNING    RUNNING 2024-12-03T12:12:16+09:00 service:app FARGATE
4a88f06fd08a41b09632cf471c4700eb  dev-app:1573    STOPPED    STOPPED 2024-12-03T16:48:26+09:00 service:app FARGATE
Enter task ID: 

このように対話形式で操作対象のタスクを選択することができます。もちろん、コマンドライン引数で明示的にクラスタ名(-c)やタスクID(--id)、コンテナ名(--container)を指定することもできます。

ecsta configure

ecsta は zero config で使えますが、タスク選択のUIを任意の外部コマンドでカスタマイズできます。

filter_command として pecofzf などのフィルタリングツールを使ってタスクの選択を行うことができます。ここに指定できるツールの条件は「標準入力からタスク一覧を受け取り、選択されたタスクID(が行頭に含まれる行)を標準出力に出力する」ことです。

ecsta configure コマンドを実行すると、設定を行うための対話形式のUIが表示されます。

$ ecsta configure
2024/12/03 17:23:25 INFO configuration file path=/home/fujiwara/.config/ecsta/config.json
Enter filter_command (command to run to filter messages): peco
Enter output (output format (table, tsv or json)) [table]: 
Enter task_format_query (A jq query to format task in selector): 
2024/12/03 17:24:00 INFO saved configuration file path=/home/fujiwara/.config/ecsta/config.json

設定は $HOME/.config($XDG_CONFIG_HOME が定義されていればそちら)の ecsta/config.json に保存されます。設定ファイルを直接編集することもできます。

ecsta list

クラスタ内のタスク一覧を表示します。

ecsta describe

タスクの詳細を表示します。

ecsta logs

タスクのログを表示します。--follow オプションを指定するとログの追跡ができます。

ログは CloudWatch Logs に出力されている必要があります。ロググループやログストリームは自動で判別するため、タスクを特定するだけでそのタスクが出力しているログを表示できます。

ecsta exec

ECS Exec を使用してタスクにログインします。実行している環境に session-manager-plugin がインストールされている必要があります。

通常 ECS Execを行うためには制御端末(tty)が必要ですが、ecsta は非対話環境(例えば CI/CD パイプライン)でも利用できるように、自動的に仮想端末を割り当てる機能があります。ECS Execを利用した自動化に便利ですね。

ecsta exec --cluster foo \
           --id 472ddad8667247ae9dc728479163de42 \
           --container bash \
           --command "uptime"

ecsta portfoward

タスクのポートフォワードを行います。実装には ECS Exec を使用しています。

ssh コマンドでのポートフォワードと同様に、例えば -L 8080:localhost:80 と指定すると、ローカルの8080に接続することでタスクの80番ポートに繋がります。また、タスクを経由してさらにリモートホストのポートにもフォワードできます。-L 8080:example.com:80 と指定すると、ローカルの8080番ポートへの接続を example.com の80番ポートにフォワードします。

つまり、ECS タスクを実行している VPC 内のリソースにポートフォワード経由でアクセスできます。RDS や ElastiCache などの VPC 内に閉じたリソースに対して手元から直接アクセスできるのは便利ですね![1]

ecsta stop

タスクを停止します。

ecsta cp

タスクと ecsta を実行しているマシン間でファイルのコピーを行います。通常 ECS タスクとの間でファイルのやり取りを行うためには、S3 などの中間ストレージを利用する必要がありますが、ecsta cp を使うと直接ファイルのコピーができます。

具体的な仕組みとしては、ECS Exec + Port Forward を使用しています。

  1. ECS Exec でタスクにログインし、tncl という小さい(20KB程度)のコマンドをタスクの/tmp以下に作成後、実行します
    • tncl は tiny nc -l の略で、nc (netcat) コマンドと同様に TCP サーバを立ち上げることができます
    • tncl も fujiwara-ware です。後日紹介する予定です
  2. Port forward のセッションを開始し、ローカルのポートを tncl が listen しているポートにフォワードします
  3. ローカルのファイルを tncl に送信します / tncl からファイルを受信します
  4. コピーが終了すると tncl を停止します

タスクの OS は Linux のみ、アーキテクチャは X86_64 と ARM64 の両方をサポートしています(アーキテクチャは自動で判別します)。

大変便利ですが、外部から送り込まれたコマンドをタスク内に作成して実行し、さらにポートも開けるため(localhostのみ)、セキュリティ上のリスクが伴います。動作原理を理解した上でご利用することをお勧めします。

https://zenn.dev/fujiwara/articles/fujiwara-ware-2024-tncl

ecsta trace

tracer をライブラリとして内部で使用してタスクに発生したイベントやログを時系列で表示します。tracer については以下の記事を参照してください。

https://techblog.kayac.com/ecs-task-tracer

ECS タスクが上手く起動しないときなど、デバッグに大変役立ちます。

tracer については、明日の記事で詳しく紹介します。

https://zenn.dev/fujiwara/articles/fujiwara-ware-2024-tracer

まとめ

ECS タスクの操作に特化した ecsta を使うことで、ECS タスクのログの確認やデバッグ、ファイルのコピー、ポートフォワードなどが簡単に行えます。

ecspresso と異なり設定ファイルが不要なため、簡単に使い始めることができます。ぜひお試しください。

それでは、明日もお楽しみに!

関連記事

https://zenn.dev/quiver/articles/56b05ba75e6295

https://dev.to/atsushii/execute-ecs-task-by-ecsta-44io

脚注
  1. セキュリティグループなどの設定に依存します。また、本番環境での利用にはセキュリティ上のリスクが伴うため、慎重に扱ってください。 ↩︎

Discussion