This guide covers deploying NeuroNetes on Amazon Web Services (AWS) using EKS (Elastic Kubernetes Service).
NeuroNetes on AWS leverages:
# Configure variables
export CLUSTER_NAME=neuronetes-prod
export REGION=us-west-2
export K8S_VERSION=1.28
# Create cluster with GPU node groups
eksctl create cluster \
--name $CLUSTER_NAME \
--region $REGION \
--version $K8S_VERSION \
--node-type m5.xlarge \
--nodes 2 \
--nodes-min 2 \
--nodes-max 5 \
--managed \
--with-oidc
# Add GPU node group (P4d instances)
eksctl create nodegroup \
--cluster $CLUSTER_NAME \
--region $REGION \
--name gpu-workers-p4d \
--node-type p4d.24xlarge \
--nodes 0 \
--nodes-min 0 \
--nodes-max 10 \
--node-labels role=agent,gpu=nvidia-a100 \
--node-taints neuronetes.ai/gpu=true:NoSchedule \
--asg-access
# Add spot GPU node group for burst capacity
eksctl create nodegroup \
--cluster $CLUSTER_NAME \
--region $REGION \
--name gpu-workers-spot \
--node-type p4d.24xlarge \
--nodes 0 \
--nodes-min 0 \
--nodes-max 20 \
--spot \
--instance-types p4d.24xlarge,p4de.24xlarge \
--node-labels role=agent,gpu=nvidia-a100,capacity=spot \
--node-taints neuronetes.ai/gpu=true:NoSchedule \
--asg-access
# Install NVIDIA device plugin
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.14.0/nvidia-device-plugin.yml
# Verify GPU nodes
kubectl get nodes -l gpu=nvidia-a100
kubectl describe node <node-name> | grep nvidia.com/gpu
# Create S3 bucket for model weights
aws s3 mb s3://neuronetes-models-$REGION --region $REGION
# Enable versioning and encryption
aws s3api put-bucket-versioning \
--bucket neuronetes-models-$REGION \
--versioning-configuration Status=Enabled
aws s3api put-bucket-encryption \
--bucket neuronetes-models-$REGION \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
}
}]
}'
# Install EFS CSI driver for shared model cache
kubectl apply -k "github.com/kubernetes-sigs/aws-efs-csi-driver/deploy/kubernetes/overlays/stable/?ref=master"
# Create EFS filesystem
export EFS_ID=$(aws efs create-file-system \
--region $REGION \
--performance-mode maxIO \
--throughput-mode provisioned \
--provisioned-throughput-in-mibps 1024 \
--encrypted \
--tags Key=Name,Value=neuronetes-model-cache \
--query 'FileSystemId' \
--output text)
# Create mount targets in each AZ
for SUBNET_ID in $(aws ec2 describe-subnets \
--region $REGION \
--filters "Name=tag:kubernetes.io/cluster/$CLUSTER_NAME,Values=shared" \
--query 'Subnets[*].SubnetId' \
--output text); do
SECURITY_GROUP=$(aws eks describe-cluster \
--name $CLUSTER_NAME \
--region $REGION \
--query 'cluster.resourcesVpcConfig.clusterSecurityGroupId' \
--output text)
aws efs create-mount-target \
--region $REGION \
--file-system-id $EFS_ID \
--subnet-id $SUBNET_ID \
--security-groups $SECURITY_GROUP
done
# Create StorageClass for model cache
cat <<EOF | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: neuronetes-model-cache
provisioner: efs.csi.aws.com
parameters:
provisioningMode: efs-ap
fileSystemId: $EFS_ID
directoryPerms: "700"
gidRangeStart: "1000"
gidRangeEnd: "2000"
EOF
# Clone repository
git clone https://github.com/Bowenislandsong/NeuroNetes.git
cd NeuroNetes
# Create IAM service account for S3 access
eksctl create iamserviceaccount \
--name neuronetes-controller \
--namespace neuronetes-system \
--cluster $CLUSTER_NAME \
--region $REGION \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess \
--approve \
--override-existing-serviceaccounts
# Install CRDs
kubectl create namespace neuronetes-system
kubectl apply -f config/crd/
# Deploy controllers
kubectl apply -f config/deploy/
# Verify installation
kubectl get pods -n neuronetes-system
kubectl get crds | grep neuronetes
# Install Prometheus Operator
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install kube-prometheus prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false \
--set prometheus.prometheusSpec.podMonitorSelectorNilUsesHelmValues=false
# Install NeuroNetes ServiceMonitors
kubectl apply -f config/monitoring/
# Access Grafana
kubectl port-forward -n monitoring svc/kube-prometheus-grafana 3000:80
# Login with admin/prom-operator
# Configure Model with S3 weights
cat <<EOF | kubectl apply -f -
apiVersion: neuronetes.ai/v1alpha1
kind: Model
metadata:
name: llama-3-70b
namespace: default
spec:
weightsURI: s3://neuronetes-models-$REGION/llama-3-70b/
size: 140Gi
quantization: int4
framework: vllm
shardSpec:
count: 8
strategy: tensor-parallel
topology:
locality: same-node
minBandwidth: 600Gi
cachePolicy:
storageClass: neuronetes-model-cache
priority: high
pinDuration: 2h
status:
phase: Pending
EOF
# Deploy AgentPool
kubectl apply -f config/samples/agentpool_sample.yaml
# Check status
kubectl get models,agentpools,pods
# config/deploy/manager-ha.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: neuronetes-controller-manager
namespace: neuronetes-system
spec:
replicas: 3
selector:
matchLabels:
control-plane: controller-manager
template:
metadata:
labels:
control-plane: controller-manager
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
control-plane: controller-manager
topologyKey: kubernetes.io/hostname
serviceAccountName: neuronetes-controller
containers:
- name: manager
image: ghcr.io/bowenislandsong/neuronetes:v0.1.0
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 500m
memory: 1Gi
Spot Instance Configuration:
apiVersion: neuronetes.ai/v1alpha1
kind: AgentPool
metadata:
name: code-assistant-pool
spec:
minReplicas: 2
maxReplicas: 50
prewarmPercent: 10
# Cost optimization with spot instances
costOptimization:
enabled: true
spotAllocation:
maxSpotPercentage: 70
fallbackToOnDemand: true
sloHeadroomMs: 200
# Scale to spot when headroom allows
scaleToSpot:
enabled: true
minHeadroomMs: 500
nodeSelector:
capacity: spot
tolerations:
- key: neuronetes.ai/gpu
operator: Equal
value: "true"
effect: NoSchedule
Cluster Autoscaler Configuration:
# Install cluster autoscaler
helm repo add autoscaler https://kubernetes.github.io/autoscaler
helm install cluster-autoscaler autoscaler/cluster-autoscaler \
--namespace kube-system \
--set autoDiscovery.clusterName=$CLUSTER_NAME \
--set awsRegion=$REGION \
--set rbac.serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::ACCOUNT_ID:role/cluster-autoscaler
Pod Security Standards:
# Apply pod security standards
kubectl label namespace neuronetes-system \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted
Network Policies:
# config/security/network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: agent-pool-policy
namespace: default
spec:
podSelector:
matchLabels:
neuronetes.ai/component: agent
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
neuronetes.ai/component: ingress
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
neuronetes.ai/component: model-server
ports:
- protocol: TCP
port: 8000
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
CloudWatch Integration:
# Install CloudWatch Container Insights
curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/quickstart/cwagent-fluentd-quickstart.yaml | \
sed "s/{{cluster_name}}/$CLUSTER_NAME/;s/{{region_name}}/$REGION/" | \
kubectl apply -f -
Custom Metrics:
# config/monitoring/servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: neuronetes-metrics
namespace: neuronetes-system
spec:
selector:
matchLabels:
app: neuronetes-controller
endpoints:
- port: metrics
interval: 30s
path: /metrics
# Check NVIDIA device plugin
kubectl logs -n kube-system -l name=nvidia-device-plugin-ds
# Verify GPU drivers
kubectl run gpu-test --image=nvidia/cuda:11.8.0-base-ubuntu22.04 --rm -it -- nvidia-smi
# Check node labels
kubectl get nodes --show-labels | grep gpu
# Check S3 access
kubectl run aws-cli --image=amazon/aws-cli:latest --rm -it -- \
s3 ls s3://neuronetes-models-$REGION/
# Check EFS mount
kubectl exec -it <pod-name> -- df -h | grep efs
# View model controller logs
kubectl logs -n neuronetes-system -l app=neuronetes-controller --tail=100
# Check node metrics
kubectl top nodes
# Check pod resource usage
kubectl top pods -n default
# Analyze scheduler decisions
kubectl logs -n neuronetes-system -l app=neuronetes-scheduler | grep "Scheduling decision"
Monthly costs (us-west-2, approximate):
| Component | Configuration | Monthly Cost |
|---|---|---|
| EKS Control Plane | Standard | $73 |
| m5.xlarge nodes (3) | On-demand | $365 |
| p4d.24xlarge (2) | On-demand | $65,000 |
| p4d.24xlarge (5) | Spot (avg) | $48,750 |
| S3 storage (5TB) | Standard | $115 |
| EFS (10TB) | Provisioned | $6,144 |
| Data transfer | 1TB/month | $90 |
| Total | ~$120,537 |
Cost optimization with spot: ~40% savings on GPU compute