Recommend a Container-Based Solution — Lesson
AZ-305 › Unit 4: Design infrastructure solutions › Design compute solutions › Recommend a container-based solution
Recommend a Container-Based Solution — Lesson
A retail platform's CTO walks into a planning meeting with a single slide: "We have 14 microservices and 3 Kubernetes clusters. Two of those clusters run one service each. The third runs everything else. We are paying for 3 control planes, 3 sets of cluster patching, and the platform team is spending half its time on cluster ops, not the product." The architect's question — "did each cluster have to be Kubernetes?" — turned out to be the right one. Two of the clusters became Azure Container Apps environments, and the central one stayed AKS because it ran a stateful workload with a Helm chart from a vendor. Cost dropped 40% and the platform team got their afternoons back. This lesson is about choosing the right container service for each workload — not defaulting to one and paying for that default everywhere.
We will work through Azure's container compute story the way the AZ-305 exam expects you to: distinguishing the four primary container hosts (Azure Container Instances, Azure Container Apps, Azure Kubernetes Service, App Service for Containers), choosing between them based on workload shape, and configuring container registries, networking, and scaling primitives. Reference: the AZ-305 exam study guide, particularly Chapter 4 Skill 4.1 on container-based solutions.
Why This Matters
Containers are now the default packaging format for new workloads — but Azure offers four distinct ways to run a container, and they are not interchangeable. Picking AKS when Azure Container Apps would have worked adds full Kubernetes operational toil (node upgrades, CRDs, RBAC, networking) for a workload that doesn't need it. Picking Container Instances for a steady-state web service overpays per-second pricing instead of per-month. Picking App Service for Containers for a microservice mesh leaves orchestration features (service discovery, dapr, KEDA scalers) on the table.
The AZ-305 exam tests this LO with question shapes like "the team needs X scaling behaviour, Y networking, and Z compliance — which service?". Getting it right is a question of pattern matching workload signals to service capabilities. The financial case is concrete: a small microservice fleet on AKS typically costs the same fleet on Container Apps, mostly because of the always-on system node pool and the operational overhead. If you can match a workload — a single batch container, a microservice mesh, a vendor Helm chart, a quick-start API — to the right container host and configure registry/identity/networking correctly, you will pass this slice of the exam and design container compute like a senior architect.
Prerequisites
Before working through this lesson, make sure you can answer each prompt below in one or two sentences.
- Container fundamentals. Can you explain the difference between an image and a running container, and how registries fit in? — Self-check: where does
docker pullpull from? - Kubernetes basics. Are you fluent with Pods, Deployments, Services, and Namespaces? — Self-check: which one is the unit Kubernetes schedules onto a node?
- Azure resource basics. Do you know what
Microsoft.ContainerService/managedClustersandMicrosoft.App/containerAppscorrespond to? — Self-check: which one isAKS? - Networking models. Can you describe Azure CNI vs kubenet at a sentence each? — Self-check: which one allocates pod IPs from the VNet?
- Identity for compute. Are you fluent with
managed identityandworkload identity? — Self-check: which one is required for non-AKS containers to access Azure resources?
If any of these feels shaky, pause and review the container intro modules in Unit 4 of the AZ-305 guide before continuing.
Learning Objectives
By the end of this lesson, you will be able to:
- Analyse a containerised workload's attributes (orchestration needs, state, scale shape, vendor packaging, integration surface) and translate them into a container service recommendation.
- Evaluate trade-offs between
ACI,Container Apps,AKS, andApp Service for Containersfor a given workload. - Recommend an
Azure Container RegistrySKU and configuration that fits the team's geo, scale, and supply-chain requirements. - Design networking integration (VNet integration, private endpoint, ingress) for a container workload that meets a customer's security posture.
- Configure scale rules (HTTP, KEDA, CPU/memory, scheduled) and identity (managed identity vs workload identity) for a container deployment.
- Recognise common anti-patterns — Kubernetes for single workloads, ACI for steady-state web, missing image vulnerability scanning, latest-tag deployments — and rewrite them.
Building Blocks
Read this section as a glossary. Each term follows the same shape: an everyday analogy, a formal definition, then the reason it matters for the exam.
Container image — A frozen filesystem snapshot of an application and its dependencies. Like a tar archive of the app's runtime requirements. Formally, an OCI-compliant artefact composed of layered filesystem deltas and metadata, pulled from a registry and instantiated as one or more running containers. It matters because the image is the unit of deployment in every Azure container service — image quality (size, layers, vulnerabilities) drives both performance and security.
Azure Container Registry (ACR) — Azure's private OCI-compliant container registry. Like a private DockerHub. Formally, Microsoft.ContainerRegistry/registries resource, available in Basic, Standard, and Premium SKUs, with geo-replication, content trust, and quarantine policies in Premium. It matters because nearly every Azure container deployment pulls from ACR — its SKU and configuration are as important as the runtime host.
Azure Container Instances (ACI) — A single-container quick-start service that runs an image without an orchestrator. Like a serverless docker run. Formally, Microsoft.ContainerInstance/containerGroups — a managed compute service that runs one or a few co-located containers with per-second billing and no cluster overhead. It matters because ACI is the right answer for ephemeral, one-shot, or burst container workloads where orchestration would be overkill.
Azure Container Apps (ACA) — A managed serverless container platform built on Kubernetes, Knative, and Dapr. Like Kubernetes without Kubernetes responsibilities. Formally, Microsoft.App/containerApps — a fully managed environment that exposes scale-to-zero, KEDA scalers, dapr sidecars, and a Knative-style request model without exposing the underlying cluster. It matters because ACA is the modern default for stateless microservices that do not need full Kubernetes flexibility.
Azure Kubernetes Service (AKS) — A managed Kubernetes control plane plus customer-controlled node pools. Like a managed K8s but with nodes you own. Formally, Microsoft.ContainerService/managedClusters — Azure operates the control plane (with optional Uptime SLA), the customer operates the data plane (node pools). It matters because AKS is the right answer when the workload needs Kubernetes-specific features: complex RBAC, third-party Helm charts, CRDs, multi-tenant clusters, GPU pools, custom CNIs.
App Service for Containers — App Service plans that run a custom container image instead of a built-in runtime. Formally, an option on Microsoft.Web/sites that lets a Web App or API App use a customer-built image. It matters because it offers the operational simplicity of App Service (deployment slots, easy SSL, custom domains) for workloads packaged as containers, but lacks orchestration features.
Kubernetes Event-Driven Autoscaling (KEDA) — An add-on that lets Kubernetes (and Container Apps) scale on external event signals. Like an event-aware horizontal pod autoscaler. Formally, an open-source project bundled into ACA and available as an AKS add-on, supporting scalers (HTTP, queue depth, Event Hubs, Service Bus, Kafka, Redis, etc.). It matters because it converts a container workload from "scale on CPU" to "scale on real demand signals" — usually better fit.
Workload identity (federated identity) — A way for a Kubernetes pod or container to authenticate to Azure as a managed identity without storing credentials. Like Workload-aware Azure RBAC. Formally, an OIDC federation between the cluster's identity provider and Microsoft Entra ID, swapped for an Microsoft Entra ID token at runtime. It matters because it replaces brittle pod-identity patterns and is the supported path for AKS / ACA / ACI access to Key Vault, Storage, etc.
Sidecar pattern — A second container in the same pod (AKS) or app revision (ACA) that augments the primary container. Like an auxiliary process running next door. Formally, a co-located process sharing network and (optionally) storage with the primary container; commonly used for service mesh proxies, dapr, logging agents. It matters because the pattern unlocks cross-cutting concerns (mTLS, tracing, retries) without modifying the primary app.
Deep Dive
1. The container-host decision — picking among ACI, ACA, AKS, App Service
The first decision is which service to use. Each one is right for some workloads; none is right for all.
| Service | Best for | Pricing model | Orchestration | Networking |
|---|---|---|---|---|
Azure Container Instances | Ephemeral / burst / single-shot containers | Per-second per container | None | VNet integration optional |
Azure Container Apps | Stateless microservices, event-driven workers | Per-second (scale-to-zero) | Managed Kubernetes (hidden) | VNet integration, Dapr, KEDA |
Azure Kubernetes Service | Full Kubernetes needs, third-party charts | Per-node (control plane optionally paid) | Customer-owned Kubernetes | Full Kubernetes networking |
App Service for Containers | Container-packaged web apps; PaaS familiarity | Per-plan (always-on) | None | App Service VNet integration |
[!TIP] Default to
Container Appsfor new stateless microservices. Move toAKSonly when you can articulate a specific Kubernetes feature you need. Default toACIfor one-shot or short-lived containers.App Service for Containersshines when migrating an existing App Service code-base to a container without changing operational tooling.
The exam tests the inverse: a scenario describes a workload and asks "which service?". The trigger words to memorise:
| Trigger word in question | Service |
|---|---|
| "scale to zero" | Container Apps (or Functions) |
| "third-party Helm chart" | AKS |
| "single one-shot container, fast start" | ACI |
| "uses Dapr / Knative / KEDA" | Container Apps |
| "needs Windows container with custom kernel" | AKS (Windows node pool) |
| "GPU training workload" | AKS with GPU node pool |
| "lift-and-shift web app to container" | App Service for Containers |
| "the team owns Kubernetes" | AKS |
| "the team does not want to own Kubernetes" | Container Apps |
2. Azure Container Registry — the supply-chain layer
Every Azure container service pulls images from somewhere. ACR is the supported default — geo-replicated, identity-integrated, content-trust capable.
resource acr 'Microsoft.ContainerRegistry/registries@2023-07-01' = {
name: 'acrprodneu'
location: 'northeurope'
sku: { name: 'Premium' }
properties: {
adminUserEnabled: false
publicNetworkAccess: 'Disabled'
policies: {
quarantinePolicy: { status: 'enabled' }
trustPolicy: { status: 'enabled', type: 'Notary' }
retentionPolicy: { status: 'enabled', days: 30 }
}
}
}
resource replication 'Microsoft.ContainerRegistry/registries/replications@2023-07-01' = {
parent: acr
name: 'westeurope'
location: 'westeurope'
}[!IMPORTANT] Disable
adminUserEnabledon production ACRs. The admin account is a single shared credential; every supported pull path uses a managed identity / service principal / workload identity instead. The admin user is only useful for early prototyping.
[!WARNING]
BasicandStandardSKUs do not support geo-replication, private endpoints, content trust, or quarantine. For production,Premiumis the answer. The cost premium (/month versus for Basic) is small relative to the supply-chain risk it removes.
3. Container Apps deep dive — the modern default
Container Apps packages most of the Kubernetes value (rolling deployments, autoscale, namespaces, secrets) without exposing the cluster. The two key constructs:
An environment is a logical boundary that shares a VNet, Log Analytics workspace, and (optionally) Dapr / managed identity. Container Apps inside one environment share secure network and observability. A container app is a deployment unit with one or more revisions; KEDA scalers drive replicas.
# Sketch — Container App with a Service Bus queue scaler
properties:
managedEnvironmentId: <env-id>
configuration:
activeRevisionsMode: Single
ingress: { external: true, targetPort: 8080 }
template:
containers:
- image: acrprodneu.azurecr.io/order-worker:1.2.4
resources: { cpu: 0.5, memory: 1.0Gi }
scale:
minReplicas: 0
maxReplicas: 30
rules:
- name: queue-rule
custom:
type: azure-servicebus
metadata:
queueName: orders
messageCount: '10'[!NOTE]
minReplicas: 0enables scale-to-zero. The trade-off is a cold-start latency of seconds on the first request after idle. For consistent low latency, setminReplicas: 1or higher and accept the always-on cost.
4. AKS deep dive — when Kubernetes is the right answer
AKS exposes Kubernetes directly. Choose it when the workload's design requires Kubernetes primitives: CRDs (e.g., for Istio, Argo, KEDA advanced features), multi-tenant RBAC across namespaces, custom CNIs, or a third-party platform that ships as a Helm chart.
| AKS feature | Why it matters |
|---|---|
| Multiple node pools | Mix CPU and GPU pools, system and user pools, Linux and Windows pools |
| Cluster autoscaler | Scales nodes in response to pending pods |
| Virtual Nodes | Bursts pods onto ACI for spiky workloads |
| Azure CNI Overlay | VNet-aware pod networking without exhausting VNet IPs |
| Workload Identity | Pods authenticate to Azure with managed identities |
| Azure Policy add-on | Cluster-scope policy enforcement |
| Uptime SLA add-on | 99.95% control-plane SLA (with multi-AZ node pools, 99.99% data plane) |
# Create an AKS cluster with autoscaler and workload identity
az aks create \
--resource-group rg-app \
--name aks-prod \
--location westeurope \
--node-count 3 \
--enable-cluster-autoscaler --min-count 3 --max-count 10 \
--enable-oidc-issuer --enable-workload-identity \
--network-plugin azure --network-plugin-mode overlay \
--node-vm-size Standard_D4s_v5 \
--zones 1 2 3[!WARNING] Kubenet networking is deprecated for AKS production use. Default to
azure CNI(orazure CNI overlayif you are tight on VNet IPs). The exam tests the choice of CNI as a scenario where the cluster runs out of pod IPs.
5. Scale, identity, and observability — the operational triad
Once the host is chosen, three operational settings determine whether the deployment runs well: how it scales, how it authenticates, and how it is observed.
The exam frequently tests the combination: a scenario describes a workload, asks for a topology, and bundles a "and also configure identity" addendum. The right pattern is always to use workload identity (not pod identity, not service-principal secrets) and KEDA scalers (not just CPU).
// Find Container App revisions that have been live for > 30 days — refresh candidates
ContainerAppSystemLogs_CL
| where TimeGenerated > ago(30d)
| where Reason_s == "RevisionActivated"
| summarize firstSeen=min(TimeGenerated) by RevisionName_s, ContainerAppName_s
| where firstSeen < ago(30d)
| project ContainerAppName_s, RevisionName_s, firstSeen
| order by firstSeen asc6. Image hygiene — the silent quality gate
Three image-level practices separate professional container deployments from amateur ones:
- Pin tags by digest, not by
latest.image: my.acr.io/app@sha256:abc123...makes rollouts deterministic.image: my.acr.io/app:latestmakes them race conditions. - Scan images on push. Microsoft Defender for Containers in ACR Premium flags CVEs at push time. Reject vulnerable images at the registry, not in production.
- Sign images with Notary v2. ACR Premium supports
notationsigning; pull verification can be enforced by ACA, AKS, and admission controllers.
Worked Examples
Easy — pick a container host
Problem. A team has 5 stateless microservices that they want to deploy as containers. They do not want to operate Kubernetes. The services communicate via HTTP and Service Bus. Recommend a container host.
Solution. Azure Container Apps. The five services map to five container apps in one environment. ACA handles ingress, internal service-to-service routing, scale-to-zero, Service Bus scalers via KEDA, and managed identity for Azure access. No Kubernetes operational toil, and the team can adopt Dapr if they later want service discovery / state management / pub-sub abstractions.
[!NOTE] If one of the five services later needs a Helm chart from a vendor or a complex Istio service mesh, that one workload moves to
AKS— but the other four stay on ACA.
Medium — AKS networking with limited VNet IPs
Problem. An AKS cluster needs 200 pods across 5 nodes. The VNet subnet has only 128 IPs free. Recommend a CNI configuration.
Solution. Use Azure CNI Overlay. Overlay mode allocates pod IPs from a private overlay range (not the VNet subnet), so the cluster can have thousands of pods without exhausting VNet IPs. Node IPs still come from the VNet subnet (5 IPs needed). The alternative — classic Azure CNI — would have required IPs from the VNet, which is not available. Kubenet is deprecated. The fix is a one-flag config change at cluster create.
networkProfile:
networkPlugin: azure
networkPluginMode: overlay
podCidr: 10.244.0.0/16
serviceCidr: 10.0.0.0/16Hard — multi-host topology with shared ACR
Problem. A multinational retailer wants 4 services: an order API (3 regions), a vendor inventory sync (third-party Helm chart), a nightly report job (one-shot, 2-hour runs), and a customer-facing web app migrated from App Service. Recommend a per-service container host, a shared ACR design, and how identity is managed.
Solution. Mix four hosts according to fit:
| Service | Host | Why |
|---|---|---|
| Order API | Azure Container Apps (per region) | Stateless microservice, scale-to-zero overnight, KEDA scalers |
| Inventory sync | AKS | Third-party Helm chart; needs CRDs |
| Nightly report | Container Apps Job | One-shot per night, scale-to-zero between runs |
| Customer web app | App Service for Containers | Lift-and-shift from existing App Service Plan |
ACR: a single Premium registry geo-replicated to the four regions hosting workloads. Every host uses a managed identity granted AcrPull on the registry — no shared credentials. AKS uses workload identity for cluster-internal pulls; ACA / App Service use system-assigned managed identity.
[!TIP] Geo-replicated ACR is required when workloads pull images at startup in multiple regions — without geo-replication, image pulls cross regions and add latency / cost.
Visual Explanations
Figure 1 — Container service decision flow
The tree's first branch is the most consequential. Kubernetes adoption is a strategic platform choice; the architect should resist taking on Kubernetes ops unless the workload genuinely demands it.
Figure 2 — ACR private-endpoint topology
The pattern: a Premium ACR with public access disabled, a private endpoint into the hub VNet, and consumer workloads (AKS + ACA) using workload / managed identities to authenticate without shared secrets.
Figure 3 — Scale rule shapes
| Scaler type | Source signal | Typical use |
|---|---|---|
| HTTP scaler (ACA) | Concurrent requests | Web APIs, sync workloads |
KEDA Service Bus | Queue / topic depth | Async work behind SB |
KEDA Event Hubs | Unprocessed event lag | Streaming processors |
KEDA cron | Time schedule | Pre-warm before peak, drain after |
| CPU / memory | Resource pressure | Generic CPU-bound apps |
| HPA (AKS) | Custom metric (Prometheus) | Anything with a real metric |
The richer the scaler set, the better the cost. Most architects who default to CPU-based scaling overpay during low-but-bursty traffic.
Figure 4 — Pricing shape sketch
| Host | Idle cost | Burst cost | Steady cost |
|---|---|---|---|
ACI | 0 (per-second) | High (per container) | Wasteful |
Container Apps (min=0) | 0 | Low (per-second) | Low |
Container Apps (min=1) | Low (always-on baseline) | Low | Low |
AKS (D4 ) | High (node pool always on) | Low marginal | Low |
App Service for Containers | Plan cost | Plan cost (scaled) | Plan cost |
A "right answer" depends on the load shape: ACA scale-to-zero wins on idle, AKS wins on dense steady-state.
Common Mistakes
❌ Myth: "We'll always run on Kubernetes — it's the modern standard." ✅ Reality: Kubernetes is one of several modern container hosts. For workloads without a Kubernetes-specific need,
Container Appsdelivers the same scaling, deployment, and networking outcomes with less operational toil. Why it's tricky: Industry mind-share rewards Kubernetes adoption. Architects pick AKS for resume value, not workload fit.
❌ Myth: "ACR Standard SKU is enough for production — Premium is luxury." ✅ Reality: Production workloads need private endpoints, geo-replication, content trust, and Defender for Containers — all Premium-only features. The cost gap is small; the security and reliability gap is large. Why it's tricky: The SKU names are misleading — "Standard" sounds like it suits production.
❌ Myth: "Container Apps is just Kubernetes with the cluster hidden." ✅ Reality: ACA is intentionally not Kubernetes. You cannot run arbitrary CRDs, install Helm charts, or apply a Kubernetes manifest. The abstraction is a feature, not a limitation — workloads that need Kubernetes go to AKS. Why it's tricky: The architecture is Kubernetes-based, but the surface is not. Teams who try to "use Helm with ACA" misunderstand the model.
❌ Myth: "Image tagging with
latestis fine — that's how Docker tutorials show it." ✅ Reality:latestis a moving tag. Production deployments should pin by digest (@sha256:...) for determinism. Rolling out withlatestis a frequent cause of "it worked yesterday" outages. Why it's tricky: Tutorials uselatestfor convenience. Production teams inherit it.
Practice Exercises
🟢 Exercise 1. A team needs to run a 10-minute one-shot container that processes a manually uploaded file. Recommend a host.
▶💡 Hint
Per-second billing, no orchestrator needed.
▶✅ Solution
Azure Container Instances. The workload is ephemeral and has no orchestration needs. ACI starts the container on demand, runs it, and bills per second. After it exits, no cost. Alternative: Container Apps Job if the team already has an ACA environment — but for a one-off, ACI is simpler.
🟡 Exercise 2. A vendor distributes an inventory-sync platform as a Helm chart with 20 CRDs and requires Istio service mesh. Recommend a host.
▶💡 Hint
Helm + CRDs + Istio is Kubernetes-only.
▶✅ Solution
AKS. Helm charts that ship CRDs cannot be deployed to Container Apps (no CRD support) or App Service for Containers (no Kubernetes at all). AKS with a multi-node-pool design and the Istio managed add-on is the supported path.
🟡 Exercise 3. A microservice has bursty traffic — 0 requests overnight, 100 rps during peak business hours. Architect wants to scale to zero overnight. Cost matters. Recommend a configuration.
▶💡 Hint
Scale-to-zero is the differentiator.
▶✅ Solution
Azure Container Apps with minReplicas: 0, maxReplicas: N, and an HTTP scaler with concurrentRequests: 50. Overnight the service idles at zero replicas and zero cost; during peak, ACA scales replicas up based on concurrent request count. First-request latency after idle is s — acceptable for most internal/business APIs. For customer-facing low-latency APIs, set minReplicas: 1.
🔴 Exercise 4. An ACR has 4 subscribers in 4 regions. Pull times during deployment are seconds in 3 regions and minutes in the fourth. Diagnose and recommend.
▶💡 Hint
Cross-region pulls are slow. Geo-replication fixes them.
▶✅ Solution
The slow region is pulling cross-region from the ACR's primary location. Upgrade the ACR to Premium (if not already) and enable geo-replication to the fourth region. Pull times normalise to s everywhere. Cost increase is modest; supply-chain reliability is the payoff.
🔴 Exercise 5. A startup runs 1 microservice on AKS with 3 nodes (/month) and no other workloads in the cluster. CFO asks how to cut cost. Recommend.
▶💡 Hint
One service does not need a cluster.
▶✅ Solution
Migrate to Azure Container Apps. One service does not justify an AKS control plane and three nodes. ACA will run the same container with min replicas 1 (for HA) at a small fraction of the AKS cost (/month for similar capacity). The team also recovers operational time spent on cluster patching.
🟢 Exercise 6. True or false: an ACR with adminUserEnabled: true is acceptable for production.
▶💡 Hint
Look up Microsoft's identity-best-practice for ACR.
▶✅ Solution
False. The admin user is a shared credential that bypasses Microsoft Entra ID identity controls. Production deployments should disable it and pull via managed identity / workload identity / service principal with AcrPull role assignment. The admin user is intended for the very first test pull, then disabled.
🟡 Exercise 7. Design a Bicep snippet for a Container Apps Environment and a single Container App exposing port 8080 externally, with min replicas 2 and CPU-based scaling up to 10.
▶💡 Hint
Look up Microsoft.App/managedEnvironments and Microsoft.App/containerApps.
▶✅ Solution
resource env 'Microsoft.App/managedEnvironments@2024-03-01' = {
name: 'aca-env-prod'
location: location
properties: {
appLogsConfiguration: {
destination: 'log-analytics'
logAnalyticsConfiguration: { customerId: logAnalyticsId, sharedKey: logAnalyticsKey }
}
}
}
resource app 'Microsoft.App/containerApps@2024-03-01' = {
name: 'ca-web'
location: location
properties: {
managedEnvironmentId: env.id
configuration: { ingress: { external: true, targetPort: 8080 } }
template: {
containers: [ { name: 'web', image: 'acrprodneu.azurecr.io/web:1.0.0', resources: { cpu: 1, memory: '2.0Gi' } } ]
scale: {
minReplicas: 2
maxReplicas: 10
rules: [ { name: 'cpu', custom: { type: 'cpu', metadata: { type: 'Utilization', value: '70' } } } ]
}
}
}
}Summary & Concept Map
The headline takeaways from this lesson:
- Four container hosts, four sweet spots.
ACIfor ephemeral / one-shot,Container Appsfor stateless microservices,AKSfor Kubernetes-feature-driven workloads,App Service for Containersfor migrating from App Service. Container Appsis the modern default. Reach forAKSonly when you can name the Kubernetes feature you need.Azure Container RegistryPremium is the production SKU. Private endpoint, geo-replication, content trust, quarantine.- Identity is workload identity or managed identity. Disable ACR admin user; never embed credentials in images.
- Scale on real signals, not just CPU. KEDA scalers (queues, event hubs, cron) usually fit the workload better.
- Pin images by digest in production. Tags drift; digests do not.
Walk the map workload-down. The hard decisions live near the top of the tree; below it, the supporting configuration (registry SKU, identity, scaler choice) is the same regardless of host.