Image Volumes
How do you hand a Pod a model or toolset without baking it into the app image? An image volume names an OCI image or artifact, and before any container starts Kubelet asks the container runtime to resolve it by its pullPolicy, pulling it if needed with the same credentials as a container image. It is mounted read-only as one directory at the mountPath. A recreated Pod resolves it again, and IfNotPresent reuses the copy on the Node unless other credentials pulled it.
Play the animation 5 steps, animated, best on a wide screen
Image Volumes, step by step
-
Pod llm-server declares an image volume named model: reference llm:v1, pullPolicy IfNotPresent, mounted at /models. At Pod startup Kubelet asks the container runtime to resolve it, before any container starts. The app image app:v3 is already on this Node.
Play from step 1 -
The model image llm:v1 is not on disk, so IfNotPresent pulls it. It comes from the registry the same way a container image does, with the same pull credentials. The weights ship as their own image, not baked into app:v3.
Play from step 2 -
As Kubelet creates the app container, the runtime mounts the image as one directory at the mountPath, /models, always read-only. Which kinds of OCI object it can mount is up to the runtime, but at least every image a container can run.
Play from step 3 -
Only now does Kubelet start the app container, from its own image app:v3. Had resolving or pulling llm:v1 failed, the app container, which mounts it, would wait while Kubelet retries with backoff, and the Pod would report why in its status.
Play from step 4 -
The app reads the weights under /models but cannot write there. A recreated Pod resolves the volume again, but under IfNotPresent a Node holding llm:v1 skips the pull, unless it pulled that private image with other credentials. New weights take a new tag or digest, or pullPolicy Always, and app:v3 is never rebuilt for them.
Play from step 5