一、背景
之前介绍过使用System Manager套件中的Session Manager免密钥登录EC2,可参考这篇文章。针对ECS容器服务,因为开发、调试和运维的需要,也希望能登录到容器内部的shell上进行操作。此场景可使用ECS服务的exec功能在容器上执行shell命令的功能。
本文档适用于ECS Fargate和ECS Fargate spot,并在中国区测试通过。
二、准备工作
1、构建容器
正常构建一个容器镜像,无需额外安装System Manager Agent(简称SSM Agent)。在EC2上如果希望使用Session Manager,那么是需要为AMI事先安装SSM Agent。在ECS上服务不需要这一步,在启动容器时候,ECS服务会完成Agent加载。因此,在构建镜像阶段,只需要正常构建并上传到ECR即可。
2、安装AWSCLI的Session Manager plugin
根据官网文档下载并安装Session Manager plugin,然后建议通过登录一台EC2验证测试Session Manager plugin工作正常。具体登录EC2的方法可参考这篇文章。
3、配置ECS运行任务定义时候调用Session Manager的IAM策略
ECS的容器运行是由任务定义配置文件指定的,并且每个容器都会作为一个任务启动。任务是使用ECS任务角色来定义运行权限的。如果之前按照ECS标准教程,那么系统会创建名为ecsTaskExecutionRole
的IAM角色。如果之前是手工创建的角色,请查找对应的名称。
找到ECS任务运行角色后,点击进入,然后附加Inline策略。如下截图。
接下来新配置如下策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Resource": "*"
}
]
}
粘贴好之后,点击右下角的Review Policy
的按钮。如下截图。
输入策略名称,点击创建策略,如下截图。
至此IAM策略配置完成。
三、配置ECS服务并启用
1、启动ECS服务
在完成前文任务执行角色修改的情况下,正常完成ECR的任务定义(Task定义),正常启动服务(Service)。
2、修改服务参数打开远程执行
修改ECS服务需要通过AWSCLI,并且输入ECS集群的名称和服务名称。通过AWS控制台可以查询集群名称和服务名称。如下截图。
查询到集群名称和服务名称后,拼接如下命令。
aws ecs describe-services --cluster ECS-fargate --service phpdemo
在上述返回结果包含的输出信息超过一个屏幕显示,按空格键来到最后一屏幕,可看到如下返回信息。如下截图。
其中最后几行可以看到(节选):
"createdBy": "arn:aws-cn:iam::420029960748:role/admin",
"enableECSManagedTags": true,
"propagateTags": "NONE",
"enableExecuteCommand": false
}
],
"failures": []
}
上述节选内容,表示当前服务的enableExecuteCommand
开关是关闭的,也就是不允许远程执行shell。为此需要打开这个参数。
执行如下命令更新ECS服务,请代入您的集群名称和服务名称,然后执行:
aws ecs update-service --cluster ECS-fargate --service phpdemo --enable-execute-command --force-new-deployment
注意这个命令将强制重新部署新版本的服务。ECS会在不停止原有容器的基础上,先启动新的容器,确保加入ELB健康检查稳定后,再将旧的容器退出流量分发,然后停止旧的容器。
在执行这个命令的返回结果中,最后几行即可看到"enableExecuteCommand": true
。由此即表示本服务下的容器都已经打开了Session Manager远程执行功能。如下截图。
3、登录到容器
登录到容器是一个ECS服务下的单个Task(容器)作为最小单位进行登录的,因此要先确定登陆哪一个容器,也就是对应哪一个Task。注意服务和任务的对应关系是:一个服务可能有很多任务(容器),每个任务有自己的ID。因此查询要登陆的Task对应的ID,才可以启动shell。
通过ECS控制台界面,进入到集群,点击服务进入到服务,切换到任务标签页,即可看到当前服务有两个任务。现在复制下来其中一个任务ID即85d2289b435f44bfb229d5a7c8be8a4a
,此外还需要确认Task任务定义中的容器名称。如下截图。
然后拼接如下命令并执行:
aws ecs execute-command --cluster ECS-fargate --container phpdemo --task 85d2289b435f44bfb229d5a7c8be8a4a --interactive --command "/bin/bash"
由此就可以看到,使用shell登录容器成功。如下截图。
现在即可在本地开发环境上,通过Session Manager远程登录到ECS服务中的某个容器,开始远程调试。
四、参考文档
ECS Exec使用:
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html
全文完。