The general availability launch of Azure Container Apps back in May 2022 brought, in my opinion, a game-changing feature for serverless compute: Kubernetes Event-driven Autoscaling (KEDA). At Advania, within Managed Services, we've been migrating some of our own Function Apps to Container Apps in recent months and I wanted to highlight why the support of the KEDA feature in particular is such a big deal in this serverless area.
This article references Azure Function Apps, but other apps (e.g. Web apps) are also compatible to migrate-run on Azure container apps. However, in terms of emissions and cost reductions, I associate Function Apps as being more likely to not be required to run 24/7, 365.
Function Apps: pros and cons
Function Apps are great in many use cases for scaling, leveraging different triggers and orchestration with Durable Function Apps, and you might already be utilising them within your own environment. However, only Azure's Consumption tier (SKU) allows for Function Apps to pause and be re-awoken on demand without incurring cost whilst inactive.
The problem is that Azure's Consumption tier (SKU) is not considered to be the most secure option and is therefore not suitable for production workloads. This is primarily due to it providing no support for private networking - all connections to and from the apps on this tier are over public (Internet) networking.
For production workloads we only utilise the Premium App Service Plan SKU's to host Function Apps. These allow integration into Virtual Networks for private networking as per security posture best practise. However, they do have a fixed cost with constant running compute, regardless of the running state of the Function Apps and their execution counts,. The compute is running and has to be paid for, so a cost is incurred.
How do Container Apps with KEDA improve on function apps?
To cover very quickly what KEDA is, we can turn to the clear and simple definition on the website: "KEDA is a Kubernetes-based Event Driven Autoscaler. With KEDA, you can drive the scaling of any container in Kubernetes based on the number of events needing to be processed."
Kubernetes is an open-source container orchestration platform. Azure Container Apps runs on the Kubernetes platform, with Azure taking care of the management plane - making container apps a simpler and quicker solution to implement whilst still leveraging some key benefits.
Azure Functions Support by KEDA is important to mention, so if you're already running Function Apps that have been around for much longer, all of the Azure native function apps SDK's and capabilities are fully supported by KEDA. Therefore, if you want to carry out a proof-of-concept of container apps, there is no significant coding changes required from your function apps.
Private networking is also possible with Azure container apps. Azure virtual network integrates with container app environments with excellent controls over Ingress traffic, whilst the container apps are not running and scaled-to-zero, there is no compute usage or cost during this time (unlike the premium function app service plan). There are still costs for the related networking services but this is not much different from a secure/premium function app deployment.
The following image shows a shortened sequence of a Container App activating from a Storage Account Queue that populates with messages to process, then scaling back to zero.
With the above example, where we previously had a Function App running constantly, perhaps waiting to be triggered by a scheduled or spontaneous HTTP request, we have migrated the triggering request payload to a Storage Account Queue that is monitored by the input binding of the Container App (leveraging the KEDA capability).
As mentioned earlier there is full support of Azure Function Apps and their bindings, so if you already have Azure Function Apps these can be hosted within Azure container apps in minimal steps.
Container Apps scaling
A key feature of Container Apps is the scale-to-zero capability, which has significant impact on cost and sustainability reductions.
This scaling capability of Container Apps also has a much greater scope. Previously, when leveraging Durable Function Apps to break down and orchestrate multiple steps (sub-functions) that could fan out into parallel instances of those sub-functions, we would often run into challenges with the amount of data being handled by the Durable Function, and extended the runtime of the individual functions and could slow and risk overloading the available App Service Plan compute at times.
With Container Apps, however, the app code can be kept simpler and the scaling is achieved by creating multiple concurrent replicas of the app (up to a pre-defined cap). Leveraging message queues in conjunction with this means that each replica can collect a batch of messages, process them and then go back for more until all of the messages have been processed. This results in an app that can include multiple steps (without using Durable Functions) but effectively manages the workload batch automatically.
To sum up, if you already run Function Apps in Premium App Service Plan SKU's that do not need to run 24/7-365, it could be worth reviewing your current costs and emissions usage of those plans to see if there is value in considering a proof of concept of Azure Container Apps.