Azure Container Hosting – which service should you use?

Its Christmas time, and that means its time for another month of the always fantastic Festive Tech Calendar. This was one of the first events that I participated in when I was trying to break into blogging and public speaking and I’m delighted to be involved again this year.

This year, the team are raising funds for Beatson Cancer Charity who raise funds to transform the way cancer care is funded and delivered by funding specialists, research and education to invest in a better future for cancer patients. You can make donations via the Just Giving page.

In this post, I’ll walk through the extensive list of Container hosting options that are available on Azure. I’ll take a look at the Azure-native offerings, include some third-party platforms that run on Azure, and then compare them on performance, scalability, costs, and service limits.

What counts as “Container Hosting” on Azure?

For this post I’m treating a “container hosting option” as:

A service where you can run your own Docker images as workloads, with Azure (or a partner) running the infrastructure.

There are an extensive list of options (and I will exclude a few off the list below, but the main “go-to” options that I’ve seen in architecture discussions are:

  • Azure Container Apps
  • Azure Kubernetes Service (AKS)
  • Azure Container Instances (ACI)
  • Azure App Service (Web Apps for Containers)
  • Azure Service Fabric (with containers)
  • Azure Red Hat OpenShift (ARO) – OpenShift on Azure
  • Kubernetes platforms on Azure VMs or Azure VMware Solution (VMware Tanzu, Rancher, etc.)

But what about the humble reliable Virtual Machine?

OK yes, its still out there as an option – the Virtual Machine with Docker installed to run containers. And its the place where most of us have started on this journey (you can check out a blog series I wrote a few years ago here on the subject of getting started with running Docker on VM’s).

There are still some situations where you will see a need for Virtual Machines to run containers, but as we’ll see in the options below, this has been superseded by the range of offerings available on Azure who can run containers from single instances right up to enterprise level offerings.

Azure Container Instances (ACI)

Lets start with the smallest available form of hosting which is Azure Container Instances. ACI is the “run a container right now without VMs or an orchestrator” service – there are no virtual machines or orchestrators to manage, and containers start within seconds on Azure’s infrastructure. ACI provides a single container or small group of containers (called a container group) on-demand. This simplicity makes it essentially “containers-as-a-service”.

You can run a container by issuing a single Azure CLI command. It’s completely managed by Azure: patching, underlying host OS, and other maintenance are invisible to the user. ACI also supports both Linux and Windows containers.

Its great for short-lived tasks and simple container groups, good examples of this would be Cron-style jobs, build workers, data processing pipelines, and dev/test experiments where you just want a container to run for a bit and then disappear.

Azure App Service (Web Apps for Containers)

Azure App Service (Web App for Containers) is a Platform-as-a-Service offering that lets you deploy web applications or APIs packaged as Docker containers, without managing the underlying servers.

This uses all of the features that you would normally see with App Service – you get deployment slots, auto-scaling, traffic routing, and integrated monitoring with Azure Monitor. The benefit of this is that it abstracts away the container management and focuses on developer productivity for web applications.

The use case of using App Service is the familiarity with the product. Its gives you predictable, reserved capacity and can be used to host HTTP APIs or websites where you don’t want to have the overhead of using Kubernetes, but want to utilise features like deployment slots, built-in auth, easy custom domains, built-in backup & integration.

Azure Container Apps

Azure Container Apps is a fully managed container execution environment, designed specifically for microservices, APIs, and event-driven processing.

It abstracts away the Kubernetes infrastructure and provides a serverless experience for running containers – meaning you can run many containers that automatically scale in response to demand and even scale down to zero when idle.

Container Apps sits on top of Kubernetes (it runs on Azure’s internal K8s with open technologies like KEDA, Dapr, and Envoy) but as a developer you do not directly interact with Kubernetes objects. Instead, you define Container Apps and Azure handles placement, scaling, and routing.

Container Apps is an ideal place for running Microservices, APIs and event-driven jobs where you don’t want to manage Kubernetes, and want to scale-to-zero and only pay when there’s traffic. Its a nice “middle ground” between App Service and full AKS.

Azure Kubernetes Service (AKS)

We’re finally getting to the good stuff!!

Image Source – Microsoft

Azure Kubernetes Service (AKS) is Azure’s flagship container orchestration service, offering a fully managed Kubernetes cluster.

With AKS, you get the standard open-source Kubernetes experience (API, kubectl, and all) without having to run your own Kubernetes control plane – Azure manages the K8s master nodes (API servers, etc.) as a service.

You do manage the worker nodes (agent nodes) in terms of deciding their VM sizes, how many, and when to scale (though Azure can automate scaling).

In terms of ease-of-use, AKS has a steep learning curve if you’re new to containers, because Kubernetes itself is a complex system. Provisioning a cluster is quite easy (via Azure CLI or portal), but operating an AKS cluster effectively requires knowledge of Kubernetes concepts (pods, services, deployments, ingress controllers, config maps, etc.).

It’s less turn-key than the earlier services – you are stepping into the world of container orchestration with maximum flexibility. One of the main benefits of AKS is that it’s not an opinionated PaaS – it’s Kubernetes, so you can run any containerized workload with any configuration that Kubernetes allows.

Another reason for choosing AKS is that you can run it locally in your environment on an Azure Local cluster managed by Azure Arc.

The main reason for choosing AKS is running enterprise or large-scale workloads that need:

  • Full Kubernetes API control
  • Custom controllers, CRDs, service meshes, operators
  • Multi-tenant clusters or complex networking

If you’re already familiar with Kubernetes, this is usually the default choice.

Azure Red Hat OpenShift (ARO)

Azure Red Hat OpenShift (ARO) is a jointly managed offering by Microsoft and Red Hat that provides a fully managed OpenShift cluster on Azure.

OpenShift is Red Hat’s enterprise Kubernetes distribution that comes with additional tools and an opinionated setup (built on Kubernetes but including components for developers and operations). With ARO, Azure handles provisioning the OpenShift cluster (masters and workers) and critical management tasks, while Red Hat’s tooling is layered on top.

It’s a first-class Azure service, but under the covers, it’s Red Hat OpenShift Container Platform. In terms of ease-of-use: for teams already familiar with OpenShift, this is much easier than running OpenShift manually on Azure VMs. The service is managed, so tasks like patching the underlying OS, upgrading OpenShift versions, etc., are handled in coordination with Red Hat.

The use case for ARO comes down to whether you’re an OpenShift customer already, or need OpenShift’s enterprise features (built-in pipelines, operators, advanced multi-tenancy).

Azure Service Fabric

Service Fabric predates AKS and was Azure’s first container orchestrator. I’ve not seen this ever out in the wild but it deserves a mention here as its still available as a container hosting platform on Azure.

Its a mature distributed systems platform from Microsoft, used internally for many Azure services (e.g., SQL DB, Event Hubs). It can orchestrate containers as well as traditional processes (called “guest executables”) and also supports a unique microservices programming model with stateful services and actors where high-throughput is required.

I’m not going to dive too deep into this topic, but the use case for this really is if you already have significant investment in Service Fabric APIs.

Third-party Kubernetes & container platforms on Azure

Beyond the native services above, you can also run a variety of third-party platforms on Azure:

  • Kubernetes distributions on Azure VMs: VMware Tanzu Kubernetes Grid, Rancher, Canonical Kubernetes, etc., deployed directly onto Azure VMs.
  • Azure VMware Solution + Tanzu: run vSphere with Tanzu or Tanzu Kubernetes Grid on Azure VMware Solution (AVS) and integrate with Azure native services.

There are a number of reasons for ignoring the native Azure services and going for a “self-managed” model:

  • If you need a feature that AKS/ARO doesn’t provide (e.g., custom Kubernetes version or different orchestrator, or multi-cloud control plane).
  • If you want to avoid cloud vendor lock-in at the orchestration layer (some companies choose BYO Kubernetes to not depend on AKS specifics).
  • If your organization already invested in those tools (e.g., they use Rancher to manage clusters across AWS, on-prem and also want to include Azure).
  • If you have an on-prem extension scenario: e.g., using VMware Tanzu in private cloud and replicating environment in Azure via AVS to have consistency and easy migration of workloads.
  • Or if you require extreme custom control: e.g., specialized network plugins or kernel settings that AKS might not allow.

Comparison Summary

Lets take a quick comparison summary where you can see at a glance the ease of use, hosting, cost model and use cases of each service:

OptionEase of UseHosting ModelCost ModelBest For
Azure Container InstancesVery High Serverless Pay per second of CPU/Memory, no idle cost.Quick tasks, burst workloads, dev/test, simple APIs.
Azure App Service High PaaSFixed cost per VM instance (scaled-out). Always-on cost (one or more instances).Web apps & APIs needing zero cluster mgmt, CI/CD integration, and auto-scaling.
Azure Container AppsModerate ServerlessPay for resources per execution (consumption model) + optional reserved capacity. Idle = zero cost.Microservice architectures, event-driven processing, varying workloads where automatic scale and cost-efficiency are key.
Azure Kubernetes Service (AKS)Low (for beginners).  Moderate (for K8s proficient teams).Managed Kubernetes (IaaS+PaaS mix)Pay for VMs (nodes) only. Control plane free (standard tier) Complex, large, or custom container deployments
Azure Red Hat OpenShift (ARO)Moderate/Low – easy for OpenShift experts, but more complex than AKS for pure K8s users. Managed OpenShift (enterprise K8s)Pay for VMs + Red Hat surcharge. Higher baseline cost than AKS.Organizations requiring OpenShift’s features (built-in CI, catalog, stricter multi-tenancy) or who have OpenShift on-prem and want cloud parity.
Azure Service FabricLow – steep learning curve IaaS (user-managed VMs) with PaaS runtimePay for VMs No automatic scaling – you manage cluster size.Stateful, low-latency microservices, or mixed workloads (containers + processes). Teams already leveraging SF’s unique capabilities.

Conclusion

As we can see above, Azure offers a rich spectrum of container hosting options.
Serverless and PaaS options cover most workloads with minimal ops overhead, while managed Kubernetes and third-party platforms unlock maximum flexibility at higher complexity.

In my own opinion, the best way to go is to make the decision based on business needs and the core knowledge that exists within your team. Use managed and/or serverless options by default; move to Kubernetes only when needed.

You can use the decision tree shown below as an easy reference to make the decision based on the workload you wish to run.

Image Source – Microsoft

I hope this blog post was useful! For a deeper dive, you can find the official Microsoft guide for choosing a Container hosting service at this link.

100 Days of Cloud – Day 85: Security for Azure Containers

Its Day 85 of my 100 Days of Cloud journey, and in todays post I’m looking at the options for Container Security in Azure.

Image Credit: Docker Saigon Github

We looked at an overview of Containers on Day 81, how they work like a virtual machines in that they utilize the underlying resources offered by the Container Host, but instead of packaging your code with an Operating System, each container only contains the code and dependencies needed to run the application and runs as a process inside the OS Kernel. This means that containers are smaller and more portable, and much faster to deploy and run.

We need to secure Containers in the same way as we would any other services running on the Public Cloud. Lets take a look at the different options that are available to us for securing Containers.

Use a Private registry

Containers are built from images that are stored in either public repositories such as Docker Hub, a private registry such as Docker Trusted Registry, which can be installed on-premises or in a virtual private cloud, or a cloud-based private registry such as Azure Container Registry.

Like all software that is publicly available on the internet, a publicly available container image does not guarantee security. Container images consist of multiple software layers, and each software layer might have vulnerabilities.

To help reduce the threat of attacks, you should store and retrieve images from a private registry, such as Azure Container Registry or Docker Trusted Registry. In addition to providing a managed private registry, Azure Container Registry supports service principal-based authentication through Azure Active Directory for basic authentication flows. This authentication includes role-based access for read-only (pull), write (push), and other permissions.

Ensure that only approved images are used in your environment

Allow only approved container images. Have tools and processes in place to monitor for and prevent the use of unapproved container images. One option is to control the flow of container images into your development environment. For example, you only allow a single approved Linux distribution as a base image in order to minimize the surface for potential attacks.

Another option is to utilize Azure Container Registry support for Docker’s content trust model, which allows image publishers to sign images that are pushed to a registry, and image consumers to pull only signed images.

Monitoring and Scanning Images

Use solutions that have the ability to scan container images in a private registry and identify potential vulnerabilities. Azure Container Registry optionally integrates with Microsoft Defender for Cloud to automatically scan all Linux images pushed to a registry to detect image vulnerabilities, classify them, and provide remediation guidance.

Credentials

Credential management is one of the most basic tyes of security. Because containers can spread across several clusters and Azure regions, you need to ensure that you have secure credentials required for logins or API access, such as passwords or tokens.

Using tools such as TLS encryption for secrets data in transit, least-privilege Azure role-based access control (Azure RBAC), and Azure Key Vault to securely store encryption keys and secrets (such as certificates, connection strings, and passwords) for containerized applications.

Removing unneeded privileges from Containers

You can also minimize the potential attack surface by removing any unused or unnecessary processes or privileges from the container runtime. Privileged containers run as root. If a malicious user or workload escapes in a privileged container, the container will then run as root on that system.

Enable Auditing Logging for all Container administrative user access

Use native Azure Solutions to maintain an accurate audit trail of administrative access to your container ecosystem. These logs might be necessary for auditing purposes and will be useful as forensic evidence after any security incident. Azure solutions include:

  • Integration of Azure Kubernetes Service with Microsoft Defender for Cloud to monitor the security configuration of the cluster environment and generate security recommendations
  • Azure Container Monitoring solution
  • Resource logs for Azure Container Instances and Azure Container Registry

Conclusion

So thats a brief overview of how we can secure containers running in Azure and ensure that we are only using approved images that have been scanned for vulnerabilities.

Hope you enjoyed this post, until next time!

100 Days of Cloud – Day 82: Options for Managing Containers in Azure

Its Day 82 of my 100 Days of Cloud journey, and in todays post I’m going to look at options for managing Containers in Azure.

In the last post, we looked at the comparison between Bare Metal or Physical Servers, Virtual Servers and Containers and the pros and cons of each.

We also introducted Docker, which is the best known method of managing containers using the Docker Engine and built-in Docker CLI for command management.

The one thing we didn’t show was how to install Docker or use any of the commands to manage our containers. This is because I’ve previously blogged about this and you can find all of the details as part of my series about Monitoring with Grafana and InfluxDB using Docker Containers. Part 1 shows how you can create your Docker Host running on an Ubuntu Server VM (this could also run on a Bare Metal Physical Server), and Part 2 shows the setup and configuration of Docker Containers that have been pulled from Docker Hub. So head over there and check that out, but don’t forget to come back here!

Docker Context

By default when running any Docker commands from the CLI, Docker automatically assumes that you wish to use the local Docker Host for storing and running your containers. However, you can manage multiple Docker or Kubernetes hosts or nodes by specifying contexts. A single Docker CLI can have multiple contexts. Each context contains all of the endpoint and security information required to manage a different cluster or node. The docker context command makes it easy to configure these contexts and switch between them.

In short, this means that you can manage container instances that are installed on multiple hosts and/or multiple cloud providers from a single Docker CLI.

Let take a look at the different options for managing containers in Azure.

The Docker CLI Method

In order to use containers in Azure using Docker, we first need to log on to Azure using the docker login azure command, which will prompt us for Azure credentials. Once entered, this will return “login succeeded”:

We then need to create a context by running the docker context create aci command. This will associate Docker with an Azure subscription and resource group that you can use to create and manage container instances. So we would run docker context create aci myacicontext to create a context called myacicontext.

This will select your Azure subscription ID, then prompt to select an existing resource group or create a new resource group. If you choose a new resource group, it’s created with a system-generated name. Like all Azure resources, Azure container instances must be deployed into a resource group

Once thats completed, we then run docker context use myacicontext – this ensures that any subsequent commands will run in this context. We can now use docker run to deploy containers into our Azure resource group and manage these using the Azure CLI. So lets run the following command to deploy a quickstart container runing Node.js that will give us a static website:

docker run -p 80:80 mcr.microsoft.com/azuredocs/aci-helloworld

We can now run docker ps to see the running container and get the Public IP that we can use to browse to it:

And if we log onto the Portal, we can see our running container:

So as we’ve always done, lets remember to remove the container by running docker stop sweet-chatterjee, and then docker rm sweet-chatterjee. These commands stops and deletes the Azure Container Instance:

Finally, run docker ps to ensure the container has stopped and is no longer running.

The Azure Portal Method

There are multiple ways to create and manage containers natively in Azure. We’ll look at the portal method in this post, and reference the remaining options at the end of the page.

To create the container, log on to the Portal and select Container Instances from the Marketplace:

Once we select create, we are brought into the now familiar screen for creating resources in Azure:

One important thing to note on this screen is the “Image Source” option – we can select container images from either:

  • The quickstarts that are available in Azure.
  • Images stored in your Azure Container Registry.
  • Other registry – this can be Docker or other public or private container registry.

On the “Networking” screen, we need to specify a public DNS name for our container, and also the ports we wish to expose across the Public Internet

And once thats done, we click “Review and Create” to deploy our container:

Once thats done, we can see the FQDN or Public IP that we can use to browse to the container:

As always, make sure to stop and delete the container instance once finished if you are running these in a test environment.

There are a total of four other options in Azuire for creating and managing containers:

Conclusion

So thats a look at how we can create and manage Azure Container Instances using both Docker CLI and the wide range of options available in Azure.

Azure Container Instances is a great solution for any scenario that can operate in isolated containers, including simple applications, task automation, and build jobs. You can find all of the documentation on Azure Container Instances here.

Hope you enjoyed this post, until next time!