every Tech Blog

株式会社エブリーのTech Blogです。

ECS Fargate を検証するために ECS Exec を使用した話

f:id:hueless:20220302185515p:plain

tl;dr

  • Fargate ではホストが隠蔽されていて、EC2 のように SSH でコンソールに入って検証することができない
  • ECS Exec は十分に SSH の代用となる
  • ECS Exec の導入に必要なことはこのセクションを参照

DELISH KITCHEN on ECS

弊社では DELISH KITCHEN というサービスを運用しており、主なアプリケーションサーバは ECS の上に構築しています。

ECS には EC2 によるものと、Fargate によるものの2つの環境が存在しますが、現時点ではほぼ全てのアプリケーションサーバが EC2 の環境です。

ECS は、十分な機能を備えながらシンプルで柔軟に運用できる優れたコンテナオーケストレーションサービスです。

しかしながら、EC2 環境においては常にホストとなる EC2 インスタンスをメンテナンスする必要があります。

それほど頻繁に発生する作業ではありませんが、定期的に AMI を更新しなければなりませんし、ECS 以外にホストで動作させているものがあれば、新しい AMI でも同様に動作するかの検証が必要になります。

また、EC2 の定期メンテナンスを行なっても、基本的にサービスへの影響がないことも、どのタイミングでメンテナンスを行うべきかの判断を難しくさせます。

同じだけ人員と工数をかけるのであれば、サービスにとってプラスになるタスクを優先したいというのは当然の考えです。

必然的にこのようなタスクは後回しになりますが、何らかの理由で(多くの場合はセキュリティに起因します)本当に作業が必要になった時には、それまでに積み重なっていた問題を一度に解決しなくてはいけないような状況に陥ることすらあります。

DELISH KITCHEN on Fargate

Fargate とは、ECS 上でコンテナのホストとなる EC2 の管理を不要にし、ECS タスクの管理に集中することができるサービスです。

DELISH KITCHEN で Fargate を採用できれば、前述したようなインスタンスの管理に必要なタスクが削減でき、よりサービスの開発に注力できるようになります。

これは 2022年 エブリーの開発組織の抱負 にある 事業にこだわる開発組織 にもマッチしており、導入に向けて検証を進めることになりました。

検証を進めていく中で、一番ネックになったのはホストに SSH ができないことです。

従来の EC2 環境ではホストに SSH 後、docker exec 経由でコンテナの内部の調査ができたのですが、Fargate ではホストも docker も隠蔽されており、通常はアクセスすることができません。

最初は原始的にアプリケーション自体に printf デバッグを仕込んだりしていたのですが、あまりに効率が悪いため、ECS Exec を導入しました。

ECS Exec の評価

ECS Exec では以下のようなコマンドで shell を実行できます

aws ecs execute-command --cluster "$CLUSTER" --task "$TASK_ID" --container "$CONTAINER_NAME" --interactive --command sh

shell だけ使うならほとんど SSH と使い勝手は変わりません。強いて言うならタイムアウトが 20 分とやや短いのと、その設定がグローバルでしか設定できないところが使い勝手が悪いでしょうか。

scp でファイルの送受信ができないことも困るタイミングがありますが、s3 を経由するのが一般的な解決法のようです。

port forwarding は ECS Exec では提供されませんが、大元の SSM では提供されています。 targetに ecs:{CLUSTER}_{TASK_ID}_{CONTAINER_NAME} を指定すれば Fargate で起動しているタスクへのセッションが開始できます。

例えばコンテナ内の nginx に port forwarding するなら

aws ssm start-session \
    --target "ecs:${CLUSTER}_${TASK_ID}_${CONTAINER_NAME}" \
    --document-name AWS-StartPortForwardingSession \
    --parameters '{"portNumber":["80"], "localPortNumber":["$LOCAL_PORT"]}'

のようにします。

Fargate への道

このように、多少の制限はあるものの、Fargate でも従来の使い勝手に近い形でアプリケーションの調査ができることが確認できました。

現在は引き続き Fargate の評価と移行準備を行なっており、次回があればその話をできれば良いと考えています。

また、ECS Exec を有効化するのにいくつか戸惑った点があったため、最後にドキュメントと共に補足としてまとめておきました。参考になれば幸いです。

ECS Exec の有効化

ECS Exec を利用するためには、事前にいくつかの準備が必要になります。 公式のドキュメント の通りにすれば良いのですが、セッションマネージャープラグインのインストールを見落としやすいため、注意が必要です。

こちらのドキュメントではプラグインのインストールに関するリンク先が英語のみですが、こちらにほぼ同様のものの日本語版があります。

以下にドキュメントの各セクションについて補足の説明を記載します。

ECS Exec を使用するための考慮事項

このセクションでは特に以下の点に注意すれば良いでしょう

  • ECS Exec は linux でしか動作しない
  • 既存のタスクは変更できない(設定後に新しく配置されたタスクから有効になる)
  • コマンドは root からのものになる
  • デフォルトのセッションタイムアウトは 20 分

ECS Exec を使用するための前提条件

aws cli は余程古いバージョンを使っていない限り問題にならないでしょう。

前述の通り、プラグインのインストールが必要になります。aws cli のセットアップ後、ドキュメントに従って各自の環境に合わせたプラグインをインストールしましょう。

Fargate のバージョンも、最近作られたサービスなら問題にならないと思いますが、2021/03/19 より以前に作られたものの場合、注意が必要です。

ECS Exec の有効化と使用

最低限 IAM の設定とサービス(ないしタスク)の設定をすれば ECS Exec を使用できるようになります。 対象がサービスの場合、設定だけでなく、タスクの再配置が必要になります。ウェブコンソールからの場合、"サービスの更新"から"新しいデプロイの強制"を有効にすると設定を変えずにタスクを再配置することができます。

現時点ではウェブコンソールからはサービスやタスクについて、ECS Execを有効にするための機能は提供されていません。ドキュメントに従い、--enable-execute-command 引数を使って aws cli から設定する必要があります。

aws ecs execute-command で SessionManagerPlugin is not found というエラーが出る場合、セッションマネージャープラグインが認識されていません。初回の設定後、シェルやマシンの再起動などが必要な場合があります。