Configuring AWS ECS cluster to be load-balanced and auto-scaling behind a DNS - docker

I have a recently-Dockerized web app that I'm trying to get running in AWS ECS. I'm using Route 53 for the DNS.
Although I haven't set it up yet in Route 53, my plan is to create a DNS record of api.uat.myapp.example.com, and what I want is to have that domain name backed by an load-balanced, autoscaleable cluster of my containers living in ECS.
I'm in the ECS Container Network Configuration tab:
Press the "I believe!" button for a minute and let's pretend that I've already created the api.uat.myapp.example.com domain name in Route 53. What values/configs do I need to add here so that:
When remote clients try to connect to api.uat.myapp.example.com they get routed to a load-balanced container running in my ECS cluster?; and
That load-balanced ECS cluster is auto-scaling (once I figure out where I can configure auto-scaling properties, I'm sure I can figure out how to configure them!)

Your question is extremely broad. As such, this answer is likely overly generic to be of specific use, but hopefully will point you in the right direction.
First things first
You're misunderstanding the configuration you've taken a screenshot of. This is the network configuration within your container. So, what is your container's hostname, what other containers does it link to, what DNS Server do you want it to use, or alternatively, what specific other hosts should it know about... these are all optional, but may be required for your specific setup.
This has nothing to do with how your application scales.
Load Balancing
You need to decide on what type of load balancer you should use for your application, first. You then can point Route53 to that load balancer. Behind your load balancer will be your EC2 instances. For traffic to route to your containers, you need to make sure your EC2 ports map to the listening ports of your container. ECS can help with this.
Autoscaling
This happens in multiple ways.
You can do application autoscaling within ECS by having an ECS Service spin up and tear down containers on your EC2 instances.
You can have your Autoscaling Group scale up and down your EC2 instances -- but doing so, you'll need a way to automatically add those instances to your ECS Cluster.
Multiple scaling strategies exist. You'll need to decide for yourself which one is the most appropriate for your application, based on what metrics are most important to your scaling decisions.

Related

How to handle the concurrence of file uploads in my kubernetes cluster?

I am designing the architecture of my software instance provisioning system. For this I will use kubernetes in such a way that each client will have their namespace with the pods of their integrity. However, the kubernetes cluster will have a common entry point to all the instances, which will be a nginx server.
My question is as follows, as software provided allows upload of files, in case at the same time several of my clients decide to upload a file simultaneously, I run the risk that the server nginx is overloaded and that nobody can access your instance hired?
Is there any good practice to try to design my architecture?
You could use nginx ingress controller and deploy it with multiple replicas so that it can be scaled up to handle the load. Then your nginx is part of the cluster (rather than a separate server) and can take advantage of the kubernetes cluster's capacity for horizontal scaling.
Unless you are running on-prem with NodePort/HostPort - then you might want to run your nginx as an external Load balancer as in that case you don't have one from a cloud provider. Then what you can do is configure rate-limiting and throttling in nginx. If cloud then you can also use annotations to do this with nginx ingress.

Docker Swarm with external Load Balancer - how to get collective healthcheck

I'm hoping that there are some docker swarm experts out there who have configured a load balancer to front a docker swarm multi-node setup. In such a simplified architecture, if the load balancer needs to detect if a manager node is down and stop routing traffic to it, what is the "best practice" for that? Does Docker swarm provide a health endpoint (api) that can be tested for each manager node? I'm new to some of this and there doesn't seem to be a lot out there that describes what I'm looking for. Thanks in advance
There is the metrics endpoint of the engine, and then the engine api, but I don't think that's what you want by an application load balancer.
What I see most people do is put a load balancer in front of the Swarm nodes they want to handle incoming traffic for specific apps running in services, and since that LB needs to know if the containers are responding (not just the node's engine health) they should hit the apps health endpoint, and take nodes in and out of that apps LB based on the app response.
This is how AWS ELB's work out of the box, for example.
If you had a published service on port 80 in the Swarm, you would setup your ELB to point to the nodes you want to handle incoming traffic, and have them expect a healthy 200/300 return on those nodes. It'll remove nodes from the pool if they return something else or don't respond.
Then you could use a full monitoring solution that checks node health and optionally respond to issues like replacing nodes.

Docker level load balancing using ECS

I am using elastic beanstalk to deploy the web services as Docker containers on AWS using ECS. Default load balancer available in EBS provides me network-level autoscaling to handle the load on EC2 instance.
How to handle auto-scaling in application level and use dockerization features using ECS like Kubernetes handling the dockers? I want to scale my individual dockers when it receives more memory or CPU usage. Please help me to achieve this.
You can have the ECS cluster managed by an auto scaling group . This would take care of the hardware underlying the docker images.
As far as the containers themselves are concerned, you can go the way of application auto scaling.
Since both these services can be configured to answer to CW alarms for both downscale and upscale, you can have a HIGH cpu/ram alarm policy to add 1 host and 2 container replicas for example and remove the same amount on a LOW alarm.
Hope this helps
You can use scaling of task when you are updating your service which is attached with a cloudwatch alarm to scale up/down and called as service autoscaling.
Ref: http://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-auto-scaling.html
These are not the answers to this question. Using multicontainer docker environment on ELB service, we can specify (within the Dockerrun.aws.json) our docker services and their relationships, but we cannot specify the number of instances for individual services. This means that if we want to scale our ELB docker services, we can do that useing autoscale groups and CloudWatch alarms, but this means that our entire docker service environment will be affected: if we have 3 docker services, we can scale only all them together, not individual services.
The only think you can do is to use Elastic Container Service (ecs). Within this service you will create the cluster (similar to Kubernetes approach), then create individual services which will be able to run multiple tasks, and each task will be the specification for individual docker container. This way you will be able to run your services in desired way and scale them appropriately.

Understanding Docker in Production

I've been learning how to use Docker to setup dev environments, however, I'm
curious how these ideas translate to a production stack. As an example, I have a Laravel (Php) app, which uses MySQL, Redis, and Nginx
So in production, let's say I would normally have 2 application ec2 instances behind a load balancer on AWS. When setting up a similar production situation using Docker...
1) because I'd be using RDS and Elasticache, there would be no need for containers for those. So basically, id only need containers for PHP-Fpm and Nginx?
2) to have high availability, I would still have 2 (or least more than 1) ec2 instances behind the ELB. So I suppose each instance would run the above containers (PHP and Nginx). But that sounds no different than my previous VM setup, where each server runs what it needs to serve the application. Is that accurate?
3) with VMs, I would traditionally bake the code into an AMI and add those AMIs to a Launch Configuration and an Auto Scaling group, and that group would spin up instances as needed. So for deployment, I would tear down the old ec2 instances and spin up new ones. With Docker, Since these containers would be running on ec2 instances, wouldn't i still have to spin up / tear down the VMs, or would I just replace the containers and keep the VMs running?
Its reasonable to keep RDS, Elasticache and other fully managed services, outside of docker environment. Yes for high availability you need multiple EC2 instances having docker daemon running.
The real advantage is not coming with having two EC2 instances running two web server docker containers on each of them. Real advantages comes when you break down your application to microservices, where multiple containers in combination construct your web application providing the benefits of microservices.
Apart from that the DevOps flow would be different compared to traditional web application deployment in EC2 with autoscaling and load balancing and have many benefits. For example your source code will contain the container code as well, which will guarantee, the environment will work uniformly in your staging and production. Also you will be having images pointing to branches/tags in your source control, which allows to get new updates(delta downloads) for new releases.
If you are going to setup docker in AWS, its recommended to go with AWS ECS to reduce management overhead.
You're right, you will only need to run your code in a container and it will simply access the remote services. The only thing you'll have to consider is to ensure connectivity to them.
You're right again, you'll need to have everything you previously had in your VMs in the Docker container so that your code works as before. Anyway, with Docker containers it is possible to run multiple instances of your app on the same EC2 instance. Of course, your app will try to run on the same port, so some extra networking layer is needed for managing ports is necessary, but it's possible. All the EC2 instances needs to have is docker installed.
Instead of creating AMIs and closing and spinning up EC2 instances, you'll only have to pull the new Docker image and restart the container with the new image. This means just a few seconds compared to minutes in the EC2 instances flow. This is means you have a really quick way of reverting buggy deploys and opens the doors for a setup in which 0% downtime can be reached.

