> ## Content Index
> Fetch the complete content index at: https://devopscube.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# How to Mount OCI Image as Volume in Kubernetes Pods
- URL: https://devopscube.com/oci-image-volume-kubernetes-pods/
- Published: 2026-07-12T08:28:00.000Z
- Updated: 2026-07-14T12:14:03.000Z
- Author: Aswin Vijayan
- Tags: #blog, Kubernetes, HOW TO GUIDES, #syntax-highlight

In this guide, you will learn how to mount OCI container images as volumes in Kubernetes Pods using the **`ImageVolume`** feature.

This feature is useful in ML projects that work with LLMs, as it allows you to package model data in OCI images and easily switch between different models.

## What is ImageVolume

The Image Volume feature allows you to use OCI images as volumes directly within [Kubernetes pods](https://devopscube.com/kubernetes-pod/).

In Kubernetes version 1.31, the [Image Volume feature](https://kubernetes.io/docs/tasks/configure-pod-container/image-volumes/?ref=devopscube.com) was introduced, and in Kubernetes version 1.36, the image volume feature was marked as a stable release and enabled by default.

The below image gives you a high level overview of how OCI images are mounted to pods using the image volume feature.

![Mounting oci image as volume in Kubernetes pods](https://storage.ghost.io/c/5f/2f/5f2f4d20-2abf-4534-8d40-7aa233aedd43/content/images/2026/07/image-98.png)

So what are OCI images?

OCI images follow the rules set by [Open Container Initiative](https://opencontainers.org/?ref=devopscube.com). For example, [Docker](https://devopscube.com/what-is-docker/), [Podman](https://devopscube.com/podman-tutorial-beginners/), and container runtimes like containerd and **CRI-O** use OCI image rules.

You can use the **`ImageVolume`** feature to store model files, binary files, configuration files, or other data in images which can be mounted to pods.

Also, a key thing about this feature is that it is a **read only Volume.**

![Mount OCI Image as Volume in Kubernetes Pods](https://storage.ghost.io/c/5f/2f/5f2f4d20-2abf-4534-8d40-7aa233aedd43/content/images/2025/09/image-52.png)

Now, lets get started with the practical example.

## How to Mount OCI Image as a Volume in Kubernetes Pods

In this section, we will build an OCI image and a sample predictor application, then deploy them in the Kubernetes cluster to test the **`ImageVolume`** feature.

Follow the below steps to mount an OCI image as a volume for a Kubernetes pod.

💡

If you just want to check this feature and you dont have an active cluster with v1.36, you can create a local cluster using [Kind](https://devopscube.com/kubernetes-kind-cluster-tutorial-setup-and-deploy-apps) or [Kubeadm](https://devopscube.com/setup-kubernetes-cluster-kubeadm/).

### Step 1: Build an OCI Image

The first step is to build an OCI image.

For this example, I am using a prediction model that I have locally. You can replace the model file with any file for testing.

Here is the Dockerfile.

```
FROM scratch
COPY model.pkl /models/model.pkl
```

You can see, unlike other Dockerfiles that build images on top of a base images, the OCI image is built using `FROM scratch`.

I have uploaded this image to Docker Hub as `devopscube/oci-image:1.0`.  
You can use it directly for testing.

### Step 2: Build a Sample Predictor Application

To test the `**ImageVolume**`, we will build a simple Python predictor application. This application loads the `model.pkl` file directly from the mounted image volume.

I have already built the app and published it as `devopscube/predictor:1.0`, which you can use for testing.

Here is the Python code that is part of the predictor image.

```python
import os
import joblib
import numpy as np
from fastapi import FastAPI
from pydantic import BaseModel

MODEL_PATH = os.environ.get("MODEL_PATH", "/models/model.pkl")
model = joblib.load(MODEL_PATH)

app = FastAPI()

class PredictIn(BaseModel):
    instances: list

@app.get("/healthz")
def healthz():
    return {"ok": True, "model_path": MODEL_PATH}

@app.post("/v1/models/model:predict")
def predict(p: PredictIn):
    X = p.instances
    try:
        X_arr = np.array(X, dtype=float)
        preds = model.predict(X_arr).tolist()
    except Exception:
        preds = model.predict(X).tolist()
    return {"predictions": preds}
```

### Step 3: Mount the ImageVolume With Deployment

Now, lets create a deployment with the predictor container image and the OCI volume image to test the image volume.

Here are the Deployment and Service manifests.

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: predictor
spec:
  replicas: 1
  selector:
    matchLabels:
      app: predictor
  template:
    metadata:
      labels:
        app: predictor
    spec:
      containers:
      - name: app
        image: devopscube/predictor:1.0                    
        ports:
        - containerPort: 8000
        env:
        - name: MODEL_PATH
          value: /volume/models/model.pkl
        volumeMounts:
        - name: model-vol
          mountPath: /volume
      volumes:
      - name: model-vol
        image:
          reference: devopscube/oci-image:1.0
          pullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
  name: predictor-svc
spec:
  selector:
    app: predictor
  ports:
  - port: 80
    targetPort: 8000
```

Deploy the above manifest and check if the pod is running without issues.

```bash
$ kubectl get po

NAME                        READY   STATUS    RESTARTS   AGE

predictor-5f8bb486d-jd7k2   1/1     Running   0          64s
```

Now, exec into the pod and check if the `model.pkl` file is inside the volume.

```bash
$ kubectl exec -it predictor-5f8bb486d-jd7k2 -- ls /volume/models

model.pkl
```

Now run the following command to port-forward the predictor service so that we can test the prediction endpoint.

```bash
kubectl port-forward svc/predictor-svc 8080:80
```

Now, use the following `curl` command from your workstation to send a prediction request to the predictor application. This will validate whether the application is able to access the `model.pkl` file from the **`ImageVolume`**.

```bash
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{
        "instances": [
          "sparrow",
          "elephant",
          "rose"     
        ]
      }' \
  "http://127.0.0.1:8080/v1/models/model:predict"
```

You will get the following output.

![](https://media.beehiiv.com/cdn-cgi/image/fit=scale-down,format=auto,onerror=redirect,quality=80/uploads/asset/file/6984c43d-842f-456e-a738-d847f8ded191/image.png?t=1756183770)

This is the expected output, `0` means animal, `1` means bird, and `2` means plant.

## ImageVolume With subPath

Lets say you have multiple models in different folders of the OCI image and you want to mount a specific model or want to mount multiple models to the pod.

This is why `subPath` was introduced for ImageVolumes in Kubernetes v1.33.

The image below shows how the subPath mounts a specific model to the pod.

![mounting a single directory of the image with subpath](https://storage.ghost.io/c/5f/2f/5f2f4d20-2abf-4534-8d40-7aa233aedd43/content/images/2026/07/image-99.png)

And the volumeMounts section in the manifest will look like below.

```yaml
  env:
  - name: MODEL_PATH
    value: /volume/model.pkl
  volumeMounts:
  - name: model-vol
    mountPath: /volume
    subPath: models/prediction
volumes:
- name: model-vol
  image:
    reference: devopscube/oci-image:1.0
    pullPolicy: IfNotPresent
```

In this way, you can use same image for multiple models and choose model path in the subPath.

That’s a wrap! 🎉

## Conclusion

In this post, you learned about the **`ImageVolume`** feature in Kubernetes, built an OCI image, and tested it with a sample predictor ML application. 

This feature makes it easy to package data, tools , or models and switch between models without managing complex storage setups.

Refer the [Kubernetes ML features](https://devopscube.com/kubernetes-ai-ml-features/) blog to know more about native ML support in Kubernetes.

If you want to learn more Kubernetes concepts, look at our [Kubernetes tutorial](https://devopscube.com/kubernetes-tutorials-beginners/) blog.

Try this feature and let me know how it goes!