问题
Context:
I am using Circle CI's aws-ecs/deploy-service-update
orb to deploy my docker container by pulling the latest image in AWS ECR and deploy it in AWS ECS with AWS EC2 instance. This container is a Machine Learning model that accepts API requests at TCP port 3000(I am using fastAPI
for this) and returns the predictions. After I deployed it I couldn't send requests to the public IP of the container instance of the task that deploys the container at port 3000 (This IP is not my EC2 instance's public IP; it only has private IP and public IP is disable).
Debugging
- I checked my security group and made sure that the port 3000 is open to receive requests from all IPs(0.0.0.0), as part of the inbound rule.
- I stopped the task(which automatically will stop the container running in the EC2 instance) with the thought that something may have gone wrong from Circle CI. Then, according to the service configuration(1 desired task) and task definition of AWS ECS, a new task has started(hence the container) automatically. But, I couldn't send requests to this either.
- I SSHed into my EC2 instance to know if the port 3000 is open. This is when is when I learned that ports weren't mapped at all:
As you can see, PORTS column is empty for the container and the container has to accept requests at port 3000 from the command.
And here are the open ports of the EC2 instance: As you can see, port 3000 is not listed here.
Here is the task with port mappings which deployed the container (to AWS ECS) that you see docker ps
screenshot above:
In the task definition, you can see the port mappings I have defined for the container.
Here is the task running on my EC2 instance with the task-definition shown above and the network mode I am using is 'awsvpc':
Here's the "Networking" tab of ENI associated with the task, and also the inbound rule of the security group associated with the EC2 instance that the task is running inside, which accepts requests on port 3000 from all IPs.
EDIT 1:
After I did
docker run -p 3000:3000 <my-image:my-tag>
inside the EC2 machine(by SSHing from my laptop), I could send API requests and receive proper response to the container to it's public IP, of the cluster of AWS ECS. This means that ports are being mapped only when I run the container manually.
I had no problems with ports when I used FARGATE, when I updated the service from Circle CI or even when I manually started tasks.
So, how to automatically map ports when a task is run from AWS ECS service dashboard or from Circle CI? If I run docker container manually, I will not be able to get logs automatically from AWS Cloudwatch and will not be able to stop it from AWS ECS dashboard. Another container by AWS that is running in EC2 instance will take care of those things. It will route the logs to Cloudwatch and accepts stop the existing one and start commands to start a new container with new image stored in AWS ECR, without having to SSH everytime I would want to look at logs or start/stop containers.
What has gone wrong here, which led to ports not being mapped and How do I fix it and map ports properly, so i will be able to send API requests to my container.
回答1:
For the awsvpc
network mode port mappings work a bit different. The hostPort
is no valid option here, the created ENI will expose the containerport to the VPC.
There are several prerequisites for this mode, e.g ECS agent version, instance type (ENI count limit), instance profile, ... check the official AWS documentation: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-networking.html
Habe you checked for ENI attached and which ports are open on those ENIs?
回答2:
The mistake I had done was to use FARGATE optimised cluster and an EC2 instance inside it; which presumably had led to no network mode(default, bridge, host, awsvpc and none) work for my application. So, when I redid everything same as last time, but with EC2 optimised cluster type, bridge
network mode worked just as expected.
来源:https://stackoverflow.com/questions/64632279/how-to-have-aws-ecs-automatically-map-ports-of-my-container-to-the-host-machine