A Kubernetes operator for deploying and managing machine learning models in production environments. This operator provides a declarative way to deploy ML models with support for multiple inference runtimes including Triton, TorchServe, and FastAPI-PyTorch.
The Model Operator is built using the Kubebuilder framework and provides:
- Custom Resource Definition (CRD):
ModelDeploymentfor declarative model deployment - Multiple Runtime Support: Triton, TorchServe, and FastAPI-PyTorch
- Model Validation: Optional validation scripts before deployment
- Autoscaling: Built-in horizontal pod autoscaling support
- Monitoring: Prometheus metrics integration
- Resource Management: Configurable CPU and memory limits
Before you begin, ensure you have the following installed:
- Go 1.24.0 or later
- Docker or Podman for container operations
- kubectl configured to communicate with your cluster
- make for running build commands
- Kind (optional, for local testing)
The operator defines a ModelDeployment custom resource with the following specification:
apiVersion: mlops.sathvik.dev/v1
kind: ModelDeployment
metadata:
name: example-model
spec:
modelURI: "https://example.com/model.pt" # Model artifact location
runtime: "fastapi-pytorch" # Inference runtime
resources: # Resource requirements
limits:
cpu: "500m"
memory: "512Mi"
requests:
cpu: "250m"
memory: "256Mi"
validateScript: "validate.py" # Optional validation script
autoscale: true # Enable autoscaling
version: "v1" # Model version
runtimeImage: "custom-image:tag" # Optional runtime image override- triton: NVIDIA Triton Inference Server
- torchserve: PyTorch TorchServe
- fastapi-pytorch: Custom FastAPI with PyTorch
git clone <repository-url>
cd model-operatorThe project uses make targets to manage dependencies. Run:
# Install all required tools (kustomize, controller-gen, etc.)
make controller-gen
make kustomize
make setup-envtest
make golangci-lint# Generate CRDs and RBAC manifests
make manifests
# Generate DeepCopy methods
make generate# Build the operator binary
make build
# Run tests
make test
# Run linting
make lint
# Run e2e tests (requires Kind cluster)
make test-e2e# Run the operator locally
make run# Install CRDs
make install
# Deploy the operator
make deploy
# Or build and deploy with custom image
make docker-build IMG=your-registry/model-operator:latest
make deploy IMG=your-registry/model-operator:latest# Build for multiple architectures
make docker-buildx IMG=your-registry/model-operator:latestCreate a ModelDeployment resource:
apiVersion: mlops.sathvik.dev/v1
kind: ModelDeployment
metadata:
name: dummy-model
spec:
modelURI: https://dummy.com/dummy_model.pt
runtime: fastapi-pytorch
resources:
limits:
cpu: "500m"
memory: "512Mi"
requests:
cpu: "250m"
memory: "256Mi"
autoscale: false
version: v1Apply it to your cluster:
kubectl apply -f example-cr.yamlapiVersion: mlops.sathvik.dev/v1
kind: ModelDeployment
metadata:
name: custom-model
spec:
modelURI: https://example.com/model.pt
runtime: fastapi-pytorch
runtimeImage: "localhost/fastapi-pytorch:dev"
resources:
limits:
cpu: "1"
memory: "1Gi"
requests:
cpu: "500m"
memory: "512Mi"
validateScript: "validate.py"
autoscale: true
version: v1# Check ModelDeployment status
kubectl get modeldeployments
# Get detailed information
kubectl describe modeldeployment dummy-model
# Check operator logs
kubectl logs -n model-operator-system deployment/model-operator-controller-managerThe operator uses predefined images for each runtime:
- fastapi-pytorch:
localhost/fastapi-pytorch:dev - triton:
nvcr.io/nvidia/tritonserver:latest - torchserve:
pytorch/torchserve:latest
You can override these using the runtimeImage field.
Configure CPU and memory limits/requests based on your model's requirements:
resources:
limits:
cpu: "2"
memory: "4Gi"
requests:
cpu: "1"
memory: "2Gi"Optional validation scripts can be specified to validate models before deployment:
validateScript: "validate.py"The operator exposes Prometheus metrics:
model_deployments_created_total: Total number of ModelDeployment resources createdmodel_validations_total: Number of model validation jobs run (with status labels)
# Port forward to access metrics
kubectl port-forward -n model-operator-system deployment/model-operator-controller-manager 8080:8080
# Access metrics endpoint
curl http://localhost:8080/metrics# Run unit tests
make test# Setup Kind cluster and run e2e tests
make test-e2e
# Cleanup test cluster
make cleanup-test-e2e# Deploy example model
kubectl apply -f example-cr.yaml
# Check deployment status
kubectl get modeldeployments
kubectl get pods
kubectl get services
# Test inference (if using FastAPI runtime)
kubectl port-forward service/dummy-model-service 8000:8000
curl -X POST http://localhost:8000/predict \
-H "Content-Type: application/json" \
-d '{"features": [[1.0], [2.0]]}'model-operator/
βββ api/v1/ # API definitions and CRDs
βββ cmd/main.go # Operator entry point
βββ internal/controller/ # Controller logic
βββ config/ # Kustomize configurations
β βββ crd/ # CRD manifests
β βββ rbac/ # RBAC configurations
β βββ manager/ # Manager deployment
βββ inference/ # Example inference service
βββ test/ # Test files
βββ charts/ # Helm charts
βββ Makefile # Build and deployment commands
- CRD not found: Ensure CRDs are installed with
make install - Image pull errors: Check if runtime images are accessible
- Resource constraints: Verify cluster has sufficient resources
- Validation failures: Check validation script logs
# Check operator logs
kubectl logs -n model-operator-system deployment/model-operator-controller-manager
# Check CRD status
kubectl get crd modeldeployments.mlops.sathvik.dev
# Check events
kubectl get events --sort-by='.lastTimestamp'
# Describe resources
kubectl describe modeldeployment <name>
kubectl describe deployment <name>
kubectl describe service <name>- Kubebuilder - Framework for building Kubernetes operators
- NVIDIA Triton - Inference server
- TorchServe - PyTorch model serving
- FastAPI - Modern Python web framework