9 — Containers
Azure propose 4 services principaux pour héberger des containers + 1 registry pour les stocker. Choisir selon : besoin de control K8s, scale-to-zero, durée du workload.
A. Décider quel service utiliser
| Service | Modèle | Use case | Note |
|---|---|---|---|
| ACI (Container Instances) | Single pod managé | Job ponctuel, batch, ad-hoc | Pas de scale, pas de LB. Démarre en quelques secondes |
| ACA (Container Apps) ⭐ | Serverless, microservices | Microservices stateless avec scale-to-zero | Tourne sur AKS managé par MS, simplifie K8s |
| AKS (Kubernetes Service) | K8s complet | Workloads complexes, stateful, multi-tenants | Tu gères les nodes (cluster K8s natif) |
| Web App for Containers | App Service container | App web simple en container | Voir fiche 8 |
Pour AZ-104 : retenir quand utiliser quoi (questions scénario fréquentes). Pas besoin de connaître K8s en profondeur.
B. Azure Container Registry (ACR)
Registry Docker privé managé. Stocke et distribue les images de containers (et autres OCI artifacts : Helm charts, etc.).
SKUs
| SKU | Storage | Throughput | Geo-replication | Private Endpoint | Content Trust | Use case |
|---|---|---|---|---|---|---|
| Basic | 10 GB | Bas | ❌ | ❌ | ❌ | Dev/test |
| Standard | 100 GB | Moyen | ❌ | ❌ | ❌ | Prod modérée |
| Premium ⭐ | 100 TiB | Haut | ✅ active-active | ✅ | ✅ | Prod multi-region, compliance |
Le SKU est modifiable à chaud (sauf que pour passer Premium → Standard/Basic il faut d'abord supprimer geo-replications + private endpoints).
Auth
- Admin user : compte unique avec username/password (déconseillé, à désactiver).
- Service Principal : pour CI/CD pipelines.
- Managed Identity ⭐ : recommandé. AKS / VM / App Service avec MI accède à l'ACR via RBAC.
- Entra ID + RBAC :
AcrPull,AcrPush,AcrDelete,AcrImageSigner(Premium).
ACR Tasks
Build des images dans Azure (pas besoin de Docker local). 3 modes :
- Quick Task : build one-shot (
az acr build). - Triggered Task : build auto sur git push, base image update, ou schedule.
- Multi-step Task : pipeline (build → test → push) en YAML.
Avantage Tasks : build cross-architecture (ARM64), patching base image auto.
Features Premium importantes
- Geo-replication : 1 registry, N regions, accès local depuis chaque region (pull rapide).
- Private Endpoint : registry uniquement accessible depuis VNet.
- Content Trust : signature des images (Docker Notary).
- Customer-Managed Keys (CMK) pour encryption.
- Repository-scoped tokens : auth granulaire par repo (au lieu d'auth tenant entier).
C. Azure Container Instances (ACI)
Le plus simple : un container (ou un container group) qui tourne, billing à la seconde.
À retenir
- Container group = unité de déploiement (1+ containers partageant le même hostname, IPs, storage). Équivalent d'un pod K8s.
- OS : Linux ou Windows. ⚠️ Tous les containers d'un même group = MÊME OS (pas de mix Linux + Windows). 2 images Linux dans 1 group OK, 2 images Windows OK, mais 1 Linux + 1 Windows = ❌ refus.
🚨 Piège exam : si on te donne 4 images (ex: 2 Linux + 2 Windows Server Core/Nano), tu peux faire 2 container groups (1 par OS), pas 1 group de 4.
- Networking :
- Public IP par défaut (avec FQDN optionnel
<label>.<region>.azurecontainer.io) → DNS name label = public networking obligatoire (privé = pas de FQDN public). - Possibilité de déployer dans un VNet (subnet dédié, IP privée)
- Public IP par défaut (avec FQDN optionnel
- Storage :
- Volumes : Azure File Shares (SMB), Empty Dir, Git repo, Secrets
- Restart policy :
Always/OnFailure/Never - Hyper-V isolation par défaut (chaque pod dans une VM légère).
Use cases AZ-104
- Build agents (CI/CD)
- Batch jobs ponctuels
- Backend léger d'une queue (KEDA-style)
- POC/démos
Limites
- ❌ Pas de scaling auto
- ❌ Pas de load balancing natif
- ❌ Pas de stateful (stockage persistant via Files mount uniquement)
- ❌ Pas de monitoring avancé natif
D. Azure Container Apps (ACA)
Plateforme serverless pour microservices containerisés. Tourne sur AKS managé par MS — tu n'as pas accès à K8s directement.
Concepts clés
- Environment : équivalent du cluster, contient les apps (1 environment = 1 VNet / Log Analytics).
- Container App : 1 application = N revisions.
- Revision : version immutable d'une app (snapshot du container + config).
- Scaling rules (KEDA) : scale-to-zero, HTTP, CPU/RAM, custom (queue length, etc.).
- Ingress : interne ou externe (HTTPS auto, custom domains, mTLS).
- Dapr intégré nativement (pour microservices distribués).
Plans / Environment types
| Plan | Description | Subnet min |
|---|---|---|
| Consumption only | Pay-as-you-go par vCPU-second + RAM-second. Scale-to-zero. Pas d'UDR, pas de NAT GW custom | /23 |
| Workload profiles ⭐ | Mix Consumption + Dedicated (général ou GPU/memory-optimized). Supporte UDR + NAT GW egress | /27 |
🚨 Piège exam : si la question demande "smallest subnet pour ACA workload profiles" → /27. Si /27 n'est pas dans les choix proposés (cas tutorialdojo), prendre la taille immédiatement plus grande disponible (ex /26). Pour Consumption only : /23 minimum (donc /22, /21… acceptables).
Choix de l'environment type est figé à la création (irréversible). Pour migrer Consumption → Workload profiles : recréer.
Connexion à un VNet existant :
- Subnet dédié à l'environment (pas partagé avec autre chose).
- Subnet vide au moment de la création de l'environment.
- 1 environment = 1 VNet (et 1 Log Analytics workspace).
Comparé à AKS
- ✅ Plus simple (pas de gestion nodes, pas de YAML K8s)
- ✅ Scale-to-zero natif
- ❌ Moins de contrôle (pas d'accès K8s API natif)
- ❌ Pas pour workloads très spécifiques (DaemonSets, CRDs custom, etc.)
E. Azure Kubernetes Service (AKS)
K8s managé : MS gère le control plane (gratuit ou payant selon SKU), tu gères les worker nodes.
Architecture
- Cluster : 1 control plane + N node pools.
- Node pool : groupe de VMs (System pool obligatoire pour les services system + User pools pour tes apps).
- Pod : unité de déploiement K8s (1+ containers).
- kubectl : CLI K8s pour interagir avec le cluster.
SKUs (Tier)
| Tier | Description |
|---|---|
| Free | Control plane gratuit, pas de SLA financier sur l'API K8s |
| Standard | Control plane payant, SLA 99.95%, recommandé prod |
| Premium | Standard + Long-Term Support (LTS) sur version K8s |
Auth & Networking
- Auth : Entra ID (recommandé) ou local accounts. RBAC K8s + Azure RBAC.
- Networking models :
- Kubenet : NAT, IPs pods invisibles depuis VNet (legacy, en décommissioning)
- Azure CNI : pods avec IP du VNet, plus performant, IP plus consommé
- Azure CNI Overlay ⭐ : compromis (pods en /24 superposé, IPs économisées)
- Network policies : Calico ou Azure Network Policy.
- Ingress : Application Gateway Ingress Controller (AGIC), ou Nginx, ou Application Routing.
Cluster ops
- Upgrade K8s : control plane d'abord, puis nodes (rolling).
- Auto-upgrade channel :
none,patch,stable,rapid,node-image. - Cluster Autoscaler : scale automatique du nb de nodes.
- HPA (Horizontal Pod Autoscaler) : scale du nb de pods. ⚠️ Nécessite Kubernetes Metrics Server (récupère CPU/RAM des pods pour HPA) — installé par défaut sur AKS.
- VPA (Vertical Pod Autoscaler) : ajuste CPU/RAM des pods.
🚨 Piège exam HPA : "scale pods sur traffic/CPU" → Metrics Server + HPA object (min/max replicas). Mauvaises réponses : Kubernetes Dashboard (visualisation, pas HPA) / AKS Cluster Autoscaler (scale nodes ≠ pods) / Azure Monitor for Containers + VPA (VPA ajuste ressources, ne scale pas le count).
Storage K8s
- PV / PVC (Persistent Volume / Claim).
- Storage classes : Azure Disk, Azure Files, Azure NetApp Files, Blob (CSI drivers).
Pour AZ-104
Niveau d'attente AZ-104 = basique :
- Comprendre la hiérarchie (cluster, node pool, pod, deployment, service).
- Savoir créer un cluster + connecter
kubectl(az aks get-credentials). - Notion de node pool system vs user.
- Notion d'auto-scale.
- Pas de questions K8s pures (CRDs, operators, etc.).
DEMO — chemins portail
ACR — créer + push une image
Portail :
Container registries > Create→ SKU Basic/Standard/Premium, region, name (DNS unique :<name>.azurecr.io)- Optionnel :
Networking(Public/Selected/Private) +Encryption(CMK)
CLI :
# Login
az acr login --name myacr
# Tag + push une image locale
docker tag myapp:v1 myacr.azurecr.io/myapp:v1
docker push myacr.azurecr.io/myapp:v1
# Lister les repos / tags
az acr repository list --name myacr -o table
az acr repository show-tags --name myacr --repository myapp -o table
ACR Tasks — build dans Azure
# Quick build (sans Docker local)
az acr build --registry myacr --image myapp:v1 .
# Triggered task sur push GitHub
az acr task create --registry myacr --name buildmyapp \
--image myapp:{{.Run.ID}} --context https://github.com/user/repo \
--branch main --git-access-token <PAT> --file Dockerfile
ACI — déployer un container
Portail :
Container instances > Create→ image (Quickstart, ACR, Docker Hub)- Onglet Networking : Public IP (avec DNS label) ou Private (VNet/subnet)
- Onglet Advanced : restart policy, env vars (avec secrets), volumes (Azure Files)
CLI :
az container create -g myrg --name mycontainer \
--image myacr.azurecr.io/myapp:v1 \
--cpu 1 --memory 1.5 \
--registry-username <user> --registry-password <pwd> \
--dns-name-label mycontainer-prod \
--ports 80
Container Apps — créer + déployer
Portail :
Container Apps Environment > Create(region, Log Analytics workspace, VNet optionnel)Container App > Createdans cet environment :- Image source : ACR / Docker Hub / quickstart
- Ingress : External (HTTPS public) ou Internal
- Scaling : min replicas, max replicas, rules (HTTP, CPU, custom)
CLI :
# Créer environment
az containerapp env create -g myrg --name myenv -l eastus
# Créer container app avec scale rules
az containerapp create -g myrg --name myapp \
--environment myenv \
--image myacr.azurecr.io/myapp:v1 \
--target-port 80 --ingress external \
--min-replicas 0 --max-replicas 10
AKS — créer un cluster basique
Portail :
Kubernetes services > Create > Kubernetes cluster- Choisir : tier (Free/Standard), version K8s, node pool system (taille + count)
- Onglet Node pools : ajouter user pool si besoin
- Onglet Auth : Entra ID + RBAC (recommandé)
- Onglet Networking : Azure CNI Overlay, NSG, Application Routing
CLI :
# Créer cluster
az aks create -g myrg -n myaks \
--node-count 2 --enable-managed-identity \
--enable-cluster-autoscaler --min-count 1 --max-count 5 \
--network-plugin azure --network-plugin-mode overlay \
--enable-aad
# Récupérer kubeconfig pour kubectl
az aks get-credentials -g myrg -n myaks
# Tester
kubectl get nodes
kubectl get pods -A
AKS — attacher un ACR
# Pour que les nodes AKS puissent pull depuis l'ACR sans creds
az aks update -g myrg -n myaks --attach-acr myacr
Containers — administering hosting (à savoir)
- Logs :
- ACI :
az container logsou Log Analytics workspace - ACA :
az containerapp logs showouLogsblade (KQL) - AKS :
kubectl logs <pod>ou Container Insights (Log Analytics)
- ACI :
- Metrics : Azure Monitor (CPU/RAM/network) pour tous
- Scaling :
- ACI : ❌ pas de scale natif
- ACA : KEDA rules (HTTP, CPU, queue, custom)
- AKS : HPA (pods) + Cluster Autoscaler (nodes)
🏢 Scenarios d'entreprise réels — pensée d'architecte
Comment ces services s'utilisent dans la vraie vie. Pour chaque scenario : contexte business → choix techniques (uniquement les services traités dans la fiche) → pièges typiques.
Scenario 1 : Plateforme fintech microservices régulée (néobanque, paiement)
Contexte business : Néobanque gère paiements + KYC + ledger comptable, ~40 microservices en Go/Java, latence < 50ms p99, pic 24/7 avec saisonnalité (paie fin de mois), PCI-DSS + DORA. Équipe SRE solide, DevOps mature. Choix techniques : AKS Standard tier (SLA 99.95% control plane), ACR Premium geo-replicated (Europe West + North), node pools System + multiple User pools, Azure CNI Overlay, Entra ID + RBAC K8s, HPA + Cluster Autoscaler. Architecture / pattern :
- ACR Premium répliqué EU West + EU North → chaque cluster AKS pull en local (latence + résilience régionale)
--attach-acrpour que les nodes AKS authentifient via Managed Identity, sans creds dans le pipeline- AKS multi-cluster : 1 cluster par region, Front Door en amont
- Node pools :
system(3 nodes, taintsCriticalAddonsOnly) +user-default(apps stateless) +user-memory(matching engine ledger, M-series) +user-spot(batch reconciliation overnight) - HPA sur tous les deploys (Metrics Server natif) avec min=3 (anti-fragile), Cluster Autoscaler 3-50 nodes
- Network policy Calico, Azure Policy for AKS pour enforcer (pas de privileged containers, signed images via Content Trust ACR)
- Auto-upgrade channel
stablesur le control plane,node-imagesur nodes Pièges à éviter : - AKS Free tier en prod : pas de SLA financier sur l'API K8s, un outage = pas de remboursement et l'audit DORA tombe
- 1 seul node pool mix System + User : un workload buggy peut affamer CoreDNS/kube-proxy → split obligatoire
- Pas de ResourceQuota + LimitRange par namespace → 1 dev déploie un Deployment sans limits, OOMKille les voisins. Jamais un namespace sans ResourceQuota.
- ACR Basic en prod multi-region : pas de geo-replication, latence pull cross-region + SPOF si la region du registry tombe
- Mauvaise réponse exam : "scale les pods" = HPA (pas Cluster Autoscaler, pas VPA, pas Dashboard)
Scenario 2 : Plateforme événementielle / e-commerce serverless (retailer DTC)
Contexte business : Marque DTC (direct-to-consumer) avec activité très saisonnière (Noël, soldes). Backend en N microservices stateless (catalog, cart, checkout, recommendations). Reste de l'année = trafic faible. Veut payer 0€ la nuit. Choix techniques : Azure Container Apps Consumption + Workload Profiles (mix), ACR Standard, ingress externe HTTPS auto, KEDA scale-to-zero, Dapr pour la communication inter-services. Architecture / pattern :
- 1 Container Apps Environment Workload profiles (pour avoir UDR + NAT Gateway egress fixe nécessaire à un partenaire paiement qui whitelist des IPs)
- Apps "front" (catalog, recommendations) : scale rule HTTP (concurrent requests > 50 → scale-out), min=0 la nuit, max=30
- Apps "worker" (order processor, mail sender) : scale rule Service Bus queue length (KEDA natif), min=0, scale-out à la première message
- Revisions multiples avec traffic split 90/10 pour canary lors d'un déploiement
- ACR Standard suffit (1 region), authentification AcrPull via Managed Identity du Container App
- Ingress external HTTPS + custom domain + cert managed (gratuit) Pièges à éviter :
- Choisir Consumption only puis réaliser qu'on a besoin d'UDR pour router via firewall → environment type figé à la création, faut recréer en Workload profiles
- Subnet trop petit pour ACA : /27 min pour Workload profiles, /23 min pour Consumption only. Provisionner un /24 et on est coincé en Consumption.
- Scale-to-zero avec un cold start de 5s sur du checkout = perte de panier client. Pour ces apps "money path" : min=1 ou 2.
- ACA = pas d'accès K8s API natif. Si l'équipe veut absolument un CRD spécifique ou un DaemonSet → migrer AKS (mais c'est rare ici)
Scenario 3 : CI/CD build agents + batch jobs ponctuels (ESN, intégrateur)
Contexte business : ESN avec 50 développeurs lance des builds GitHub Actions, tests d'intégration, scripts data migration ponctuels. Pas besoin d'orchestration permanente, juste "lance un container, attends qu'il finisse, paie ce que t'as consommé".
Choix techniques : Azure Container Instances (ACI) pour les jobs ponctuels, ACR Basic ou Standard pour les images custom, Azure Files mounted pour le shared state, restart policy Never.
Architecture / pattern :
- Image custom "ci-runner" (terraform + az CLI + node + .NET) buildée via ACR Tasks (
az acr build) — pas besoin de Docker local sur les laptops des devs - GitHub Actions déclenche
az container createavec env vars (secrets injectés depuis Key Vault via MI), runs, exit → billing à la seconde s'arrête - Restart policy
Never(un job qui crash = échec qu'on veut voir, pas un retry silencieux) - Volume Azure Files mounted pour partager des artefacts entre jobs séquentiels d'un même pipeline
- Container groups quand un job a besoin d'un sidecar (ex: app + nginx reverse proxy pour un test e2e) Pièges à éviter :
- Mélanger Linux + Windows dans le même container group → interdit, le déploiement échoue. Split en 2 container groups.
- DNS name label public sans Service Tag restriction → endpoint container exposé à Internet, scanné en quelques minutes. Soit subnet privé, soit ne pas exposer.
- ACI pour de l'app web "qui tourne tout le temps" → erreur classique. Pas de LB, pas de scale, billing 24/7 supérieur à App Service Basic. Pour du long-running : Container Apps ou App Service.
- ACR Basic = 10 GB storage. Pour une équipe qui pousse 5 images × 50 tags par sprint → satureé en 3 mois, passer Standard (100 GB).
Scenario 4 : Migration progressive d'un monolithe vers microservices (assureur tradi)
Contexte business : Assureur historique avec un monolithe .NET Framework legacy. Stratégie : ne pas tout refondre d'un coup, extraire 1 par 1 des "bounded contexts" (sinistres, devis) en microservices modernes. Équipe ops K8s = en formation, pas encore experte. Choix techniques : Phase 1 = Azure Container Apps (pour livrer vite sans gérer K8s), phase 2 (dans 18 mois quand équipe formée) = AKS pour les workloads complexes. ACR Premium dès le départ (image signing pour compliance + geo-replication). Architecture / pattern :
- Phase 1 — chaque microservice extrait du monolithe = 1 Container App dans un Environment Workload profiles, communication via Dapr pubsub (Service Bus en backend)
- Le monolithe reste sur App Service Premium v3 derrière le même Front Door, routing progressif vers ACA au fur et à mesure
- ACR Premium avec Content Trust + CMK encryption + repository-scoped tokens (équipe sinistres ne peut push que sur
acr/claims/*) - ACR Tasks pour le patching base image auto : nouveau patch de l'image Ubuntu base → rebuild auto de toutes les images applicatives en aval
- Phase 2 (futur) — migration des workloads stateful (legacy SQL listener, jobs longs) vers AKS quand l'équipe sera prête Pièges à éviter :
- Aller direct sur AKS sans expertise = burn la team. ACA d'abord pour bénéficier de la productivité, AKS quand on a des besoins qu'ACA ne couvre pas (DaemonSets, GPU sharing fine-grained, multi-tenancy K8s natif)
- Mettre Content Trust sans former l'équipe → builds rejetés en prod, panique. Le rollout doit être progressif (warn-only puis enforce)
- ACR Premium → Standard downgrade : il faut supprimer geo-replications + private endpoints d'abord. Anticiper pour ne pas se bloquer.
- Mélanger AcrPull et AcrPush sur la même MI : si la MI d'une Container App a AcrPush, un container compromis peut pousser une image malveillante. Toujours AcrPull uniquement pour les consommateurs.
Sources : ACA vs AKS comparison, AKS microservices reference, ACR geo-replication, ACR best practices