Container delivery on amazon ecs

I’m using Amazon ECS to auto deploy my containers on uat/production.
What is the best way to do that?
I have a REST api with a several front-end clients
Should I package my api container with nginx in the same container?
And do the same thing with the others front end clients.
Or I have to write a big task definition to bring together all my containers(db, nginx, php, api, clients) :(, but that's mean that I should redeploy all my infrastructure at each push uat/prod
I'm very confusing.
I would avoid including too much in a single container. Try and distill your containers down to one process doing one thing. If all you're doing is serving up a REST API for consumption by your front end, just put the essential pieces in for that and no more.
In my experience you also want your ECS tasks to be able to handle failure gracefully and restart, and the more complicated your containers are the harder this is to get right.
Depending on your requirements I would look into using ELB instead of nginx, you can have your ECS cluster point at an ELB and not have to deal with that piece at all.
Do not use ECS - it's too crude. I was using it as a platform for our staging/production environments and had odd problems during deployments - sometimes it worked well, sometimes - not (with the same Docker images). ECS provides not clear model of container deployment and maintenance.
There is another good, stable and predictive option - Docker Cloud service. It's new tool (a.k.a. Tutum) that was acquired by Docker. I switched the CI/CD to use it and we're happy with it.
Bind Amazon user credentials to Docker Cloud account. Docker Cloud uses AWS (or other provider) API for creating appropriate computer instances.
Create Node. Select Amazon EC2 instance type and parameters of storage, security group and so on. New instance will contain installed docker software and managing container that handles messages from Docker Cloud (deploy, destroy and others).
Create Stackfile, see https://docs.docker.com/docker-cloud/apps/stack-yaml-reference/. Stackfile is a definition of container group you required. You can define different scaling/distribution models for your containers using specific Stackfile options like deployment strategy, see https://docs.docker.com/docker-cloud/apps/stack-yaml-reference/#deployment-strategy-1.
Define ELB configurations in AWS for your new instances.
P.S. I'm not a member of Docker team and I like other AWS services :).
Here is my two cents on the topic, the question is not really related to ecs, it applies to any body deploying their apps on docker.
I would suggest separating the containers, one for nginx and one for API.
if they need to be co-located on the same instance, on ECS you can define them as part of the same task and on kubernetes you can make them part of same pod.
Define a docker link between the nginx and the api container. This will allow the nginx process to talk to api container without the api container exposing its ports to the host.
One advantage of using the container running platforms such as kubernetes and ecs is that they ensure each of the container run all the time and dynamically restart if one of the processes/containers go down.
Separating the containers will allow these platforms to monitor both the processes separately. When you combine the two into one container the docker container can only run with one of the processes in foreground, so you will loose the advantage of auto-healing for one of the processes.
Also moving from nginx to ELB is not a straightforward solution, you may have redirections and other things configured on the nginx, which are not available on ELB(As of date).
If you also need the ELB, there is no harm in forwarding the requests from the ELB to the nginx port.

Resources