Skip to main content
RunBook Academy

KubernetesCIX · LimitRangeLimitRange

Pod-level limits — bounding the sum across containers

Advanced⏱ ~16 minkubectl

What you'll learn

  • Configure Pod-level limits (max, min)
  • Reason about multi-container Pods and sidecars
  • Apply the interaction with container-level limits
  • Apply the operational discipline of bounding multi-container Pods

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

Pod-level limits in LimitRange bound the sum across all containers in a Pod. This lesson walks the Pod limits, the use cases (multi-container Pods, sidecars), the interaction with container limits, and the discipline.

The Pod-level limits

apiVersion: v1
kind: LimitRange
metadata:
  name: pod-limits
  namespace: tenant-a-prod
spec:
  limits:
    - type: Pod
      max:
        cpu: 4
        memory: 8Gi
      min:
        cpu: 100m
        memory: 128Mi

The Pod-level fields:

  • max. Maximum sum across all containers in a Pod. A Pod with containers requesting 2 cores each would exceed a max of 4.
  • min. Minimum sum across all containers. A Pod with one container requesting 10m CPU would be rejected if min is 100m.

Multi-container Pods

flowchart LR
    A[Pod] --> B["App container: 2 cores"]
    A --> C["Sidecar: 200m"]
    A --> D["Logging agent: 100m"]
    B --> E["Total: 2.3 cores"]
    C --> E
    D --> E
    E --> F{Pod max: 4 cores}
    F -->|2.3 < 4| G[Accepted]

Multi-container Pods have:

  • A main container (the application).
  • Sidecars (logging, monitoring, service mesh proxies).
  • Init containers (run before the main container).

Each container has its own resources. The sum must fit within the Pod max.

Sidecar pattern

apiVersion: v1
kind: Pod
metadata:
  name: myapp-with-sidecar
spec:
  containers:
    - name: app
      image: myapp
      resources:
        requests:
          cpu: 2
          memory: 4Gi
    - name: log-shipper
      image: fluentbit
      resources:
        requests:
          cpu: 200m
          memory: 256Mi

The Pod has two containers. Without Pod-level limits, the sum is unbounded. With Pod max of 4 cores and 8Gi, the Pod is accepted.

Init containers

apiVersion: v1
kind: Pod
metadata:
  name: myapp-with-init
spec:
  initContainers:
    - name: init-data
      image: init-data
      resources:
        requests:
          cpu: 1
          memory: 2Gi
  containers:
    - name: app
      image: myapp
      resources:
        requests:
          cpu: 2
          memory: 4Gi

Init containers run before the main container. Their resources count toward the Pod max during their lifetime (but not after they complete).

The Pod max must accommodate the init container’s resources plus the main container’s.

Interaction with container limits

flowchart LR
    A["Container max: 2 cores"] --> B["Each container: ≤ 2 cores"]
    C["Pod max: 4 cores"] --> D["Sum of containers: ≤ 4 cores"]
    B --> E["Effective: ≤ 2 containers per Pod"]
    D --> E

The interaction:

  • Container max. Each container is bounded individually.
  • Pod max. The sum is bounded.
  • Effective constraint. The smaller of the two determines the actual limit.

A namespace with container max=2 and Pod max=4 allows 2 containers per Pod (each at 2 cores).

Quiz

Knowledge check · 4 questions

  1. Q1. What does a Pod-scoped LimitRange `max` bound?

  2. Q2. A container-level maximum is sufficient to bound the total resources of a multi-container Pod.

  3. Q3. Enabling sidecar injection makes every Pod in a namespace fail admission; reconcile the Pod-level bound with the injected container.

    A mesh migration labels `catalogue-prod` with `istio-injection=enabled`. Every subsequent rollout is rejected with `maximum cpu usage per Pod is 4, but limit is 4500m`. The application container declares `limits.cpu: 4`; the injected proxy declares `limits.cpu: 500m`. The namespace LimitRange has a `Container` entry with `max cpu 2` and a `Pod` entry with `max cpu 4`.

  4. Q4. Why can a `Pod`-type LimitRange entry not carry `default` or `defaultRequest`, and what follows from that?

Passing score: 75%. Answers are checked in this browser.

The operational discipline

Pod-level limits in production rest on five non-negotiable elements:

  • Set Pod max deliberately. Account for sidecars.
  • Account for init containers. Their resources count during their lifetime.
  • Tune based on workload pattern. Sidecar-heavy workloads need higher Pod max.
  • Test multi-container Pods. Quarterly: create a Pod with sidecars; verify the Pod max.
  • Document the limits. The runbook lists container and Pod limits.

Pod-level limits are the guardrail for multi- container Pods. Without them, sidecars can unexpectedly push the Pod over the quota.