ECS ExecがどうもマネージドなSSM Agentを使って動いているということはわかっていたが、実際どうなっているのかよくわからなかった。
- New – Amazon ECS Exec による AWS Fargate, Amazon EC2 上のコンテナへのアクセス | Amazon Web Services ブログ
- デバッグに Amazon ECS Exec を使用する - Amazon ECS
- AWS Fargateで動いているコンテナにログインしたくて Systems Manager の Session Manager を使ってみた話 - SMARTCAMP Engineer Blog
- 踏み台EC2を廃止してSession Manager接続に置き換えました | by Daichi Harada | Eureka Engineering | Sep, 2021 | Medium
aws ssm start-session
を実行できそうな雰囲気があるが、--target
に何を渡せばいいのかよくわからなかった。
session-manager-pluginを実行しているようなので、aws ecs execute-command
を実行しつつpsコマンドを実行してみる。
sugawara 80091 0.1 0.1 5441620 17444 s002 S+ 4:39PM 0:00.11 session-manager-plugin {"sessionId": "ecs-execute-command-0acebb01a1ed41142", "streamUrl": "wss://ssmmessages.ap-northeast-1.amazonaws.com/v1/data-channel/ecs-execute-command-0acebb01a1ed41142?role=publish_subscribe", "tokenValue": "(省略)"} ap-northeast-1 StartSession {"Target": "ecs:hello_7412261320c54ef9a1ae606175e9bec1_7412261320c54ef9a1ae606175e9bec1-3811061257"} https://ecs.ap-northeast-1.amazonaws.com
"Target": "ecs:hello_7412261320c54ef9a1ae606175e9bec1_7412261320c54ef9a1ae606175e9bec1-3811061257"
なにこれ?
いろいろ探してみるがドキュメントが見当たらないのでaws cliのソースコードを読む。
def build_ssm_request_paramaters(response, client): cluster_name = response['clusterArn'].split('/')[-1] task_id = response['taskArn'].split('/')[-1] container_name = response['containerName'] # in order to get container run-time id # we need to make a call to describe-tasks container_runtime_id = \ get_container_runtime_id(client, container_name, task_id, cluster_name) target = "ecs:{}_{}_{}".format(cluster_name, task_id, container_runtime_id) ssm_request_params = {"Target": target} return ssm_request_params
クラスタ名・タスクID・コンテナIDでTergetを構築しているっぽい。
クラスタ名とタスクIDとコンテナの名前がわかっているなら以下のようにaws ssm start-session
を実行できる。
~% CLUSTER=hello ~% TASK_ID=7412261320c54ef9a1ae606175e9bec1 ~% CONTAINER_NAME=busybox ~% CONTAINER_ID=$(aws ecs describe-tasks --cluster $CLUSTER --task $TASK_ID | jq -r --arg CONTAINER_NAME $CONTAINER_NAME '.tasks[0].containers[] | select(.name == $CONTAINER_NAME).runtimeId') ~% aws ssm start-session --target ecs:${CLUSTER}_${TASK_ID}_${CONTAINER_ID} Starting session with SessionId: root-06ad4aa7ce3831373 #
ポートフォワードも可能。
~% aws ssm start-session --target ecs:${CLUSTER}_${TASK_ID}_${CONTAINER_ID} --document-name AWS-StartPortForwardingSession --parameters '{"portNumber":["8080"],"localPortNumber":["18080"]}' Starting session with SessionId: root-08212759680ea948b Port 18080 opened for sessionId root-08212759680ea948b. Waiting for connections... Connection accepted for session [root-08212759680ea948b]
~% curl localhost:18080 Hello World!
これでコンテナにstoneでも入れておけば、Fargateのタスクを踏み台にしてデータベースなどへのアクセスができる。 ドキュメントがないっぽいのがやや気になるが…