For AWS Cloud engineers working with containers, oftentimes there will be a need to connect to the Docker Container running on AWS ECS Fargate.
This may be to debug, troubleshoot issues, application configuration, application testing, container customization, security, monitoring, and many other use cases.
But by default, Fargate containers do not provide direct shell access to the underlying infrastructure or the container instances.
In this article we discuss on how to access the container shell which “at times”, can save a lot of time.
In this two part article, we walk you through the,
- Prerequisites
- Steps to Access the interactive shell of a docker container running on AWS ECS Fargate
- Steps to Find the disk space of AWS ECS Fargate Container
- Steps to Increase the disk space of the container running on ECS Fargate
- Common errors and troubleshooting steps
Part 1 – Discusses the prerequisites and the steps to access the interactive shell of a docker container running on AWS ECS Fargate.
Part 2 – Discusses the steps to find and increase the disk space of a docker container on AWS ECS Fargate and also the common issues and troubleshooting steps.
Click here to read Part 2 of this article.
Prerequisites
AWS CLI version 2.0 or above installed and configured.
Session Manager plugin installed on AWS CLI.
IAM Role with relevant permissions.
Existing Cluster and Task definition.
Install AWS CLI
Install AWS CLI on Linux
To install AWS CLI on Linux OS, run the below commands to download, unzip and install.
Linux x86_64
$ curl https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install
Linux ARM
$ curl https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install
To confirm the installation run the below command.
$ aws --version
Install AWS CLI on Windows
To install AWS CLI on Windows OS,
Download and run the AWS CLI MSI installer for Windows (64-bit):
https://awscli.amazonaws.com/AWSCLIV2.msi
Install AWS Session Manager plugin on AWS CLI.
To Install Session Manager plugin on Linux run the below command.
Linux x86_64
$sudo yum install -y https://s3.amazonaws.com/session-manager-downloads/plugin/latest/linux_64bit/session-manager-plugin.rpm
Linux ARM
$sudo yum install -y https://s3.amazonaws.com/session-manager-downloads/plugin/latest/linux_arm64/session-manager-plugin.rpm
To Install Session Manager plugin on Windows
Download the installer using the following URL. Unzip and Run the downloaded installer, and follow the on-screen instructions.
Executable Version – https://s3.amazonaws.com/session-manager-downloads/plugin/latest/windows/SessionManagerPluginSetup.exe
Zipped version – https://s3.amazonaws.com/session-manager-downloads/plugin/latest/windows/SessionManagerPlugin.zip
Note: For more information and elaborated steps for installing AWS Session Manager, please click here.
IAM Role and Permissions
Update your ECS Fargate IAM role with below permissions.
The permission includes AWS Systems Manager Agent (SSM) permission to establish a secure link between the device you use to issue the exec command and the target container. And ECS Execute permission enables access to the container.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel",
"ecs:ExecuteCommand"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"logs:DescribeLogGroups"
],
"Resource": "*"
}
]
}
Start the docker container with Enable Exec
To start the container with Enable exec run the below run-task command with given parameters.
Replace the CLUSTER_NAME, TASK_DEFINITION, PUBLIC_SUBNET_ID and SECURITY_GROUP_ID with the appropriate values.
aws ecs run-task
--cluster <CLUSTER_NAME>
--task-definition <TASK_DEFINITION>:LATEST
--network-configuration '{"awsvpcConfiguration":{"subnets":["<PUBLIC_SUBNET_ID>","<PUBLIC_SUBNET_ID>"],"securityGroups":["<SECURITY_GROUP_ID>"], "assignPublicIp":"ENABLED"}}'
--launch-type FARGATE
--enable-execute-command
Note: The above works on platform version 1.4 or above which is the most recent version and ships with the ECS Exec prerequisites) Note: For this example Public subnets are used. However we can launch tasks in a private subnet which has a VPC routing table configured with NAT gateway for outbound traffic. This way the NAT gateway can open a connection to ECR on behalf of the task. In this case to connect to the container a bastion host in a public subnet will be needed.
If everything goes well, we get the output similar to below.
[ec2-user@ip-10-x-x-xxx]$ aws ecs run-task --cluster test-cluster --task-definition test-definition:2 --network-configuration '{"awsvpcConfiguration":{"subnets":["subnet-02****28","subnet-0a****af"],"securityGroups":["sg-04****62"], "assignPublicIp":"ENABLED"}}' --launch-type FARGATE --overrides --enable-execute-command
{
"tasks": [
{
"attachments": [
{
"id": "9211ec7e-7953-419a-a62d-f6233a8b7a9e",
"type": "ElasticNetworkInterface",
"status": "PRECREATED",
"details": [
{
"name": "subnetId",
"value": "subnet-02****28"
}
]
}
],
"attributes": [
{
"name": "ecs.cpu-architecture",
"value": "x86_64"
}
],
"availabilityZone": "us-east-2a",
"clusterArn": "arn:aws:ecs:us-east-2:31*********55:cluster/test-cluster",
"containers": [
{
"containerArn": "arn:aws:ecs:us-east-2:31*********55:container/test-cluster/fac2a0afb35f4be38e983f826aef6717/b0272b34-85a3-457f-9e8e-fd46de1040a2",
"taskArn": "arn:aws:ecs:us-east-2:31*********55:task/test-cluster/fac2a0afb35f4be38e983f826aef6717",
"name": "test-cluster",
"image": "31*********55.dkr.ecr.us-east-2.amazonaws.com/test-cluster:latest",
"lastStatus": "PENDING",
"networkInterfaces": [],
"managedAgents": [
{
"name": "ExecuteCommandAgent",
"lastStatus": "PENDING"
}
],
"cpu": "0",
"memoryReservation": "1024"
}
],
"cpu": "1024",
"createdAt": "2023-04-22T08:34:29.019000+00:00",
"desiredStatus": "RUNNING",
"enableExecuteCommand": true,
"group": "family:test-cluster",
"lastStatus": "PROVISIONING",
"launchType": "FARGATE",
"memory": "2048",
"overrides": {
"containerOverrides": [
{
"name": "test-cluster"
}
],
"inferenceAcceleratorOverrides": []
},
"platformVersion": "1.4.0",
"platformFamily": "Linux",
"tags": [],
"taskArn": "arn:aws:ecs:us-east-2:31*********55:task/test-cluster/fac2a0afb35f4be38e983f826aef6717",
"taskDefinitionArn": "arn:aws:ecs:us-east-2:31*********55:task-definition/test-definition:2",
"version": 1
}
],
"failures": []
}
Access the Interactive shell of a docker container and find the diskspace
In the execute-command below, replace the CLUSTER_NAME, TASK_ID with appropriate values and execute it.
aws ecs execute-command \
--region us-east-2 \
--cluster CLUSTER_NAME \
--task TASK_ID \
--container linux_container \
--command "/bin/bash" \
--interactive
This opens the bash shell access to the container!
[ec2-user@ip-10-x-x-xxx]$ aws ecs execute-command \
> --region us-east-2 \
> --cluster test-cluster \
> --task fac2a0afb35f4be38e983f826aef6717 \
> --container test-container \
> --command "/bin/bash" \
> --interactive
The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.
Starting session with SessionId: ecs-execute-command-02938fdaae0e071ba
bash-4.2#
Conclusion
Usually its tedious and time consuming to debug, troubleshoot issues on the Fargate docker container, as it needs the image to be built, pushed to ECR each time and then run on ECS Fargate.
And like already mentioned accessing the container shell directly saves us time.
Although the interactive shell offers a variety of advantages, it should be used judiciously and carefully.
Make sure to adhere to security best practises and only provide access to authorised personell.
Hope this was helpful. Please share your thoughts and comments below.