This guide provides comprehensive instructions for deploying AstroML with Feature Store to Kubernetes clusters.
The Kubernetes deployment provides:
- Scalable deployment with horizontal pod autoscaling
- High availability with multiple replicas
- Monitoring with Prometheus and Grafana
- Logging with Elasticsearch, Fluentd, and Kibana (EFK stack)
- Ingress for external access
- CI/CD pipeline with GitHub Actions
- Kubernetes cluster v1.24+ (EKS, GKE, AKS, or minikube)
- kubectl v1.24+ configured for cluster access
- kustomize v4.0+ for configuration management
- Helm v3.0+ (optional, for additional packages)
- Storage class configured for persistent volumes
- Ingress controller installed (nginx, traefik, etc.)
# Install kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
# Verify installation
kubectl version --client# Install kustomize
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
sudo mv kustomize /usr/local/bin/
# Verify installation
kustomize version- PostgreSQL - Primary database with persistent storage
- Redis - Caching and job queues
- Feature Store - Dedicated feature management service
- Ingestion Service - Data processing and backfill
- Training Service - ML model training
- API Service - REST API for feature access
- Prometheus - Metrics collection and storage
- Grafana - Visualization and dashboards
- Elasticsearch - Log storage and search
- Fluentd - Log collection and aggregation
- Kibana - Log visualization and analysis
Internet
↓
Ingress Controller
↓
AstroML Services
↓
Feature Store, Ingestion, Training
↓
PostgreSQL, Redis
git clone https://github.com/Menjay7/astroml.git
cd astroml# Create secrets file
cat > k8s/secrets.yaml << EOF
apiVersion: v1
kind: Secret
metadata:
name: postgres-secret
namespace: astroml
type: Opaque
stringData:
password: your-secure-password-here
---
apiVersion: v1
kind: Secret
metadata:
name: astroml-secret
namespace: astroml
type: Opaque
stringData:
database-url: "postgresql://astroml:your-password@postgres:5432/astroml"
redis-url: "redis://redis:6379/0"
EOF# Make script executable
chmod +x scripts/deploy-k8s.sh
# Deploy all components
./scripts/deploy-k8s.sh deploy# Check pod status
kubectl get pods -n astroml
# Check services
kubectl get services -n astroml
# Check ingress
kubectl get ingress -n astroml# Access Grafana
kubectl port-forward -n astroml svc/grafana 3000:3000
# Open browser: http://localhost:3000 (admin/admin)
# Access Kibana
kubectl port-forward -n astroml svc/kibana 5601:5601
# Open browser: http://localhost:5601# Deploy all components
./scripts/deploy-k8s.sh deploy
# Deploy using kustomize
./scripts/deploy-k8s.sh kustomize
# Deploy monitoring only
./scripts/deploy-k8s.sh monitoring
# Deploy logging only
./scripts/deploy-k8s.sh logging# Apply all configurations
kubectl apply -f k8s/
# Apply specific components
kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/postgres-deployment.yaml
kubectl apply -f k8s/feature-store-deployment.yaml# Build and apply
kustomize build k8s/ | kubectl apply -f -
# Build and preview
kustomize build k8s/
# Build to file
kustomize build k8s/ > deployment.yaml
kubectl apply -f deployment.yamlCreate overlays for different environments:
# Production overlay
k8s/overlays/production/
├── kustomization.yaml
├── postgres-patch.yaml
└── feature-store-patch.yaml
# Staging overlay
k8s/overlays/staging/
├── kustomization.yaml
├── postgres-patch.yaml
└── feature-store-patch.yaml# k8s/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: astroml
bases:
- ../../
patchesStrategicMerge:
- postgres-patch.yaml
- feature-store-patch.yaml
images:
- name: astroml
newTag: v1.0.0# k8s/overlays/production/postgres-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
replicas: 3
resources:
requests:
memory: "2Gi"
cpu: "1000m"
limits:
memory: "4Gi"
cpu: "2000m"The Feature Store deployment includes HPA configuration:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: feature-store-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: feature-store
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70# Scale deployment
kubectl scale deployment/feature-store -n astroml --replicas=5
# Scale using script
./scripts/deploy-k8s.sh scale feature-store 5Configure resource limits based on workload:
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"Access Prometheus metrics:
# Port forward to Prometheus
kubectl port-forward -n astroml svc/prometheus 9090:9090
# Access in browser
# http://localhost:9090Access Grafana for visualization:
# Port forward to Grafana
kubectl port-forward -n astroml svc/grafana 3000:3000
# Access in browser
# http://localhost:3000
# Default credentials: admin/adminAccess Kibana for log analysis:
# Port forward to Kibana
kubectl port-forward -n astroml svc/kibana 5601:5601
# Access in browser
# http://localhost:5601# Check pod status
kubectl describe pod <pod-name> -n astroml
# Check logs
kubectl logs <pod-name> -n astroml
# Check events
kubectl get events -n astroml --sort-by='.lastTimestamp'# Check service endpoints
kubectl get endpoints <service-name> -n astroml
# Check service configuration
kubectl describe service <service-name> -n astroml
# Check network policies
kubectl get networkpolicies -n astroml# Check PVC status
kubectl get pvc -n astroml
# Check storage class
kubectl get storageclass
# Check PV status
kubectl get pv# Get all resources
kubectl get all -n astroml
# Get detailed information
kubectl describe deployment/feature-store -n astroml
# Get logs from all pods
kubectl logs -l app=feature-store -n astroml --all-containers=true
# Execute into pod
kubectl exec -it <pod-name> -n astroml -- /bin/bash
# Check resource usage
kubectl top pods -n astroml
kubectl top nodesThe project includes a comprehensive CI/CD pipeline:
# .github/workflows/docker-ci-cd.yml
- Build and test
- Build Docker images
- Security scanning
- Deploy to Kubernetes
- Notification- Build and Test - Run tests and coverage
- Build Docker Images - Build multi-stage images
- Security Scan - Trivy vulnerability scanning
- Deploy to Kubernetes - Automatic deployment
- Notification - Slack notifications
# Trigger deployment manually
gh workflow run docker-ci-cd.yml
# Deploy specific branch
gh workflow run docker-ci-cd.yml -f branch=developUse Kubernetes secrets for sensitive data:
# Create secret from file
kubectl create secret generic db-secret \
--from-literal=password=your-password \
-n astroml
# Create secret from file
kubectl create secret generic tls-secret \
--from-file=tls.crt=./cert.pem \
--from-file=tls.key=./key.pem \
-n astromlImplement network policies for security:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: feature-store-network-policy
namespace: astroml
spec:
podSelector:
matchLabels:
app: feature-store
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: astroml-ingestion
ports:
- protocol: TCP
port: 8000The deployment includes RBAC configuration:
apiVersion: v1
kind: ServiceAccount
metadata:
name: astroml
namespace: astroml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: astroml-role
namespace: astroml
rules:
- apiGroups: [""]
resources: ["configmaps", "secrets"]
verbs: ["get", "list"]# Backup PostgreSQL
kubectl exec -n astroml postgres-0 -- pg_dump -U astroml astroml > backup.sql
# Restore PostgreSQL
kubectl exec -i -n astroml postgres-0 -- psql -U astroml astroml < backup.sql# Backup persistent volumes
kubectl get pvc -n astroml
# Use your cloud provider's backup solution# Restore from backup
kubectl apply -f k8s/
kubectl exec -i -n astroml postgres-0 -- psql -U astroml astroml < backup.sqlAdjust resource limits based on usage:
# Monitor resource usage
kubectl top pods -n astroml
# Update resource limits
kubectl set resources deployment/feature-store \
-n astroml \
--limits=cpu=2000m,memory=2Gi \
--requests=cpu=1000m,memory=1GiOptimize Redis caching:
env:
- name: FEATURE_STORE_CACHE_SIZE
value: "5000"
- name: FEATURE_STORE_CACHE_TTL
value: "7200"Configure PostgreSQL for performance:
env:
- name: POSTGRES_SHARED_BUFFERS
value: "256MB"
- name: POSTGRES_EFFECTIVE_CACHE_SIZE
value: "1GB"# Update deployment
kubectl set image deployment/feature-store \
feature-store=astroml:latest \
-n astroml
# Rollout status
kubectl rollout status deployment/feature-store -n astroml
# Rollback if needed
kubectl rollout undo deployment/feature-store -n astroml# Remove all components
./scripts/deploy-k8s.sh cleanup
# Remove specific components
kubectl delete -f k8s/feature-store-deployment.yaml -n astroml
# Remove namespace
kubectl delete namespace astroml- Always use secrets for sensitive data
- Implement resource limits to prevent resource exhaustion
- Use liveness and readiness probes for health checks
- Implement network policies for security
- Monitor resource usage regularly
- Backup data regularly
- Test deployments in staging first
- Use version tags for images
- Implement proper RBAC for access control
- Document custom configurations
For issues and questions:
- Check this documentation
- Review logs and error messages
- Search GitHub issues
- Create new issue with details