Serverless Kubernetes with Azure Container Apps

Does Azure Container Apps deliver on the promise of serverless microservices reducing management, responsibility, and complexity?

Serverless Kubernetes with Azure Container Apps

Deploying containerized apps and microservices using a serverless service—not having to manage the underlying and usually complex infrastructure—sounds excellent. Serverless microservices are precisely what Azure Container Apps promises to deliver.

Let’s examine the Azure Container Apps service and its features. Then, we’ll compare the service to other Azure services and deploy a simple containerized app step-by-step.

Azure Container Apps

The Azure Container Apps service enables containerized apps on top of a serverless platform and doesn’t care about the programming language or runtime version.

With Azure Container Apps, you can orchestrate your containers without worrying about managing a Kubernetes cluster. You can think of Azure Container Apps as a serverless Kubernetes service. With this additional abstraction layer, you’ll lose some control and flexibility in favor of ease of management and simplicity.

Azure Container Apps can autoscale your apps, including scaling to zero instances. You can run multiple revisions of your containers, including traffic splitting, enabling various deployment scenarios. You can also integrate with an existing virtual network and much more.

As with almost every Azure service, new features are added regularly. Please refer to the documentation for a complete overview.

Scaling of your app can take place based on different triggers, including:

  • HTTP Traffic: Based on the number of concurrent HTTPS requests.
  • Events: Using KEDA-supported scale triggers like Azure Service Bus messages. KEDA stands for Kubernetes-based Event Driven Autoscaler, and you can find more information about KEDA, including the supported scalers, on KEDA’s website.
  • Resource usage: Based on the amount of CPU or memory used. Using resource usage-based scaling makes it impossible to scale down to zero instances.

Azure Container Apps supports Dapr integration. Dapr stands for Distributed Application Runtime and provides APIs that simplify microservice connectivity using sidecars. Dapr is out of the scope of this post, but you can find more information about Dapr on Dapr’s website.

Environments

The container apps are deployed to an Azure Container Apps environment, enabling the apps that are part of the environment to securely communicate with each other and share logging and a virtual network.

An environment can be deployed as a zone redundant resource, requiring virtual network integration. Once created, the zone redundancy cannot be modified.

Service comparison

How does Azure Container Apps compares to other services like Azure Container Instances, Azure Kubernetes Service, or Azure Functions?

Azure Container Instances: This service is like a stripped-down version of Azure Container Apps, lacking features like scaling and load balancing. It is less opinionated and can accommodate scenarios that do not align with Azure Container Apps. The documentation provides more information about Azure Container Instances.

Azure Kubernetes Service: This is Azure’s managed Kubernetes service and supports all Kubernetes features. The Azure Kubernetes Service (AKS) gives you direct access to the Kubernetes API, enabling you to run any Kubernetes workload. However, this comes with more complexity, management, and responsibility.

AKS is a better option than creating and managing a Kubernetes cluster yourself. You can find more information about the Azure Kubernetes Service in the documentation.

Azure Functions: This service shares many features with Azure Container Apps, such as autoscaling, load balancing, and event integration, but it is optimized for function-as-a-service workloads.

With Azure Functions, a function is the unit of work, whereas with a container app, the entire container is the unit of work. The documentation provides more information about Azure Functions.

Deployment

Let’s deploy a simple containerized app to familiarize yourself with Azure Container Apps. But before you can start deploying, there are some prerequisites to fulfill:

  • Azure tenant and user account: You’ll need an Azure tenant, an Azure Active Directory (Azure AD) instance. This instance is the foundation of the environment. It allows you to create an identity (user account) to connect to Azure, set up the environment, and deploy the resources.
  • Subscription: You’ll need a subscription and owner permissions to deploy the resources and minimize the costs by removing the resources at the end.
  • Azure CLI: To deploy the resources, you’ll need the Azure command-line interface, described in more detail in the documentation.

Now that the prerequisites have been fulfilled, let’s start! Everything is available in the supporting GitHub repository.

Start your preferred terminal and connect to Azure using the Azure CLI and your identity (user account).

az login

List the available subscriptions and locate the preferred subscription identifier.

az account list --output table

Set the subscription you’re using to deploy the resources. Use the subscription identifier from the previous step.

az account set --subscription subscription_id

Because the Azure Container Apps extension is still in preview, you must install the containerapp extension.

az extension add \
  --name containerapp \
  --upgrade

Register the Microsoft.App and Microsoft.OperationalInsights namespaces.

az provider register --namespace Microsoft.App
az provider register --namespace Microsoft.OperationalInsights

Verify the status of the namespaces.

az provider show --namespace Microsoft.App --output table
az provider show --namespace Microsoft.OperationalInsights --output table

Set the environment variables used throughout the upcoming commands.

export RESOURCE_GROUP=apps-rg
export LOCATION=westeurope
export WORKSPACE=robino-apps-log01
export ENVIRONMENT=robino-apps-env01
export APP=robino-apps-app01

Create the apps-rg resource group.

az group create \
  --location $LOCATION \
  --name $RESOURCE_GROUP

Create the robino-apps-env01 container apps environment. The apps deployed in this environment use the same Log Analytics workspace created simultaneously with the environment.

az containerapp env create \
  --name $ENVIRONMENT \
  --resource-group $RESOURCE_GROUP \
  --location $LOCATION

Deploy the robino-apps-app01 container app to the environment using the latest containerapps-helloworld container image.

az containerapp create \
  --name $APP \
  --resource-group $RESOURCE_GROUP \
  --environment $ENVIRONMENT \
  --image mcr.microsoft.com/azuredocs/containerapps-helloworld:latest \
  --target-port 80 \
  --ingress external

Verify the deployment by copying and using the URL in your browser. The container app will open.

The container app page.

Remove the apps-rg resource group, including all the resources. It’ll prompt you for confirmation.

az group delete --name $RESOURCE_GROUP

Finally, log out of the Azure CLI.

az logout

Summary

That’s it! Thank you so much for taking the time to read this post. We’ve reviewed the Azure Container Apps service and its features, compared it to other Azure services, and deployed a simple containerized app.

Azure Container Apps is delivering on its promise, which means that Google Cloud Run and AWS Fargate have a fierce competitor for running containers using a serverless service, including essential features such as autoscaling, load balancing, and event integration.

Azure Container Apps was released into general availability in May, meaning the service is still evolving and maturing. I have the feeling that there’s much more to come. Meanwhile, I’ll further experiment with the service by diving deeper into all the features and building a microservices application. Stay tuned because this will be continued.