Lesson 7: Azure AKS Internals, Cilium CNI Overlay & Azure Dependent PaaS Ecosystem
- Core Architecture: Azure CNI Overlay with Cilium eBPF, Ephemeral NVMe OS Disks ($0 cost), Entra Workload Identity OIDC, and Private Endpoint integrations.
- Must-Know Traps:
AADSTS70021Workload Identity subject claim mismatch; SNAT port exhaustion on Azure Public Load Balancer; Cosmos DB physical partition hot-spot HTTP 429s. - Staff Triage SOP:
kubectl get events -n kube-systemfor Cilium IPAM;az aks show -n ... --query oidcIssuerProfileto verify OIDC URI.
๐ง The Concept (Explain Like Iโm 5)
Running Kubernetes on Microsoft Azure (AKS) alongside Azureโs managed PaaS services is like running a high-speed bullet train station:
- AKS Node Pools & Ephemeral OS Disks: Instead of booting worker nodes off slow network hard drives (which choke when 50 containers pull images at once), Ephemeral OS Disks run the nodeโs operating system directly inside the serverโs ultra-fast local NVMe cacheโat $0 extra storage cost!
- Azure CNI Overlay with Cilium: Instead of giving every temporary pod a scarce corporate VNet IP address, pods get private internal apartment numbers (
100.64.x.x) routed at kernel speed by Cilium eBPF, while nodes sit on the corporate VNet street. - Entra Workload Identity + Key Vault CSI: Pods show a short-lived cryptographic passport (OIDC token) to Microsoft Entra ID to fetch database passwords directly from Azure Key Vault into RAMโzero static secrets stored in Git or etcd.
- Azure Dependent PaaS Services: Around AKS sits Azureโs enterprise ecosystem: Azure Front Door (global CDN/WAF shield), Application Gateway for Containers (L7 ingress), Cosmos DB (planet-scale database with 5 tunable consistency levels), and Azure Service Bus (transactional message queues that trigger KEDA to autoscale pods).
๐บ๏ธ Visual Architecture: Production AKS & Azure Dependent Services Reference Stack
flowchart TD
Users["๐ Global Users & Mobile Apps"] -->|"Anycast HTTPS"| AFD["๐ก๏ธ <b>Azure Front Door Premium</b><br/>Global WAF + DDoS + Edge Caching"]
AFD -->|"Private Link Origin<br/>(Zero Public IPs)"| AGC["โ๏ธ <b>App Gateway for Containers</b><br/>(Kubernetes Gateway API / ALB for AKS)"]
subgraph AKSVNet ["โธ๏ธ Azure AKS Production VNet (Azure CNI Overlay + Cilium eBPF)"]
AGC --> SysPool["<b>System Node Pool</b><br/>CriticalAddonsOnly=true:NoSchedule<br/>CoreDNS, Cilium, Konnectivity"]
AGC --> UserPool["<b>User Node Pool (NAP / Karpenter)</b><br/>Ephemeral NVMe OS Disks + Spot VMs"]
UserPool --> KEDA["โก <b>KEDA Autoscaler</b><br/>Scales Pods 0 to 500 on Queue Depth"]
UserPool --> CSI["๐ <b>Key Vault CSI Driver</b><br/>Entra Workload Identity OIDC"]
end
subgraph DependentPaaS ["๐๏ธ Azure Dependent Enterprise PaaS Layer (Via Private Endpoints)"]
KV["๐ <b>Azure Key Vault</b><br/>HSM Keys, Certs & Secrets"]
SB["๐จ <b>Azure Service Bus Premium</b><br/>FIFO Sessions & Dead-Letter Queues"]
EH["๐ <b>Azure Event Hubs</b><br/>Kafka-Compatible Telemetry Stream"]
Cosmos[("๐ช <b>Azure Cosmos DB</b><br/>Multi-Region Active-Active<br/>5 Consistency Levels")]
PgFlex[("๐ <b>Azure PostgreSQL Flexible</b><br/>Zone-Redundant HA + PgBouncer")]
Storage["๐พ <b>Azure Disk ZRS & Azure Files NFSv4.1</b><br/>RWO & RWX Persistent Volumes"]
end
CSI -.->|"OIDC Federated Token"| KV
SB -.->|"Queue Depth Metric"| KEDA
UserPool -->|"Private Link"| Cosmos
UserPool -->|"Private Link"| PgFlex
UserPool -->|"Private Link"| EH
UserPool --> Storage
๐ฌ Deep-Dive 1: AKS Internals, CNI Networking Models & Node Architecture
1. The 4 AKS Networking Models (Major Staff Interview Topic)
Choosing the wrong CNI plugin during AKS cluster creation requires a full cluster rebuild or complex node pool migration:
| AKS Networking Mode | Pod IP Allocation | Routing Mechanism | Max Scale & Enterprise Verdict |
|---|---|---|---|
| 1. Kubenet (Legacy / Deprecated) | Private bridge CIDR (10.244.0.0/16) |
Uses Azure User-Defined Routes (UDRs) per node. | โ Avoid: Azure Route Tables support a hard limit of 400 routes, capping cluster size at 400 nodes! |
| 2. Azure CNI Traditional | Every pod gets a real VNet Subnet IP (10.10.x.x). |
Direct VNet routing via Azure SDN (Azure-Vnet CNI). |
โ ๏ธ IP Exhaustion Risk: Pre-allocates maxPods (e.g. 30โ250) IPs per node immediately upon boot, rapidly exhausting RFC1918 VNet space. |
| 3. Azure CNI with Dynamic IP / Pod Subnets | Pods get real VNet IPs from a separate dedicated Pod Subnet. | Azure SDN routes between Node Subnet and Pod Subnet. | โ
Good: Separates node and pod CIDRs, dynamically allocating IPs on demand instead of pre-reserving maxPods per node. |
| 4. Azure CNI Overlay Powered by Cilium (Enterprise Standard) | Pods get IPs from an isolated private overlay CIDR (100.64.0.0/16 โ reusable across 100 clusters!). |
In-kernel Cilium eBPF encapsulates node-to-node pod traffic over the VNet without UDRs! | ๐ Staff Recommendation: Supports 5,000+ nodes and 250,000+ pods, saves 95% of VNet IP addresses, and enforces L7/FQDN CiliumNetworkPolicy in eBPF! |
2. System vs. User Node Pools & Ephemeral OS Disks
- System Node Pools (
mode: System): Must run at least 3 nodes across Availability Zones (1, 2, 3) tainted withCriticalAddonsOnly=true:NoSchedule. This guarantees application pods can never starvecoredns,metrics-server, orkonnectivity-agent(the secure tunnel between the Azure-managed API server and worker nodes). - Ephemeral OS Disks (
os_disk_type = "Ephemeral"):- The Problem: By default, Azure attaches a network-backed Managed Disk (
StandardSSD_LRSorPremium_LRS) for the Linux OS. During a deployment spike, pulling 10 GB container images and writingcontainerdlogs saturates the OS diskโs IOPS burst bucket, causing the node to freeze withPLEG is not healthy(NodeNotReady)! - The Architectural Fix: Always use Ephemeral OS Disks, which place the root filesystem directly on the VM hostโs local NVMe/Temp SSD cache. Read/write latency drops from
5msto< 0.2ms, node boot/scaling times drop by 50%, and OS disk storage is 100% free.
- The Problem: By default, Azure attaches a network-backed Managed Disk (
3. AKS Node Autoprovisioning (NAP โ Managed Karpenter)
AKS offers Node Autoprovisioning (NAP), which runs a Microsoft-managed Karpenter controller inside the AKS control plane:
- Evaluates unschedulable pods (
Pending) and provisions the exact optimal Azure VM SKU (e.g.,Standard_D8ds_v5,Standard_D16ps_v5ARM64 Cobalt/Ampere) in seconds without pre-creating tens of static VM Scale Set (VMSS) node pools.
๐ Deep-Dive 2: AKS Entra Workload Identity & Azure Key Vault CSI
[!WARNING] Deprecation Trap: Never propose
aad-pod-identity(v1) in an interview! It was deprecated because it used aniptablesrule on every node to intercept calls to169.254.169.254(IMDS), which added latency, failed under high concurrency, and allowed pod-level race conditions.
How Modern Entra Workload Identity Works (OIDC Federation):
- AKS OIDC Issuer: AKS exposes a public OpenID Connect discovery endpoint hosting its JSON Web Key Set (JWKS).
- Mutating Webhook Projection: When a pod has the label
azure.workload.identity/use: "true", the Workload Identity mutating webhook injects:- Environment variables:
AZURE_CLIENT_ID,AZURE_TENANT_ID,AZURE_FEDERATED_TOKEN_FILE=/var/run/secrets/azure/tokens/azure-identity-token. - A projected volume containing a short-lived, cryptographically signed Kubernetes ServiceAccount JWT.
- Environment variables:
- Federated Credential Exchange: The pod (or the Azure Key Vault Secret Store CSI Driver) sends that JWT to Microsoft Entra ID, which verifies the signature against the AKS OIDC Issuer URL (
subject: system:serviceaccount:<namespace>:<sa-name>) and returns an Entra ID Access Tokenโzero client secrets ever exist!
๐๏ธ Deep-Dive 3: Azure Dependent Enterprise Services Architecture
In Indian enterprise & GCC interviews, System Design rounds always test how AKS interacts with its surrounding Azure PaaS services:
1. Ingress Tier: Azure Front Door + Application Gateway for Containers
- Legacy Pattern (
AGICโ Application Gateway Ingress Controller): Used a single shared Application Gateway v2 instance updated via slow ARM control-plane calls (PUTrequests taking 30โ90 seconds whenever pods scaled up or down!). - Modern Enterprise Standard (
Application Gateway for Containers/ ALB for AKS):- Built specifically for Kubernetes Gateway API (
Gateway,HTTPRoute). - Uses a dedicated fast data-plane proxy API that registers new pod IPs in under 1 second (instead of 60-second ARM updates) and supports native mTLS, header rewriting, and canary traffic splitting.
- Fronted globally by Azure Front Door Premium, which connects into the internal load balancer via Azure Private Link so zero public IPs exist on the AKS cluster!
- Built specifically for Kubernetes Gateway API (
2. Database Tier: Azure Cosmos DB (The 5 Consistency Levels & Hot Partition Trap)
Almost every Azure Architect interview includes a deep drill on Azure Cosmos DB:
flowchart LR
C1["<b>1. Strong</b><br/>Linearizable Quorum<br/>RPO = 0, Highest Latency<br/>(Single-region or sync multi-AZ)"] --> C2["<b>2. Bounded Staleness</b><br/>Lags by at most K versions<br/>or T seconds (e.g. 5s)"]
C2 --> C3["<b>3. Session (Default)</b><br/>Read-your-own-writes<br/>Monotonic reads per client"]
C3 --> C4["<b>4. Consistent Prefix</b><br/>Updates appear in order<br/>(No out-of-order reads)"]
C4 --> C5["<b>5. Eventual</b><br/>Lowest RU/s cost & latency<br/>No ordering guarantee"]
- The 5 Consistency Levels:
- Strong: Linearizable reads guaranteed to return the most recent committed write globally; doubles read
RUcost compared to Eventual/Session and suffers speed-of-light cross-region write latency. - Bounded Staleness: Reads may lag behind writes by at most
Kprefixes (e.g., 100 updates) orTtime interval (e.g., 5 seconds). Ideal for multi-region DR whereStronglatency is too high. - Session (Default โ 90% of Microservices): Guarantees Read-Your-Own-Writes and monotonic reads within a single client session token (
x-ms-session-token) at half theRUcost of Strong! - Consistent Prefix: Guarantees readers never see out-of-order writes (if writes are
A, B, C, a reader seesA,A,B, orA,B,C, neverA,C). - Eventual: Lowest latency and cost, used for non-critical telemetry, view counters, or product reviews.
- Strong: Linearizable reads guaranteed to return the most recent committed write globally; doubles read
- The Infamous Cosmos DB Physical Partition & Hot Key Trap:
- Every Cosmos DB Physical Partition has a hard ceiling of 50 GB storage and 10,000 RU/s throughput, while every Logical Partition Key has a hard ceiling of 20 GB.
- The Trap: You provision a Cosmos DB collection with 100,000 RU/s, which Azure splits across 10 Physical Partitions (
100,000 / 10 = 10,000 RU/sper physical partition maximum!). If a developer picks a poor partition key (e.g.,/tenantIdwhere one giant enterprise tenant generates 80% of traffic, or/datewhere 100% of todayโs writes hit2026-10-20), all writes hit Partition #1, triggeringHTTP 429 RequestRateTooLargeat just 10,001 RU/sโeven though 90,000 RU/s across the other 9 partitions sit completely idle! - The Fix: Use Hierarchical Partition Keys (Subpartitioning up to 3 levels:
[/tenantId, /userId, /sessionId]) or Synthetic Suffixes so load spreads evenly across all physical partitions.
3. Messaging Tier: Azure Service Bus vs. Event Hubs vs. Event Grid
Interviewers love testing which Azure messaging service to pick in System Design:
| Service | Underlying Paradigm | Enterprise Features | When to Use It |
|---|---|---|---|
| Azure Service Bus (Premium) | Transactional Enterprise Message Broker (Pull Queue / Topic Subscriptions) | FIFO Message Sessions, Dead-Letter Queues (DLQ), Duplicate Detection, Distributed Transactions, Scheduled Delivery. |
Financial payments, order processing, saga workflows where losing or duplicating 1 message is unacceptable. |
| Azure Event Hubs | High-Throughput Partitioned Event Streaming (Apache Kafka Protocol Compatible) | Millions of events/sec, consumer groups, offset replay, Event Hubs Capture to ADLS Gen2 Parquet. | Clickstream telemetry, IoT ingestion, log pipelines (drop-in managed replacement for Apache Kafka!). |
| Azure Event Grid | Serverless Reactive Pub/Sub Router (HTTP Push / Event-Driven) | Sub-second push delivery based on cloud resource state changes (BlobCreated, KeyVaultSecretNearExpiry). |
Serverless automation & event routing (e.g., triggering an Azure Function when an image lands in Blob Storage). |
4. Storage Tier: Azure Disk (ZRS) vs. Azure Files (NFSv4.1) vs. Azure Blob
- Azure Disk CSI (
managed-csi-premium/UltraSSD_LRS): Block storage (ReadWriteOnce). Always usePremium_ZRS(Zone-Redundant Storage) for stateful pods in production so if AZ-1 goes down, Kubernetes can immediately reschedule the pod in AZ-2 and attach the exact same disk without waiting for cross-zone snapshots! - Azure Files CSI (
azurefile-csi-nfs): Shared file system (ReadWriteMany- RWX) over NFS v4.1 on Premium File Shares, connected via Private Endpoint. - Azure Blob CSI (
azureblob-fuse): Object storage mounted viaBlobFuse2or NFS v3โideal for reading massive 100 GB LLM model weights across 50 GPU pods simultaneously.
๐ป Production Manifests: AKS Workload Identity, Key Vault CSI & KEDA Service Bus Autoscaling
# 1. ServiceAccount annotated for Entra Workload Identity (OIDC Federation)
apiVersion: v1
kind: ServiceAccount
metadata:
name: payments-workload-sa
namespace: payments-prod
annotations:
azure.workload.identity/client-id: "11112222-3333-4444-5555-666677778888" # User-Assigned Managed Identity Client ID
azure.workload.identity/tenant-id: "99998888-7777-6666-5555-444433332222"
---
# 2. SecretProviderClass mounting Azure Key Vault secrets via CSI Driver
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: azure-kv-payments-secrets
namespace: payments-prod
spec:
provider: azure
parameters:
usePodIdentity: "false"
clientID: "11112222-3333-4444-5555-666677778888" # Uses Entra Workload Identity OIDC token!
keyvaultName: "kv-payments-prod-ind"
tenantId: "99998888-7777-6666-5555-444433332222"
objects: |
array:
- |
objectName: cosmos-db-primary-connection
objectType: secret
---
# 3. KEDA TriggerAuthentication + ScaledObject scaling pods on Azure Service Bus Queue Depth
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: azure-servicebus-auth
namespace: payments-prod
spec:
podIdentity:
provider: azure-workload
identityId: "11112222-3333-4444-5555-666677778888"
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: payment-settlement-worker-scaler
namespace: payments-prod
spec:
scaleTargetRef:
name: payment-settlement-worker
minReplicaCount: 2
maxReplicaCount: 150
triggers:
- type: azure-servicebus
metadata:
queueName: settlement-orders-queue
namespace: sb-payments-prod-ind
messageCount: "25" # Spawn 1 new pod for every 25 queued messages
authenticationRef:
name: azure-servicebus-auth
๐งญ Step-by-Step Operational Playbook: Deploying Private AKS with Cilium Overlay & Workload Identity
Follow this step-by-step operational sequence to provision an enterprise-grade AKS cluster integrated with Azure Key Vault and Managed Prometheus:
Step 1: Provision Private AKS with Cilium CNI Overlay & Ephemeral OS Disks
- Plain-English Goal: Create a private AKS cluster using
network-plugin-mode overlaywithebpf-dataplane cilium, OIDC Issuer enabled, and Ephemeral NVMe OS disks. - Action:
az aks create \ --resource-group rg-payments-prod \ --name aks-payments-prod \ --enable-private-cluster \ --network-plugin azure \ --network-plugin-mode overlay \ --ebpf-dataplane cilium \ --pod-cidr 100.64.0.0/16 \ --node-osdisk-type Ephemeral \ --enable-oidc-issuer \ --enable-workload-identity \ --enable-addons azure-keyvault-secrets-provider \ --zones 1 2 3
Step 2: Establish the Entra ID Federated Identity Credential
- Plain-English Goal: Link your Azure User-Assigned Managed Identity to the Kubernetes ServiceAccount (
system:serviceaccount:payments-prod:payments-workload-sa) using the AKS OIDC Issuer URL. - Action:
AKS_OIDC_ISSUER=$(az aks show -g rg-payments-prod -n aks-payments-prod --query "oidcIssuerProfile.issuerUrl" -o tsv) az identity federated-credential create \ --name "fed-payments-workload-sa" \ --identity-name "id-payments-prod" \ --resource-group rg-payments-prod \ --issuer "$AKS_OIDC_ISSUER" \ --subject "system:serviceaccount:payments-prod:payments-workload-sa" \ --audience "api://AzureADTokenExchange"
Step 3: Verify Pod Token Projection & Key Vault CSI Mount
- Plain-English Goal: Confirm the pod received its federated OIDC token file and successfully mounted secrets from Azure Key Vault without any static credentials.
- Action:
kubectl describe pod -n payments-prod -l app=payment-settlement-worker | grep -A 6 "AZURE_FEDERATED_TOKEN_FILE" kubectl exec -n payments-prod deploy/payment-settlement-worker -- ls -la /mnt/secrets-store
Step 4: Triage Live Logs with Kusto Query Language (KQL) in Azure Monitor
- Plain-English Goal: Query container logs and Cosmos DB throttling events across the subscription using KQL.
- Action:
// KQL Query: Find Cosmos DB HTTP 429 Throttled Partitions in the last 1 hour AzureDiagnostics | where ResourceProvider == "MICROSOFT.DOCUMENTDB" and Category == "DataPlaneRequests" | where statusCode_s == "429" | summarize ThrottledCount = count(), MaxRUs = max(todouble(requestCharge_s)) by partitionKeyRangeId_s, OperationName | order by ThrottledCount desc
๐ ๏ธ Real-World Troubleshooting & Failure Modes
Scenario 1: AKS Workload Identity Fails with AADSTS70021: No matching federated identity record found
- Symptom: Pods crash at startup when attempting to read secrets from Azure Key Vault or authenticate to Azure Service Bus, logging:
AADSTS70021: No matching federated identity record found for presented assertion. - Under-the-Hood Root Cause: Entra ID strictly validates three fields inside the Kubernetes JWT against the
az identity federated-credential:iss(Issuer URL โ often has a trailing/mismatch if copied manually!).sub(Subject โ must exactly matchsystem:serviceaccount:<namespace>:<serviceaccount-name>โcase-sensitive!).aud(Audience โ must beapi://AzureADTokenExchange). Additionally, if the Pod itself is missing the labelazure.workload.identity/use: "true"onspec.template.metadata.labels, the webhook never injects the token file in the first place!
- Immediate Triage & Fix:
# 1. Inspect the exact issuer and subject configured on the Managed Identity: az identity federated-credential list -g rg-payments-prod --identity-name id-payments-prod -o yaml # 2. Verify the Pod has the webhook label: kubectl get pod <pod-name> -n payments-prod --show-labels | grep "azure.workload.identity/use=true"
Scenario 2: Stateful Pod Stuck in ContainerCreating After AZ Failure (AzureDisk Multi-Zone Attach Failure)
- Symptom: Availability Zone 1 experiences an impairment. A StatefulSet pod running in
centralindia-1is rescheduled to a healthy node incentralindia-2, but hangs indefinitely inContainerCreatingwith:AttachVolume.Attach failed for volume "pvc-123": disk is in zone centralindia-1 and cannot be attached to VM in zone centralindia-2. - Under-the-Hood Root Cause: The StorageClass was provisioned with
StandardSSD_LRSorPremium_LRS(Locally Redundant Storage), which pins the physical disk to a single Availability Zone! - Permanent Fix: Use a Zone-Redundant Storage (
Premium_ZRS) StorageClass (skuName: Premium_ZRS) for stateful workloads requiring cross-AZ failover, which synchronously replicates blocks across all 3 Availability Zones and can be attached to nodes in any zone immediately.
๐ Knowledge Check & Real-World Interview Scenarios
โ Question 1: Cosmos DB HTTP 429 at 15% Overall RU Utilization
Question: During a flash sale, your Azure Cosmos DB monitoring dashboard shows overall database throughput utilization is only 15% (15,000 RU/s out of 100,000 provisioned RU/s), yet checkout pods are failing with thousands of HTTP 429 (RequestRateTooLarge) errors. How is this possible, and how do you prove and fix it?
Answer:
- The Root Cause (Hot Physical Partition): Cosmos DB distributes provisioned RU/s equally across all underlying Physical Partitions. If the collection has 10 physical partitions, each physical partition receives strictly
100,000 / 10 = 10,000 RU/s. It cannot borrow unused RU/s from idle sibling partitions! - The Trigger: A skewed partition key (such as partitioning by
merchantIdwhen one mega-merchant drives the flash sale, or partitioning byorderDate) routes 15,000 RU/s of requests to Physical Partition #3, exceeding its 10,000 RU/s cap and triggeringHTTP 429while the other 9 partitions sit at 0% utilization. - How to Prove It: Run a KQL query on
AzureDiagnostics(Category == "DataPlaneRequests") grouped bypartitionKeyRangeId_s, or inspect Normalized RU Consumption (%) per Partition Key Range in Azure Monitorโone partition will show 100% while others show 0%. - Permanent Architectural Fix: Redesign the partition key using Hierarchical Partition Keys (e.g.,
[/merchantId, /customerId, /orderId]) to break the 20 GB / 10,000 RU/s logical partition bottleneck, or append a deterministic hash suffix (merchantId_1..10) for write-heavy keys.
โ Question 2: Designing Zero-Trust Multi-Region Active-Active on Azure
Question: How do you architect an active-active multi-region financial platform on Azure across Central India (Pune) and South India (Chennai) with < 30 second RTO and zero public IP exposure on backend clusters?
Answer:
- Global Edge & Traffic Manager: Deploy Azure Front Door Premium at the global edge with WAF and DDoS Protection. Configure Origin Groups with health probes pointing to both
Central IndiaandSouth Indiavia Azure Private Link Origins (requiring zero public IPs on the regional VNets). - Regional Compute & Ingress: Run private AKS clusters (Azure CNI Overlay with Cilium + Ephemeral NVMe OS Disks) in both regions behind Application Gateway for Containers.
- Active-Active Data Tier: Use Azure Cosmos DB with Multi-Region Writes enabled and Session or Bounded Staleness consistency, or Azure SQL / PostgreSQL Flexible Server with Geo-Replication and Failover Groups.
- Secrets & Identity: Synchronize secrets across regions in Azure Key Vault (Geo-replicated HSM) accessed via Entra Workload Identity OIDC tokens.