Copyright (c) 2026 MindMesh Academy. All rights reserved. This content is proprietary and may not be reproduced or distributed without permission.

3.2.3. Deploying to AKS with Manifest Files

💡 First Principle: Kubernetes is a declarative reconciliation engine: manifests state the world you want ("three replicas of this image, reachable on port 80"), the control plane relentlessly edits reality to match. You never command "start a container" — you update the desired state and let reconciliation act. Every kubectl workflow and every self-healing behavior follows from this loop.

Azure Kubernetes Service (AKS) manages the control plane; you manage what runs on it, chiefly through manifests applied with kubectl apply -f. The exam expects fluency in the core objects and the shape of a working Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: rag-api
spec:
  replicas: 3
  selector:
    matchLabels: { app: rag-api }
  template:
    metadata:
      labels: { app: rag-api }
    spec:
      containers:
      - name: rag-api
        image: myreg.azurecr.io/rag-api:1.4.2
        ports: [{ containerPort: 8000 }]
        env:
        - name: COSMOS_DB
          valueFrom: { configMapKeyRef: { name: rag-config, key: cosmosDb } }
        readinessProbe:
          httpGet: { path: /healthz, port: 8000 }

The object cast: a Deployment manages ReplicaSets and rolling updates for stateless workloads; a Service gives pods a stable virtual IP and DNS name (ClusterIP internal, LoadBalancer external); ConfigMaps and Secrets externalize configuration — the same runtime-config doctrine as 3.1.3, in Kubernetes dialect; namespaces partition the cluster; readiness/liveness probes tell the reconciler what "healthy" means, gating traffic and triggering restarts. AKS pulls from ACR via managed identity (attach with az aks update --attach-acr) — AcrPull again, no image-pull secrets needed.

The declarative loop is also the deployment strategy: change the manifest's image tag, kubectl apply, and the Deployment rolls pods gradually, honoring readiness probes — a hand-rolled version of what ACA revisions gave you as a service. That symmetry is the selection question: same outcome, different abstraction level, chosen by who's willing to operate the machinery.

⚠️ Exam Trap: Selector/label mismatch — spec.selector.matchLabels disagreeing with template.metadata.labels (or the Service's selector matching neither) — yields deployments that are "running" while the Service has zero endpoints. When "pods are healthy but the service returns no responses," check label wiring before anything network-shaped.

Day-two mechanics the exam touches: kubectl apply -f ./manifests/ applies a whole directory, which is how estates version manifests in git and apply them atomically per release. kubectl rollout status deployment/rag-api watches a rollout converge, and kubectl rollout undo steps back one revision of the Deployment's history — the AKS analogue of shifting traffic back to a known-good ACA revision. Resource requests (what the scheduler reserves) versus limits (the ceiling enforced at runtime, whose breach produces OOMKilled) is a distinction worth keeping crisp, and namespaces pair with ResourceQuota objects when teams share a cluster.

One more field worth pinning: imagePullPolicy decides whether nodes re-fetch images (Always) or trust their cache (IfNotPresent) — with unique tags, cached pulls are safe and fast, which is another quiet argument against :latest.

Reflection Question: You delete a pod manually and an identical one appears seconds later. Which object noticed, and why is that the same mechanism that performs rolling updates?

Alvin Varughese
Written byAlvin Varughese
Founder18 professional certifications