Skip to content
AI-200 Learn

Configure health probes and rolling updates

Manage AKS apps with manifests for AI-200: liveness, readiness and startup probes, rolling update settings, rollout undo, scaling and HPA.

What this covers

Deploying is only half of "deploy and manage". After the first release you need Kubernetes to know when a Pod is actually healthy, to roll out new image versions without downtime, to roll back a bad release, and to scale. All of that is configured in the Deployment manifest. The module's exercise has you add health probes to an inference API, and the troubleshooting exercise has you fix a broken readiness probe path, so probe semantics are fair game on the exam.

Exam weight: Develop containerized solutions on Azure (20–25%)

Skills measured

  • "Deploy and manage applications to Azure Kubernetes Service (AKS) by using manifest files"
  • "Monitor and troubleshoot solutions on AKS and Container Apps by inspecting logs, events, and end-to-end connectivity"

Key concepts

Three probe types

ProbeQuestion it answersOn failure
livenessProbeIs the process stuck or dead?kubelet restarts the container
readinessProbeCan it take traffic right now?Pod is removed from Service endpoints; not restarted
startupProbeHas slow start-up finished?Liveness/readiness are held off until it succeeds; if it never does, the container is restarted

AI inference containers often load a large model at start-up. Without a startup probe (or a generous delay), the liveness probe can kill the container before the model finishes loading, creating a CrashLoopBackOff that has nothing to do with the code.

Probe mechanisms and defaults

A probe can be httpGet (2xx or 3xx is success), tcpSocket, exec (exit code 0), or grpc. The defaults are initialDelaySeconds: 0, periodSeconds: 10, timeoutSeconds: 1, successThreshold: 1 and failureThreshold: 3. A startup probe's time budget is failureThreshold × periodSeconds.

Rolling update strategy

The default Deployment strategy is RollingUpdate with maxSurge: 25% and maxUnavailable: 25%. Kubernetes creates a new ReplicaSet and swaps Pods gradually, waiting for new Pods to be Ready before removing old ones. That's why a readiness probe matters: without one, a Pod counts as ready the moment its container starts. Set maxUnavailable: 0 for zero-capacity-loss rollouts. The alternative Recreate strategy kills all old Pods first (downtime, but no mixed versions). revisionHistoryLimit (default 10) controls how many old ReplicaSets are kept for rollback, and progressDeadlineSeconds (default 600) marks a stuck rollout as failed.

Scaling

Manual: kubectl scale or change replicas and re-apply. Automatic: a HorizontalPodAutoscaler (autoscaling/v2) adjusts replicas from CPU or memory utilization, computed against the container's requests, so requests must be set. Node capacity is handled separately by the cluster autoscaler (az aks update --enable-cluster-autoscaler --min-count --max-count).

How it works

Diagram source: flowchart LR A[New image tag applied] --> B[New ReplicaSet] B --> C[New Pod starts] C --> D{startupProbe ok?} D -->|yes| E{readinessProbe ok?} E -->|yes| F[Added to endpoints] F --> G[Old Pod terminated] E -->|no| H[Rollout waits / stalls]
YAML
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ai-inference-api
spec:
  replicas: 3
  revisionHistoryLimit: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: inference-api
  template:
    metadata:
      labels:
        app: inference-api
    spec:
      containers:
      - name: api
        image: myregistry.azurecr.io/inference-api:v1.1
        ports:
        - name: http
          containerPort: 8080
        startupProbe:
          httpGet: { path: /health, port: http }
          periodSeconds: 10
          failureThreshold: 30        # up to 300 s to load the model
        livenessProbe:
          httpGet: { path: /health, port: http }
          periodSeconds: 10
          failureThreshold: 3
        readinessProbe:
          httpGet: { path: /ready, port: http }
          periodSeconds: 5
        resources:
          requests: { cpu: "1000m", memory: "2Gi" }
          limits: { cpu: "2000m", memory: "4Gi" }
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: ai-inference-api
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: ai-inference-api
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target: { type: Utilization, averageUtilization: 70 }

Hands-on

Azure portal

  1. Open the cluster > Kubernetes resources > Workloads > Deployments and select the Deployment.
  2. Select YAML, edit the image tag or probe settings, and select Review + save.
  3. Watch the Pods list as new Pods appear and old ones terminate.
  4. Check the Deployment Events for Readiness probe failed messages if the rollout stalls.

Azure CLI

Azure CLI / Bash
kubectl apply -f deployment.yaml

# Roll out a new image and watch it
kubectl set image deployment/ai-inference-api api=myregistry.azurecr.io/inference-api:v1.2
kubectl rollout status deployment/ai-inference-api --timeout=5m

# Inspect and roll back
kubectl rollout history deployment/ai-inference-api
kubectl rollout undo deployment/ai-inference-api
kubectl rollout undo deployment/ai-inference-api --to-revision=2

# Restart Pods (e.g. to pick up a changed Secret) without changing the spec
kubectl rollout restart deployment/ai-inference-api

# Scale
kubectl scale deployment/ai-inference-api --replicas=5
kubectl autoscale deployment ai-inference-api --cpu-percent=70 --min=3 --max=10
kubectl get hpa

# Node-level autoscaling
az aks update --resource-group <resource-group> --name <aks-name> \
  --enable-cluster-autoscaler --min-count 2 --max-count 5

Python

Python
# pip install kubernetes
from kubernetes import client, config

config.load_kube_config()
apps = client.AppsV1Api()

# Equivalent of `kubectl set image`
patch = {"spec": {"template": {"spec": {"containers": [
    {"name": "api", "image": "myregistry.azurecr.io/inference-api:v1.2"}]}}}}
apps.patch_namespaced_deployment("ai-inference-api", "default", patch)

# Equivalent of `kubectl scale`
apps.patch_namespaced_deployment_scale(
    "ai-inference-api", "default", {"spec": {"replicas": 5}})

Exam traps

NeedUse
Restart a hung process automaticallylivenessProbe
Keep traffic away while warming up or overloadedreadinessProbe
Model takes minutes to loadstartupProbe with a high failureThreshold
No capacity loss during rolloutmaxUnavailable: 0, maxSurge: 1
Never run two versions at oncestrategy.type: Recreate
Revert a bad releasekubectl rollout undo
Scale Pods on CPUHPA (kubectl autoscale) with requests set

Quick review

  • Probe defaults: period 10 s, timeout 1 s, failureThreshold 3.
  • Readiness failure removes the Pod from endpoints; liveness failure restarts it.
  • Startup probe protects slow-loading model containers from liveness kills.
  • Default strategy: RollingUpdate, maxSurge 25%, maxUnavailable 25%.
  • kubectl rollout undo --to-revision=N rolls back; history depth = revisionHistoryLimit (10).
  • HPA utilization is measured against requests.
  • Cluster autoscaler adds nodes; HPA adds Pods.

Practice

Practice: AKS manifest questions · Practice: container troubleshooting questions

Official references