Skip to main content
emnode
Compliance Medium severity MCSB PV-2

Microsoft Defender for Cloud · Azure Kubernetes Service

Container CPU and memory limits should be enforced

Written and reviewed by Emnode · Last reviewed

What does the recommendation "Container CPU and memory limits should be enforced" check?

Flags AKS clusters running containers that do not declare both a CPU limit and a memory limit in their pod spec, meaning 'resources.limits.cpu' and 'resources.limits.memory' are set on every container. Evaluation depends on the Azure Policy add-on (Gatekeeper) being installed: it inspects live and admitted pods through the constraint, not the cluster's RBAC, image provenance or network policy. It does not check 'requests' values, namespace ResourceQuotas, LimitRange defaults, or whether the limits you set are sensibly sized. A pod that sets a huge limit still passes, because the control only confirms a limit exists, not that it is right.

Why does "Container CPU and memory limits should be enforced" matter?

A container with no memory limit can consume every spare byte on its node. When the kernel's OOM killer steps in it evicts neighbouring pods, so one leaking workload takes down unrelated services sharing that node and the failure spreads as the scheduler reschedules onto the next victim. An unbounded CPU consumer starves the same neighbours of cycles. This is the classic noisy-neighbour and resource-exhaustion failure mode, and on a shared production cluster it turns a single buggy or hostile deployment into a multi-tenant outage. Enforcing limits caps the blast radius and makes capacity planning and cost attribution honest.

How do I fix "Container CPU and memory limits should be enforced"?

  1. Install the Azure Policy add-on so Gatekeeper can evaluate and enforce the constraint: 'az aks enable-addons --addons azure-policy --resource-group <rg> --name <cluster>'. Without the add-on the recommendation cannot assess the cluster.
  2. Set explicit limits on every container, for example 'resources.limits.cpu: 410m' and 'resources.limits.memory: 512Mi' in the pod spec, then re-evaluate. You can confirm current state with 'kubectl describe k8sazurecontainerlimits' and trigger an on-demand compliance scan rather than waiting for the next cycle.
  3. Assign the built-in policy 'Kubernetes cluster containers CPU and memory resource limits should not exceed the specified limits' in Deny mode so unbounded pods are rejected at admission. Look the definition up by name rather than pasting a GUID: pid=$(az policy definition list --query "[?displayName=='Kubernetes cluster containers CPU and memory resource limits should not exceed the specified limits'].name" -o tsv); az policy assignment create --name aks-container-limits --policy "$pid" --scope <cluster-scope>.

Remediation script · bash

# 1. Turn on the Azure Policy add-on so Gatekeeper starts auditing the cluster.
az provider register --namespace Microsoft.PolicyInsights
az aks enable-addons --addons azure-policy \
  --resource-group rg-prod --name aks-prod
# Confirm the policy and gatekeeper pods are running.
kubectl get pods -n kube-system -l app=azure-policy
kubectl get pods -n gatekeeper-system

# 2. Assign the built-in pod security baseline initiative in AUDIT first.
# Look the initiative up by its exact display name, never paste a GUID.
SCOPE=$(az aks show -g rg-prod -n aks-prod --query id -o tsv)
SETID=$(az policy set-definition list \
  --query "[?displayName=='Kubernetes cluster pod security baseline standards for Linux-based workloads'].name" -o tsv)
az policy assignment create \
  --name aks-pod-baseline \
  --policy-set-definition "$SETID" \
  --scope "$SCOPE" \
  --params '{"effect":{"value":"audit"},"excludedNamespaces":{"value":["kube-system","gatekeeper-system","azure-arc"]}}'

# 3. Fix the workloads (in each pod spec, securityContext):
#   privileged: false | runAsNonRoot: true | runAsUser: 1000
#   allowPrivilegeEscalation: false | readOnlyRootFilesystem: true
#   capabilities: { drop: ["ALL"] }  and add back only what is needed.

# 4. Once audit is clean except for named exceptions, ENFORCE.
az policy assignment update --name aks-pod-baseline \
  --set parameters.effect.value=deny

Full walkthrough (console steps, edge cases and verification) in the lesson Enforce AKS pod security.

Is "Container CPU and memory limits should be enforced" a false positive?

A dedicated single-tenant cluster running one trusted batch job that is deliberately allowed to use the whole node, for example a nightly data-processing run sized to the machine, may legitimately omit limits so the kernel scheduler hands it everything spare. Exempt that namespace through the policy's excludedNamespaces parameter rather than leaving limits off cluster-wide, so the safe default still applies everywhere else.