ECS on EC2でECS Execがエラーになるときはネットワークモードを確認しよう

2024.04.01

ゲームソリューション部の えがわ です。

ECS on EC2環境をTerraformで構築していますが、ECS Execがエラーとなり接続できませんでした。
原因の特定に時間がかかってしまったので、備忘録として残しておきます。

エラー内容

egawa:~$ aws-vault exec personal -- aws ecs execute-command --cluster {my-cluster} --task {task-id} --container {container-name} --interactive --command "/bin/sh"

The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.

An error occurred (TargetNotConnectedException) when calling the ExecuteCommand operation: The execute command failed due to an internal error. Try again later.

最初に結論

タスク定義のネットワークモードに問題がありました。
コンテナがインターネットに接続できていなかったため、ECS Execがエラーとなっていました。

ECS on EC2でawsvpcのネットワークモードを使用する場合、制約があります。

Amazon EC2 Linux インスタンスで awsvpc ネットワークモードを使用するタスクをホストする場合、タスク ENI にはパブリック IP アドレスが付与されません。インターネットにアクセスするには、NAT ゲートウェイを使用するよう設定されたプライベートサブネットでタスクを起動する必要があります。詳細については、「Amazon VPC ユーザーガイド」の「NAT ゲートウェイ」を参照してください。インバウンドのネットワークアクセスは、プライベート IP アドレスを使用する VPC 内からのものか、その VPC からロードバランサーを経由させルーティングされたものである必要があります。パブリックサブネット内で起動されたタスクは、インターネットにアクセスできません。

awsvpcモードで接続する場合はEC2をプライベートサブネットに配置し、NATゲートウェイ経由で外にでる必要があります。
NATゲートウェイの料金も節約したい、かつ、EC2もパブリックサブネットで問題ないため、bridgeに変更することで解決しました。

環境

  • Terraform(v1.7.3)
  • ECS on EC2

確認事項

Amazon ECS Exec Checkerで設定確認

タスク定義やIAM、VPCの設定を確認できます。

設定は問題なさそうです。

Reachability Analyzerで疎通確認

ECSタスクのENIからVPCエンドポイントのIDまで疎通確認を行ってみます。

疎通も問題なさそうです。

コンテナに入ってインターネットに接続してみる

EC2にSSMで接続し、コンテナにアクセスしてみます。

[root@ip-10-0-1-48 ~]# docker exec -it {container-name} bash
my-container@ip-10-0-1-246:/$ curl https://classmethod.jp


^C
my-container@ip-10-0-1-246:/$

むむ...!タイムアウトしました!
コンテナがインターネットに接続できないことが原因のようです。

ネットワークモードを変更

awsvpcからbridgeに変更します。

resource "aws_ecs_task_definition" "main" {
  family             = "${var.project_name}-taskdef"
  network_mode       = "bridge" # "awsvpcからbridgeに変更"
  execution_role_arn = var.exec_role_arn
  task_role_arn      = var.task_role_arn
...中略
}

変更をデプロイして再度確認してみます。

[root@ip-10-0-1-48 ~]# docker exec -it {task-name} bash
my-container@ac426e6995e9:/$ curl https://classmethod.jp
<!doctype html>
<html lang="ja">
...中略

コンテナからインターネットに接続できました!

ECS Execも確認してみます。

egawa@HL01559:~$ aws-vault exec personal -- aws ecs execute-command --cluster {my-cluster} --task  --container {container-name} --interactive --command "bash"

The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.


Starting session with SessionId: ecs-execute-command-09aa98ee275355a78
root@ac426e6995e9:/#

ECS Execが成功しました!

最後に

ECS on EC2を初めて構築してみましたが、思いもよらないところに落とし穴がありました。
Fargateだと深く考えずにawsvpcを選択していましたが、ネットワークについて考えるきっかけになりました。
どなたかの参考になれば幸いです。