Isolated ML Workspaces with Agent-Sandbox
Isolated ML Workspaces with Agent-Sandbox
You must have agent-sandbox already installed on your cluster. Follow the installation guide:
Agent-Sandbox Installation Guide
Make sure the agent-sandbox controller is running before proceeding:
kubectl get pods -n agent-sandbox-system
# Should show agent-sandbox-controller-0 in Running state
.
├── README.md # This file
├── ../../INSTALL.md # Agent-sandbox installation guide
├── jupyterlab.yaml # Modular deployment (Secret + Sandbox only)
├── jupyterlab-full.yaml # All-in-one deployment (+ ConfigMap with file contents)
└── files/
├── download_models.py # Script to download HuggingFace models
├── requirements.txt # Python dependencies
└── welcome.ipynb # Sample notebook
Choose one of two deployment methods:
Use jupyterlab-full.yaml which contains everything in a single file.
Steps:
Edit the HuggingFace token:
# Open jupyterlab-full.yaml and replace HF_TOKEN with your actual token
vi jupyterlab-full.yaml
Or use sed:
export HF_TOKEN="your_actual_HF_token_here"
sed -i "s/HF_TOKEN/$HF_TOKEN/g" jupyterlab-full.yaml
Deploy everything:
kubectl apply -f jupyterlab-full.yaml
Skip to “Verify Installation” section below.
Use jupyterlab.yaml + create ConfigMap from files. This keeps YAML clean.
Steps:
Create the ConfigMap from files:
kubectl create configmap jupyter-init-files \
--from-file=files/download_models.py \
--from-file=files/requirements.txt \
--from-file=files/welcome.ipynb \
--namespace=default
Verify the ConfigMap was created:
kubectl get configmap jupyter-init-files -o yaml
Edit the HuggingFace token:
# Open jupyterlab.yaml and replace HF_TOKEN with your actual token
vi jupyterlab.yaml
Or use sed:
export HF_TOKEN="your_actual_HF_token_here"
sed -i "s/HF_TOKEN/$HF_TOKEN/g" jupyterlab.yaml
Deploy the Sandbox:
kubectl apply -f jupyterlab.yaml
The init container will download packages and models on first run (~5-10 minutes):
# Watch pod creation
kubectl get pods -l sandbox=jupyterlab -w
# Check init container logs
kubectl logs -f jupyterlab-sandbox -c setup-environment
# You should see:
# "Installing Python dependencies to persistent storage..."
# "Downloading models to persistent storage..."
# "Initialization complete!"
Once init completes, verify JupyterLab started:
# Check main container logs
kubectl logs -f jupyterlab-sandbox -c jupyterlab
# Look for: "Jupyter Server ... is running at http://0.0.0.0:8888"
kubectl get sandbox jupyterlab-sandbox
kubectl get pod jupyterlab-sandbox
# Both should show Running status
kubectl port-forward --address 0.0.0.0 pod/jupyterlab-sandbox 8888:8888
Access in browser:
Navigate to the welcome notebook:
welcome.ipynb in the JupyterLab file browserNo password required (authentication disabled for sandbox use).
jupyter-hf-token): Stores your HuggingFace tokenjupyter-init-files): Contains Python scripts and notebooksjupyterlab-sandbox): Creates the JupyterLab environment with:
Edit files/requirements.txt:
transformers>=4.51.0
torch
huggingface_hub
ipywidgets
pandas>=2.0.0 # Add your packages
scikit-learn
matplotlib
Then recreate the ConfigMap and force re-initialization:
# Method A (all-in-one): Edit jupyterlab-full.yaml and reapply
kubectl apply -f jupyterlab-full.yaml
# Method B (modular): Recreate ConfigMap
kubectl delete configmap jupyter-init-files
kubectl create configmap jupyter-init-files \
--from-file=files/download_models.py \
--from-file=files/requirements.txt \
--from-file=files/welcome.ipynb
# Force re-init for both methods
kubectl exec jupyterlab-sandbox -- rm /home/jovyan/.initialized
kubectl delete pod jupyterlab-sandbox
Edit files/download_models.py:
model_names = [
"Qwen/Qwen3-Embedding-0.6B",
"meta-llama/Llama-3.2-1B-Instruct", # Add more
]
Then recreate ConfigMap and force re-init (same steps as above).
Add .ipynb files to the files/ directory, then:
# Recreate ConfigMap with all files
kubectl delete configmap jupyter-init-files
kubectl create configmap jupyter-init-files \
--from-file=files/ \
--namespace=default
# Update init script to copy all notebooks
# Edit jupyterlab.yaml or jupyterlab-full.yaml:
# Change: cp /config/welcome.ipynb /home/jovyan/work/welcome.ipynb
# To: cp /config/*.ipynb /home/jovyan/work/
# Reapply and restart
kubectl apply -f jupyterlab.yaml
kubectl delete pod jupyterlab-sandbox
Modify volumeClaimTemplates in the Sandbox spec:
volumeClaimTemplates:
- metadata:
name: workspace
spec:
resources:
requests:
storage: 50Gi # Increase for large datasets
Note: You must delete the existing Sandbox and PVC to change storage size:
kubectl delete sandbox jupyterlab-sandbox
kubectl delete pvc jupyterlab-sandbox-workspace
kubectl apply -f jupyterlab.yaml
Check init logs:
kubectl logs jupyterlab-sandbox -c setup-environment
Common issues:
Invalid HuggingFace token - 401 Unauthorized errors
kubectl delete secret jupyter-hf-token && kubectl create secret ...Out of disk space - Ephemeral storage exceeded
kubectl describe pod jupyterlab-sandbox | grep VolumesModel download timeout - Network issues or large model
Check main container logs:
kubectl logs jupyterlab-sandbox -c jupyterlab
Common issues:
Port already in use - Unlikely in fresh pod
kubectl exec jupyterlab-sandbox -- netstat -tuln | grep 8888Python packages not found - Init failed or was skipped
kubectl exec jupyterlab-sandbox -- ls /home/jovyan/.local/lib/python3.12/site-packageskubectl exec jupyterlab-sandbox -- rm /home/jovyan/.initialized && kubectl delete pod jupyterlab-sandbox# Delete Sandbox (also deletes pod and PVC)
kubectl delete sandbox jupyterlab-sandbox
# Delete ConfigMap and Secret
kubectl delete configmap jupyter-init-files
kubectl delete secret jupyter-hf-token
# Delete just the Sandbox (keeps PVC)
kubectl delete sandbox jupyterlab-sandbox --cascade=orphan
# PVC remains - you can reattach it later
kubectl get pvc jupyterlab-sandbox-workspace
Isolated ML Workspaces with Agent-Sandbox
Was this page helpful?