Automating ML Model Training and Deployment with Minikube and FastAPI

Introduction

In this guide, we will automate the training and deployment of a machine learning model using scikit-learn, FastAPI, and Kubernetes (Minikube). The goal is to ensure the model updates without downtime by leveraging Persistent Volumes (PVs) in Kubernetes.

Prerequisites

  • Minikube installed and running
  • Docker installed
  • Kubernetes CLI (kubectl)
  • Basic knowledge of Python and FastAPI

Step 1: Preparing the Model Training Script

We use scikit-learn to train a simple model on a time series dataset.

import joblib
import numpy as np
import pandas as pd
from sklearn.linear_model import Ridge
from sklearn.model_selection import train_test_split

# Generate synthetic data
def generate_data():
    np.random.seed(42)
    X = np.arange(100).reshape(-1, 1)
    y = 0.5 * X.flatten() + np.random.normal(scale=5, size=X.shape[0])
    return X, y

X, y = generate_data()
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Train model
model = Ridge()
model.fit(X_train, y_train)

# Save the model
joblib.dump(model, "/mnt/models/scikit_model.joblib")

Step 2: Creating the FastAPI Model Server

We now create an API to load the model and serve predictions.

from fastapi import FastAPI
import joblib
import numpy as np
import os
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

app = FastAPI()
MODEL_PATH = "/mnt/models/scikit_model.joblib"

def load_model():
    return joblib.load(MODEL_PATH)

model = load_model()

class ModelWatcher(FileSystemEventHandler):
    def on_modified(self, event):
        global model
        if event.src_path == MODEL_PATH:
            model = load_model()
            print("Model updated!")

# Watch for model updates
observer = Observer()
observer.schedule(ModelWatcher(), path="/mnt/models", recursive=False)
observer.start()

@app.get("/predict")
def predict(value: float):
    return {"prediction": model.predict(np.array([[value]]))[0]}

Step 3: Writing Dockerfiles

Model Training Dockerfile

FROM python:3.12
WORKDIR /app
COPY train.py ./
RUN pip install numpy pandas scikit-learn joblib
CMD ["python", "train.py"]

FastAPI Server Dockerfile

FROM python:3.12
WORKDIR /app
COPY api.py ./
RUN pip install fastapi uvicorn joblib watchdog scikit-learn
CMD ["uvicorn", "api:app", "--host", "0.0.0.0", "--port", "8000"]

Step 4: Kubernetes Deployment with Persistent Volumes

Persistent Volume Configuration

apiVersion: v1
kind: PersistentVolume
metadata:
  name: model-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  hostPath:
    path: "/mnt/data/models"

Persistent Volume Claim

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: model-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi

Model Training Job

apiVersion: batch/v1
kind: Job
metadata:
  name: model-trainer
spec:
  template:
    spec:
      containers:
      - name: trainer
        image: myrepo/model-trainer:latest
        imagePullPolicy: Never
        volumeMounts:
        - mountPath: "/mnt/models"
          name: model-storage
      restartPolicy: Never
      volumes:
      - name: model-storage
        persistentVolumeClaim:
          claimName: model-pvc

FastAPI Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: model-api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: model-api
  template:
    metadata:
      labels:
        app: model-api
    spec:
      containers:
      - name: api
        image: myrepo/model-api:latest
        imagePullPolicy: Never
        ports:
        - containerPort: 8000
        volumeMounts:
        - mountPath: "/mnt/models"
          name: model-storage
      volumes:
      - name: model-storage
        persistentVolumeClaim:
          claimName: model-pvc

Step 5: Deploying to Minikube

  1. Start Minikube:
    • minikube start
  2. Build and load Docker images:
    • eval $(minikube docker-env)
    • docker build -t myrepo/model-trainer:latest -f Dockerfile.train .
    • docker build -t myrepo/model-api:latest -f Dockerfile.api .
  3. Apply Kubernetes configurations:
    • kubectl apply -f pv.yaml
    • kubectl apply -f pvc.yaml
    • kubectl apply -f job.yaml
    • kubectl apply -f deployment.yaml
  4. Expose the FastAPI service:
    • kubectl expose deployment model-api --type=NodePort --port=8000
    • minikube service model-api

Step 6: Testing

curl -X 'GET' \
  'http://127.0.0.1:64366/predict?value=123' \
  -H 'accept: application/json'

Conclusion

This setup ensures automated model training and deployment with Kubernetes and Minikube. The Persistent Volume allows seamless updates without downtime, making the system robust for real-time predictions.

Scroll to Top