Deployment of the container in Amazon cloud has completed, and there are other challenges which include
- Adding SSL to current production site for increased security
- Dynamic port mapping for serving multiple services within 1 cluster
The reason why I put these 2 features together is because of their similarity on how they configure. Dynamic port mapping is used to deal with running multiple services within a cluster, imagine when more than 1 web server is built in a ec2 instance, how is the port 80 being "shared" by these 2 services (web server)? Dynamic port mapping is the solution.
Concepts
The solution is to make use of ELB (Elastic Load Balancers), which is divided into ALB (Application Load Balancers) and NLB (Network Load Balancers), ALB is to load balance the traffic in application level, L7, which is our case (HTTP & HTTPS). NLB is for binary protocols (non HTTPx protocols).
Here is how application load balancers (ALB) deals with dynamic port mapping
1. User fire requests either HTTP (port 80) or HTTPS (port 443) directly to the load balancer
2. Each load balancer has its corresponding listeners which checks the connections of the port / protocol. Note that we need to pass the healthy test before the load balancer operates
3. When such connection happens, listeners will use the listener rules (user defined, can be more than 1, depending on your needs) to direct the traffic to designated target groups
4. Here, the target group is "TG1", this group contains the frontend container which is composed by the docker compose file. We need to wire up the group arn to the container when we create the service using "ecs cli create service" command, note we cannot modify it after the service has started. And the limitation using this command is that we can only bind 1 target group to 1 container.
5.A "registered target" should be configured in the target group, and the load balancer will use the registered target to check the healthy status before operate. When the request is forwarded to the target group, the listener will choose the port specified in the registered target to transfer / map the request to the desired containers.
e.g.: If we configured a target group as ec2-instance (target instance) | 32768 (port) | ... The listener will know for the port 80, which container port should be used to map the host port 80 request to.
But remember, to ensure this happens, we need to configure the security groups to allow inbound port 80 or any desired host ports to allow load balancers correctly listens to outside requests
6. Sometimes there may be more than 1 container served in the same ec2 instance, we therefore need dynamic port mapping to accomplish 2 web servers situated in the same ec2 instance, by dividing the 2 containers into 2 different target groups, serving 2 websites using 1 ec2 instance become possible.
Procedures
1. Follow AWS tutorial to create load balancers, choose HTTP / HTTPS application load balancer
2. Choose "Internet facing" scheme and add both HTTP and HTTPS load balancer protocol if you want SSL over HTTP.

3. Choose the desired VPC to apply the load balancer to
4. Choose the certificate type (we normally use ACM as it is super easy to deploy the site with SSL enabled), choose the certificate registered in ACM (I am using route 53 for the domain and use Amazon ACM here)
5. Choose security group, if the outgoing port is 80 and 443, you need to allow inbound connection of port 80 and 443 to allow load balancer to do its job.
6. Configure the target group and health check parameters. Here, remember we use HTTP protocol (port 80) as the protocol for the load balancer to forward traffic to designated target group, we left SSL handling to load balancer and prevent configuring the certificates server configuration, deployment and renewal in application level, we let ACM to handle them all for us. So, we only need load balancer to do health check on port 80. (As our docker compose file exposed port 80 for the LB to do the health check)
7. After creating the load balancer, navigate to "target groups", you will see the group we created when we create the load balancer, head to "Description", copy the arn of the target group and use it to associate with the service using the following command
ecs-cli compose --file ./docker-compose-aws-prod.yml --cluster mw-ecs --ecs-profile mw-ecs-profile --cluster-config mw-ec2 --project-name supremeav-2-dot-0 --ecs-params ./ecs-params.yml service up --target-group-arn arn:aws:elasticloadbalancing:us-east-2:916381200858:targetgroup/http-port-80-access/222d18e3d1cddf3a --container-name frontend --container-port 80
Note that "target-group-arn" is the arn you copied in description and "container-name", "container-port" must be specified to let balancer forward the request to the right container.
8. After the container is initialized, you should see a new entry appeared in the registered target (in the target groups) automatically when the container is up and run. Health check should be carried out accordingly.
9. Finally, navigate to load balancer and copy the DNS name, navigate to route 53, find the domain name registered, add or edit the existing A type entry, with alias selected, choose from the input the DNS A type entry (or you can paste the DNS you just copied) and you are all done!
Now when user access the website through Internet, they are just forming connection with the load balancer and the load balancer will forward / direct the request to the container port through evaluating the rules.
For SSL connection, there is no extra procedure needed, just ensure there is an entry in listeners of the load balancers, the rest would be handled by them, no extra nginx configuration play around!
References
1. https://stackoverflow.com/questions/58587976/nginx-docker-container-on-aws-ecs-the-plain-http-request-was-sent-to-https-po
2. SSL redirection in docker container on aws ecs
3. Understanding dynamic port mapping in amazon ecs with load balancer
沒有留言:
張貼留言