New for AWS Lambda – Container Image Support
aws.amazon.com
aws.amazon.com
With this capability you can now package Lambda functions using familiar container image tools (Dockerfile, cli tools, build systems) but you still need to code them for the event model, have a handler, etc.
It's a big improvement, but its not "run any container in Lambda".
Either way, hope you go and try it out and we'd love feedback on how it can be better.
- Chris Munns, Lead of Dev Advocacy - Serverless@AWS
One thing I'd like to see is buildpacks for that final function contract. It's been done before for other cloud-y respond-y things (we did it on Project riff, Google have done it for Cloud Run), so I am aware it's possible. The nice part is that you won't need to build all the buildpacks yourself -- just the small set that adds your specialisations.
Feel free to email me.
Thanks, - Chris
>It's a big improvement, but its not "run any container in Lambda".
Well that’s... incredibly disappointing and makes this announcement much less exciting.
The entire point of containerization is portability across different services and platforms. It’s seems like a massive miss for the team to tout “container support” but then still require platform-specific customizations within the container. I pretty much don’t care at all for this as-is.
Are there plans for “run any container on Lambda”? That’s what everyone was (falsely) excited about.
As others have noted, ECS or Fargate would be more appropriate for cases that fall outside the Lambda event model.
[1] https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.ht...
So in other words, you can’t run any container.
Again, the entire point of containers is portability across execution environments. If I have to build special containers specifically for Lambda because they require these special runtimes, that defeats the entire point.
> You can't run a random container and expect Lambda to know how it should communicate with the world.
Google Cloud Run, which everyone keeps comparing this with, works exactly like that. Upload any random container, tell it which port to open, and bam... running application. You don’t have to mess around with adding any “Cloud Run runtimes” or modifying your code to add special “Cloud Run handlers”. Because that would be silly.
I had exactly the same thought you're expressing here when I first built a Lambda to serve as a HTTP API manually after previously using Azure a tiny bit. In Azure you write their equivalent function and one of the built-in trigger options is HTTP, you enable that and immediately get a URL. Lambdas are quite close to that now I think if you're using the console UI, but you used to have to go through API gateway and set everything up manually.
But the point is that Lambdas aren't HTTP APIs that listen on a single port. They receive events that can be proxied HTTP requests via API Gateway, or messages on queues, or completely arbitrary invocations from step functions, or notifications that look nothing like HTTP from S3 buckets. I'd like the Cloud Run model when my lambda is acting like an HTTP API, but I don't think it'd be much fun to have to treat every AWS event as a full HTTP request for everything else.
I'm not very familiar with Google Cloud, but I think their equivalent is Cloud Functions which looks very similar to Lambda's pre-container model: https://cloud.google.com/functions/docs/writing
Do Google represent a JSON body HTTP event in a clean way? In AWS when a lambda is working as one, it receives the body as a string in the JSON representing the request, which you have to JSON decode. Again because not everything a Lambda can act on is JSON and your API doesn't have to be, what else can it really do I guess. But it does make it a bit horrible to generate that data to test with - we actually have a small script we use locally to convert a nicely formatted JSON file with test data into their HTTP-request-as-json format because it's so annoying to work with a large encoded JSON body. It's a small thing, but it means when you switch to working with a plain AWS event it's one less thing to think about. And I guess even if you're in HTTP-Request-Land and everything is nice JSON, it's still all going to be custom between services from there on by necessity.
> Google Cloud Run, which everyone keeps comparing this with, works exactly like that.
Everyone does keep comparing this to GCR, wrongly. Not just because Lambda is not "bring any container" whereas GCR is, but more importantly because GCR and Lambda have very different operational models. GCR is a serverless platform for hosting web servers. Lambda is a serverless platform for event handling. The latter is a super-set of the former and thus requires more specific tools.
Yes, theoretically there could be a setup whereby you expose a port, and some lambda intermediary translates the invocation payload to an HTTP message your container can read. But I am endlessly fascinated why anyone would want that. I laugh a bit on how we've hit peak AWS where people here are legitimately asking for an HTTP request to hit an ALB, the ALB translates it into a lambda payload object, then a lambda component re-translates that payload back into an HTTP request, so your application can translate it into an object. Do you understand how insane that is?
The only tactile advantage lambda has over fargate is scale-to-zero. I think saving $7 per month is a pretty bad trade-off for the insane performance overhead and complexity a true docker-in-lambda solution would necessitate, and thus be unattractive to most consumers.
This announcement is great if you need to package stuff inside your container for use at Lambda runtime.
That's the idea. Run any container in Fargate. Now use the same tools you use to build/package those containers in Lambda.
Containerization solves a few things. One big one was the container image as a packaging model. As customers struggle with dependency management or installing native packages (RPMs) we're basically faced with reinvent Dockerfile... or just use Dockerfile. This is an over simplification of what's happening, but that was the initial spark of this, many many cycles ago.
I think this is still going to be really valuable for folks, but what you are looking for already exists I'd say, and is Fargate.
Btw, ppl shouldn't be downvoting this, its all very valid.
- Chris, Serverless@AWS
No, Fargate isn’t that at all. Google Cloud Run is what you meant to say.
This is of course still valuable to allow container-based workflows to adapt to Lambda, but it really seems like AWS missed the mark on identifying why people really want to use containers. Just one look at the amount of people on HN threads or on Reddit excited at using “arbitrary containers on Lambda” should tell you what people really wanted - and now they have to come away disappointed.
IIUC though, Fargate doesn't have "scale to zero" like Lambda and API Gateway. Then again, IMO, scale to zero and the associated cold starts probably aren't the best fit for handling HTTP requests that are waiting for an answer right now.
- Chris
Does each new Lambda cold start pull the entire image from the repo? Or if I derive from Lambda base images am I likely to get some of the layers already cached?
I'm trying to think about how the data transfer costs are going to each time the Lambda is instantiated. I didn't take this into account with Fargate and got burned when trying to trigger images on demand in a similar way.
This could replace my whole SQS / CloudWatch Events / Fargate setup using Lambda if I can figure out cold start costs ($ not time).
I know we've got a few blog posts coming out over the next couple weeks on this new feature, and each tells a few bits and pieces about the story.
Depending on volume you'll probably find that Lambda will be cheaper for that workload, especially with the new 1ms billing.
- Chris - Serverless@AWS
- - - -
REPORT RequestId: f905d5fe-a64e-48c8-b1f2-6535640a6f82 Duration: 7.55 ms Billed Duration: 1309 ms Memory Size: 256 MB Max Memory Used: 49 MB Init Duration: 1301.10 ms
- - - -
REPORT RequestId: 89afb20d-bc49-4d89-91f0-f1ef62ac99aa Duration: 12.20 ms Billed Duration: 13 ms Memory Size: 256 MB Max Memory Used: 35 MB Init Duration: 85.37 ms
Since function code has no listening socket/port as it were you need something (like the bootstrap script in a custom RunTime) to pull the local interface for the runtime API. That runs on the underlying worker and communicates with the API for Lambda.
- Chris
Thanks again!
- Don't make me build the Docker image myself. I'd like to be able to deploy lambdas by sending you a Dockerfile and having you build it for me, with as few additional steps as possible.
- Make it as easy as possible to run containers that speak HTTP, like Google Cloud Run does. Having a wrapper that translates the AWS Lambda runtime into HTTP calls, maybe even as a proxy I can run inside my own container, would help a lot here.
- Make it as easy as possible for me to host my lambda as the "root" URL of a domain or subdomain that I own - without those nasty /api/ path prefixes.
Zeit Now (the Docker-based predecessor to Vercel) did this the best in my opinion - they had an HTTP API that you could POST a Dockerfile to and they would build it into an image and then start a container listening on an HTTP port, with an HTTPS proxy in front of it, running on a subdomain that I could easily customize.
I would LOVE to see AWS Lambda offer an equivalent developer experience. I'm super-excited about container image support but I'll admit I am absolutely dreading the several hours (to several days) it's going to take me to figure out how to actually get my code running on it.
I'm OK with developers needing to understand that a Dockerfile may build differently each time if they don't take extra steps to prevent that (like pinning installed versions etc).
Using an actual container orchestration platform when you need it, and a lambda to run the same container image one-off when you don't need orchestration, feels like a best of both worlds.
I like the idea of "serverless" being more "your packaged execution environment, running with no regard for the underlying host" than "your code, running with no regard for the underlying execution environment".
EDIT: Disregard.... see the AWS team's responses in this topic for the full story, its not quite as convenient as anything packaged via standard container being able to run on Lambda
Having official base images, being able to think about lambdas as just a docker container in terms of tooling, and losing all the complexity associated with Lambda's custom code deployment logic will be a massive win.
1) the 250 mb size limit.
2) trying to get some tricky dependencies into a lambda compatible image.
Ive got one build system that was going to have to move off lambda in the next few months because of the size issue. We’re shipping a slowly changing node modules directory to lambda, and then repeatedly building an app with them.
We’re also doing perf testing with lighthouse, and that was a pain and a half to get packaged. This should make it far simpler.
Such a tool would mean I could take any existing HTTP container and turn it into an AWS Lambda Container Image just by adding the proxy process that translates between the lambda runtime and the internal HTTP server.
Personal opinion - I prefer Lambda over KNative. KNative feels like more of a shoehorn into Kubernetes than most other projects. Lambda feels more mature.
Still glad to see this move, regardless.
AWS could plausibly do exactly the same thing: provide a skin over Lambda that speaks Knative.
I think Amazon's and Microsoft's reluctance to wade into Knative has been wariness about Google's intentions. And maybe 6 months ago I would have said "fair enough, I would be cautious too". But the recent update to Knative's governance model largely resolves the problem, in my view. I would very much like to see AWS and MS involvement.
[0] "Knative" is the correct spelling, FWIW.
Disclosure: I work for VMware, which participates in Knative development.
I also, like, wrote a book about it.
About that, you don't need to use their base images, "You can deploy your own arbitrary base images to Lambda"
- Chris - Serverless@AWS
One more q: What about network latency on warm up when connecting to e.g. RDS?
I'm very curious about the invocation latency overhead of Docker. I assume its non-zero relative to the more native runtimes?
Docker's specific implementation may offer other hurdles, of course, but AWS Lambda could easily use one of the many other implementations of OCI.
Is there some easy way to simulate api gateway + docker lambda locally?
This is more like Lambda with Docker instead of ZIP. More code storage but same 15min runtime limit.