I have a docker image uploaded ECR that provides a single page web app. I would like to make an API Gateway endpoint that starts a new instance based on that image, and then maps port 443 (or 80) to container port 7894 (specified by app in the image).
Sketch of ideal architecture:
Running EC2 instance based off my ECR image
API Gateway with single GET endpoint mapping.
That is, I want something as close as possible to what I starting the image via
docker run -p 80:7894 my_app:latest
and navigating to http://localhost.
I only ever want at most one of these running (not a hard requirement, just saying I don't feel I need a load balancer), and I have a preference for "less" security given there's security in the app and I'm literally the only person who will be using this. That is, I'd be very happy if I could
start a new container
directly expose port 7894 of that to the internet
What is the absolute minimal set of resources I need to set up to make this happen?
I've tried a few approaches based on Fargate, but these all end up requiring a number of extra networking and load balancing steps (VPC/subnets, ALB/NLB/CloudMap, ...) that seem unnecessary.
AWS offers numerous way to run containers. At the time of writing the probably easiest way for use case is to use AWS App Runner. App Runner allows you to provide a Docker image and will deploy that including auto scaling and load balancing without you to need to worry about all the heavy lifting. Instead you'll directly get a HTTP endpoint you can reach your app at and that's it.
Related
I have created a puppeteer's bot a put it inside a docker container. Until there, no problem !
But now i need to scale it(by duplicattion) when there is a new request. In fact, if the bot already works on a request, i want an auto scale to a second.
Second question, for you is it better to host it on cloud or a dedicated server ?
I tried to do something with Amazon ECS and fargate but i'm a newbe with thoses technology and i can't do anything which work.
If you have any suggestion, you're welcome
Thank you a lot for your responses and sorry for my bad English ;)
I want to use a docker application container with auto scale on request. Not a scaling on ressources but on the request.
I tried to do it on Amazon ECS without success. I'm open to other hosting solutions.
If you just want to run one application container and scale depending on load, take a look at AWS App Runner. It allows you to set a limit on concurrent requests a container can serve, and scale up when that threshold is reached - https://docs.aws.amazon.com/apprunner/latest/dg/manage-autoscaling.html
Alternatively if it doesn't have to be AWS, this sounds like a use case that would fit the Cloud Run service on Google Cloud.
CONTEXT:
We have a platform where users can create their own projects - multiple projects per user. We need to provide them with a browser-based IDE to edit those projects.
We decided to go with coder-server. For this we need to configure an auto-scalable cluster on AWS. When the user clicks "Edit Project" we will bring up a new container each time.
https://hub.docker.com/r/codercom/code-server
QUESTION:
How to pass parameters from the url query (my-site.com/edit?project=1234) into a startup script to pre-configure the workspace in a docker container when it starts?
Let's say the stack is AWS + ECS + Fargate. We could use kubernetes instead of ECS if it helps.
I don't have any experience in cluster configuration. Will appreciate any help or at least a direction where to dig further.
The above can be achieved using multiple ways in AWS ECS. The basic requirements for such systems are to launch and terminate containers on the fly while persisting the changes in the files. (I will focus on launching the containers)
Using AWS SDK's:
The task can be easily achieved using AWS SDKs, Using a base task definition. AWS SDK allows starting tasks with overrides on the base task definition.
E.G. If task definition has a memory of 2GB then the SDK can override the memory to parameterised value while launching a task from task def.
Refer to the boto3 (AWS SDK for Python) docs.
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecs.html#ECS.Client.run_task
Overall Solution
Now that we know how to run custom tasks with python SDK (on demand). The overall flow for your application is your API calling AWS lambda function whit parameters to spin up and wait to keep checking task status and update and rout traffic to it once the status is healthy.
API calls AWS lambda functions with parameters
Lambda function using AWS SDK create a new task with overrides from base task definition. (assuming the base task definition already exists)
Keep checking the status of the new task in the same function call and set a flag in your database for your front end to be able to react to it.
Once the status is healthy you can add a rule in the application load balancer using AWS SDK to route traffic to the IP without exposing the IP address to the end client (AWS application load balancer can get expensive, I'll advise using Nginx or HAProxy on ec2 to manage dynamic routing)
Note:
Ensure your Image is lightweight, and the startup times are less than 15 mins as lambda cannot execute beyond that. If that's the case create a microservice for launching ad-hoc containers and hosting them on EC2
Using Terraform:
If you looking for infrastructure provisioning terraform is the way to go. It has a learning curve so recommend it as a secondary option.
Terraform is popular for parametrising using variables and it can be plugged in easily as a backend for an API. The flow of your application still remains the same from step 1, but instead of AWS Lambda API will be calling your ad-hoc container microservice, which in turn calls terraform script and passing variables to it.
Refer to the Terrafrom docs for AWS
https://registry.terraform.io/providers/hashicorp/aws/latest
Is there a way to load test every component of an AWS solution using Distributed Load Testing? https://aws.amazon.com/solutions/implementations/distributed-load-testing-on-aws/
I have an AWS serverless ecommerce solution, which has a step function(which has a few lambda functions), an API gateway and RDS. I want to load test the solution at different endpoints like load the step function, then load the API gateway so on and so forth.
So, I've deployed https://aws.amazon.com/solutions/implementations/distributed-load-testing-on-aws/ and I am facing 2 issues:
To test the entire solution I have the target URL for the S3 bucket that is the entry point to the solution, now the problem is that the authentication key and password are cycled every week. So, I have to keep updating script with the latest key id and password. Is there a way for me to use some other mechanism like have a jenkins authorised user and integrate it with the distributed load testing(DLT) solution OR some other way to keep the entire process automated without compromising the security?
Secondly, I have to load test endpoints that do not have external URLs like the step function (there is an async lambda that initiates the step function) and in order to send payload to the step function through DLT I need a target URL. Is it even possible to load test in such a scenario? If yes, how? I have tried using serverless artillery but again it needs a target URL.
Load Testing
So if I understand your question correctly, you're looking for ways to load-test your AWS setup. Well you're using serverless technologies which are scalable by default. So if you load-test the environment, most probably you'll reach the service limits depending on the load you generate. All these limits are already documented well in AWS documentation.
Load testing only makes sense (to me) when you're using EC2 instances (or Fargate) and want to know how many instances you need for particular load. Or how much time it takes for system scaling to work.
Database
To load test your RDS you don't have to load test all the components of your setup. You can independently load test it using JMeter or any other tool.
Other Consideration
If you're going with distributed Load testing then you have to notify AWS beforehand. Your distributed load might trigger few DDoS like alarms in AWS.
I have my services split into Cloud Run services, say e.g. in a blog application I have user, post and comment services.
For each service I get a separate http endpoint on deploy, but what I want is to have api.mydomain.com act as a gateway for accessing all of them via their respective routes (/user*, /post*, etc).
Is there a standard (i.e. GCP-managed and serverless-ey) way to do this?
Things I've tried/thought of and their issues:
Firebase hosting with rewrites - this is the 'suggested' solution, but it's not very flexible and more problematically I think this leads to double wrapping CDNs on every request. Correct me if wrong, but Cloud Run endpoints use a CDN already, then you have Firebase hosting running through fastly. Seems silly to be needlessly adding cost and latency like that.
nginx on a constantly running instance - works ok but not managed and not serverless; requires scaling interventions
nginx on Cloud Run - this seems like it would have highly variable performance since there are (a) two possible cold starts, and (b) again double wrapping CDN.
using Cloud LB/CDN directly - seemingly not supported with Cloud Run
Any ideas? For me this kind of makes Cloud Run unusable for microservices. Hopefully there's a way around it.
I have a basic django/postgres app running locally, based on the Docker Django docs. It uses docker compose to run the containers locally.
I'd like to run this app on Amazon Web Services (AWS), and to deploy it using the command line, not the AWS console.
My Attempt
When I tried this, I ended up with:
this yml config for ecs-cli
these notes on how I deployed from the command line.
Note: I was trying to fire up the Python dev server in a janky way, hoping that would work before I added nginx. The cluster (RDS+server) would come up, but then the instances would die right away.
Issues I Then Failed to Solve
I realized over the course of this:
the setup needs another container for a web server (nginx) to run on AWS (like this blog post, but the tutorial uses the AWS Console, which I wanted to avoid)
ecs-cli uses a different syntax for yml/json config than docker-compose, so you need to have some separate/similar code from your local docker.yml (and I'm not sure if my file above was correct)
Question
So, what ecs-cli commands and config do I use to deploy the app, or am I going about things all wrong?
Feel free to say I'm doing it all wrong. I could also use Elastic Beanstalk - the tutorials on this don't seem to use docker/docker-compose, but seem easier overall (at least well documented).
I'd like to understand why any given approach is a good way to do this.
One alternative you may wish to consider in lieu of ECS, if you just want to get it up in the amazon cloud, is to make use of docker-machine using the amazonec2 driver.
When executing the docker-compose, just ensure the remote Amazon host machine is ACTIVE which can be viewed with a docker-machine ls
One item you will have to revisit with the Amazon Mmgt Console is to open the applicable PORTS such as Port 80 and any other ports exposed in the compose file. Once the security group is in place for the VPC, you should be able to simply refer to the VPC ID on subsequent executions bypassing any need to use the Mgmt console to add the ports. You may wish to bump up the instance size from the default t2.micro to match the t2.medium specified in your NOTES.
If ECS orchestration is needed, then a task definition will need to be created containing the container definitions you require as defined in your docker compose file. My recommendation would be to take advantage of the Mgmt console to construct the definition and then grab the accompanying JSON defintion which is made available and store in your source code repository for future executions on the command line where they can be referenced in registering task definitions, executing tasks and services within a given cluster.