ECS on EC2でECS Execがエラーになるときはネットワークモードを確認しよう
ゲームソリューション部の えがわ です。
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
を選択していましたが、ネットワークについて考えるきっかけになりました。
どなたかの参考になれば幸いです。