Image Pull Optimization Kubernetes
Optimize container image pulls with pre-pulling DaemonSets, registry mirrors, image caching, and pull-through proxies for faster pod startup.
π‘ Quick Answer: Use a pull-through registry mirror (Harbor, Zot) to cache images locally. Pre-pull large images (GPU/AI containers) with a DaemonSet. Set
imagePullPolicy: IfNotPresentand use immutable tags to avoid unnecessary pulls.
The Problem
Large container images (NVIDIA GPU: 15GB, ML frameworks: 8GB) take minutes to pull, causing slow pod startup, autoscaler lag, and cold-start latency spikes. In air-gapped environments, external registries are unreachable entirely.
The Solution
Pre-Pull DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: image-prepuller
namespace: kube-system
spec:
template:
spec:
initContainers:
- name: prepull-gpu-image
image: registry.example.com/nvidia/cuda:12.6-runtime
command: ["sh", "-c", "echo Image pulled successfully"]
- name: prepull-inference
image: registry.example.com/nim/nim-llm:2.0.2
command: ["sh", "-c", "echo Image pulled successfully"]
containers:
- name: pause
image: registry.k8s.io/pause:3.9
tolerations:
- operator: Exists
nodeSelector:
nvidia.com/gpu.present: "true"Pull-Through Registry Mirror
# containerd config (/etc/containerd/config.toml)
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://mirror.example.com"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."nvcr.io"]
endpoint = ["https://mirror.example.com"]Image Pull Policies
| Policy | Behavior | Use When |
|---|---|---|
IfNotPresent | Pull only if not cached | Immutable tags (:v1.2.3) |
Always | Check registry every time | :latest (avoid in production) |
Never | Only use cached images | Air-gapped, pre-pulled images |
graph LR
POD[Pod Start] -->|imagePullPolicy| CHECK{Image cached?}
CHECK -->|Yes, IfNotPresent| START[Container starts<br/>instantly]
CHECK -->|No| PULL[Pull from registry]
PULL -->|Mirror available| MIRROR[Local Mirror<br/>~10s for 15GB]
PULL -->|No mirror| REMOTE[Remote Registry<br/>~5min for 15GB]Common Issues
ImagePullBackOff on large images
Kubelet timeout. Increase --image-pull-progress-deadline (default 1m, set to 10m for large images). Or pre-pull with DaemonSet.
Registry mirror not being used
containerd config requires restart: systemctl restart containerd. Verify with crictl pull and check mirror logs.
Best Practices
- Pre-pull GPU/AI images with DaemonSet β 15GB images should be cached before needed
imagePullPolicy: IfNotPresentwith immutable tags β never use:latestin production- Pull-through mirror for frequently used images β reduces external bandwidth
- Multi-stage builds to minimize image size β smaller images = faster pulls
imagePullSecretsper namespace β donβt share registry credentials cluster-wide
Key Takeaways
- Large images (GPU, ML) need pre-pulling β cold pulls take 3-10 minutes
- Pull-through mirrors cache images locally β subsequent pulls are 10-100x faster
IfNotPresentwith immutable tags is the production standard- DaemonSet pre-puller ensures images are cached on all target nodes
- Air-gapped clusters use
Neverpolicy with images pre-loaded viactr import

Recommended
Kubernetes Recipes β The Complete Book100+ production-ready patterns with detailed explanations, best practices, and copy-paste YAML. Everything in one place.
Get the Book βLearn by Doing
CopyPasteLearn β Hands-on Cloud & DevOps CoursesMaster Kubernetes, Ansible, Terraform, and MLOps with interactive, copy-paste-run lessons. Start free.
Browse Courses βπ Deepen Your Skills β Hands-on Courses
Courses by CopyPasteLearn.com β Learn IT by Doing
