Skip to content

Commit fd26bbc

Browse files
committed
new docs for PVC storage and model management
Signed-off-by: samzong <[email protected]>
1 parent 1361bb0 commit fd26bbc

8 files changed

Lines changed: 1115 additions & 0 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
title: "Architecture"
3+
linkTitle: "Architecture"
4+
weight: 5
5+
description: >
6+
Technical architecture and design details of OME components and systems.
7+
---
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
---
2+
title: "PVC Storage"
3+
date: 2025-07-25
4+
weight: 15
5+
description: >
6+
Technical architecture and design decisions for PVC storage support in OME.
7+
---
8+
9+
## Architecture Overview
10+
11+
PVC storage in OME uses a **controller-only architecture** that bypasses the model
12+
agent entirely. This design leverages Kubernetes native volume mounting and eliminates
13+
model duplication.
14+
15+
## Key Design Decision: Skip Model Agent
16+
17+
**Why?** DaemonSet pods cannot efficiently mount PVCs, especially ReadWriteOnce
18+
volumes.
19+
20+
```mermaid
21+
flowchart LR
22+
subgraph "Traditional Storage"
23+
MA1[Model Agent] --> Download[Download Model]
24+
Download --> HostPath[Store on Host]
25+
HostPath --> Label[Label Node]
26+
end
27+
28+
subgraph "PVC Storage"
29+
BMC[BaseModel Controller] --> Validate[Validate PVC]
30+
Validate --> Extract[Extract Metadata]
31+
Extract --> Mount[Direct PVC Mount]
32+
MA2[Model Agent] -.-> Skip[Skips PVC Models]
33+
end
34+
35+
classDef traditional fill:#ffebee
36+
classDef pvc fill:#e8f5e8
37+
38+
class MA1,Download,HostPath,Label traditional
39+
class BMC,Validate,Extract,Mount pvc
40+
```
41+
42+
## Component Flow
43+
44+
```mermaid
45+
sequenceDiagram
46+
participant User
47+
participant BMC as BaseModel Controller
48+
participant K8s as Kubernetes API
49+
participant Job as Metadata Job
50+
participant ISC as InferenceService Controller
51+
52+
User->>BMC: Create BaseModel with PVC URI
53+
BMC->>K8s: Validate PVC exists & bound
54+
55+
alt PVC Ready
56+
BMC->>K8s: Create metadata extraction Job
57+
Job->>Job: Mount PVC, read config.json
58+
Job->>BMC: Update BaseModel metadata
59+
BMC->>BMC: Set status: Ready
60+
else PVC Not Ready
61+
BMC->>BMC: Set status: Failed
62+
end
63+
64+
User->>ISC: Create InferenceService
65+
ISC->>K8s: Create pods with PVC volumes
66+
K8s->>K8s: Schedule based on PVC constraints
67+
```
68+
69+
## Component Responsibilities
70+
71+
| Component | Role | PVC Handling |
72+
| ------------------------------- | ------------------------------ | -------------------------------------------------- |
73+
| **Model Agent** | Downloads models, labels nodes | **Skips PVC** entirely |
74+
| **BaseModel Controller** | Manages BaseModel lifecycle | **Primary owner** - validates, extracts metadata |
75+
| **Metadata Job** | Extracts model config | **Temporary** - mounts PVC, reads config.json |
76+
| **InferenceService Controller** | Manages serving pods | **Volume mounter** - creates pods with PVC volumes |
77+
78+
## Core Design Decisions
79+
80+
### 1. Why Skip Model Agent?
81+
82+
**Problem**: DaemonSet + PVC incompatibility
83+
84+
- DaemonSets run on every node
85+
- ReadWriteOnce PVCs can't be mounted by multiple pods
86+
- Complex coordination needed for RWO volumes
87+
88+
**Solution**: Controller-only approach
89+
90+
```go
91+
// Model agent explicitly skips PVC storage
92+
switch storageType {
93+
case storage.StorageTypePVC:
94+
s.logger.Infof("Skipping PVC storage for model %s", modelInfo)
95+
return nil
96+
}
97+
```
98+
99+
### 2. Why Use Jobs for Metadata?
100+
101+
**Problem**: Need to read model config from PVC
102+
**Solution**: Ephemeral Jobs with PVC mount
103+
104+
```yaml
105+
# Metadata extraction job template
106+
apiVersion: batch/v1
107+
kind: Job
108+
metadata:
109+
name: metadata-{model}-{hash}
110+
spec:
111+
template:
112+
spec:
113+
containers:
114+
- name: extractor
115+
image: ome/metadata-agent
116+
volumeMounts:
117+
- name: model-pvc
118+
mountPath: /models
119+
readOnly: true
120+
volumes:
121+
- name: model-pvc
122+
persistentVolumeClaim:
123+
claimName: { pvc-name }
124+
```
125+
126+
### 3. Why No Node Labeling?
127+
128+
**Traditional**: Model agent labels nodes with available models
129+
**PVC**: Kubernetes scheduler handles PVC placement constraints
130+
131+
```mermaid
132+
graph TB
133+
subgraph "Traditional Storage"
134+
MA[Model Agent] --> Label[Label Node:<br/>model-xyz=ready]
135+
Label --> Schedule[Pod scheduled<br/>to labeled node]
136+
end
137+
138+
subgraph "PVC Storage"
139+
PVC[PVC Constraint] --> K8sScheduler[Kubernetes Scheduler]
140+
K8sScheduler --> AutoSchedule[Pod scheduled<br/>where PVC accessible]
141+
end
142+
```
143+
144+
## Storage Type Comparison
145+
146+
| Aspect | PVC Storage | Object Storage | HuggingFace |
147+
| ----------------- | ----------------- | ---------------- | ---------------- |
148+
| **Model Agent** | Skipped | Downloads | Downloads |
149+
| **Node Labels** | None | Creates labels | Creates labels |
150+
| **Scheduling** | PVC constraints | Node selectors | Node selectors |
151+
| **Data Transfer** | None | Network download | Network download |
152+
| **Availability** | Storage dependent | Node replicated | Node replicated |
153+
154+
## Security Model
155+
156+
### RBAC Requirements
157+
158+
```yaml
159+
# BaseModel Controller permissions
160+
- apiGroups: [""]
161+
resources: ["persistentvolumeclaims"]
162+
verbs: ["get", "list", "watch"]
163+
- apiGroups: ["batch"]
164+
resources: ["jobs"]
165+
verbs: ["create", "get", "list", "watch"]
166+
167+
# Metadata Job permissions
168+
- apiGroups: [""]
169+
resources: ["persistentvolumeclaims"]
170+
verbs: ["get"]
171+
- apiGroups: ["ome.io"]
172+
resources: ["basemodels"]
173+
verbs: ["update"]
174+
```
175+
176+
### Security Boundaries
177+
178+
- **Namespace isolation**: BaseModel → same namespace PVC only
179+
- **Read-only mounts**: All PVC mounts are read-only
180+
- **Minimal permissions**: Jobs have least-privilege access
181+
182+
## Performance Profile
183+
184+
| Operation | PVC Storage | Object Storage |
185+
| ---------------------- | -------------- | ------------------- |
186+
| **Model Loading** | Immediate | Minutes (download) |
187+
| **Scaling Up** | Fast | Slow (re-download) |
188+
| **Storage Efficiency** | No duplication | Replicated per node |
189+
190+
**Performance depends on storage backend:**
191+
192+
- **NFS**: Good for sharing, may bottleneck with many pods
193+
- **Block storage**: Excellent single-pod, RWO limits concurrency
194+
- **Distributed**: Scales well, varies by implementation
195+
196+
## Common Issues & Solutions
197+
198+
| Issue | Cause | Solution |
199+
| ---------------------- | -------------------- | ------------------------------------- |
200+
| MetadataPending | PVC not bound | Check PVC status, storage provisioner |
201+
| Pod scheduling failure | PVC node constraints | Verify PVC accessible from nodes |
202+
| Slow model loading | Storage performance | Use faster storage class |
203+
204+
## Future Enhancements
205+
206+
**Planned:**
207+
208+
- Cross-namespace PVC access with RBAC
209+
- Volume snapshot integration for versioning
210+
- Multi-PVC model support
211+
- Performance optimization hints
212+
213+
**Integration:**
214+
215+
- CSI driver advanced features
216+
- Automatic storage class selection
217+
- Volume expansion for growing repos
218+
219+
## Related Documentation
220+
221+
- [PVC Storage User Guide](/ome/docs/user-guide/storage/pvc-storage/) - How to use
222+
- [Troubleshooting PVC Storage](/ome/docs/troubleshooting/pvc-storage/) - Common issues
223+
- [Storage Types Reference](/ome/docs/reference/storage-types/) - Complete API spec

0 commit comments

Comments
 (0)