refactor: simplify k8s deployment to pure kubectl

- Remove kustomization.yaml and all kustomize references
- Remove deploy-pi.sh and vpa-pi-helper.sh helper scripts
- Remove redundant ConfigMap from vpa.yaml
- Update README.md to focus on standard kubectl commands
- Keep deployment simple with just YAML files and kubectl
- Maintain Pi 5 optimizations and VPA functionality
- No complex tooling required for deployment
This commit is contained in:
William Valentin
2025-09-14 23:18:04 -07:00
parent e2788cb634
commit 9caf95bb7a
6 changed files with 695 additions and 0 deletions

491
k8s/README.md Normal file
View File

@@ -0,0 +1,491 @@
# UnitForge Raspberry Pi Kubernetes Deployment
Lightweight Kubernetes deployment optimized for Raspberry Pi 5 clusters.
## 🍓 Pi Cluster Requirements
### Hardware
- **Raspberry Pi 5** (4GB+ RAM recommended)
- **SD Card**: 32GB+ Class 10 or better
- **Network**: Gigabit Ethernet preferred
- **Power**: Official Pi 5 power supply
### Software
- **OS**: Raspberry Pi OS 64-bit or Ubuntu 22.04 LTS
- **Kubernetes**: 1.25+ (k3s recommended for Pi)
- **Container Runtime**: containerd or Docker
- **Ingress**: NGINX Ingress Controller
## 📁 Simplified Structure
```
k8s/
├── namespace.yaml # Dedicated namespace
├── configmap.yaml # Application configuration
├── deployment.yaml # Single replica deployment
├── service.yaml # ClusterIP service
├── ingress.yaml # Local domain ingress
└── vpa.yaml # Vertical Pod Autoscaler for Pi
```
**Simple kubectl deployment** - No kustomize, scripts, or complex tooling required!
## 🚀 Quick Deployment
### Apply All Resources
```bash
# Create namespace (optional)
kubectl create namespace unitforge
# Apply all resources to specific namespace
kubectl apply -f k8s/ -n unitforge
# Or apply to default namespace
kubectl apply -f k8s/
# Check status
kubectl get all -n unitforge
```
### Step-by-Step Deploy
```bash
# Create namespace (optional)
kubectl create namespace unitforge
# Apply resources in order
kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/configmap.yaml -n unitforge
kubectl apply -f k8s/deployment.yaml -n unitforge
kubectl apply -f k8s/service.yaml -n unitforge
kubectl apply -f k8s/ingress.yaml -n unitforge
kubectl apply -f k8s/vpa.yaml -n unitforge
```
## 🔧 Pi Optimizations
### Resource Limits
- **Memory**: 128Mi request, 256Mi limit (VPA optimized)
- **CPU**: 100m request, 300m limit (VPA optimized)
- **Workers**: 2 (down from 4)
- **Replicas**: 1 (sufficient for Pi cluster)
- **VPA**: Enabled for automatic resource optimization
### Simplified Configuration
- **No HPA**: Single replica, manual scaling
- **No TLS**: HTTP only for simplicity
- **No NetworkPolicy**: Simplified networking
- **No Kustomize**: Standard kubectl commands only
- **Basic probes**: Longer timeouts for Pi performance
- **Minimal metrics**: Disabled to save resources
### Local Domains
- `unitforge.local` - Primary access
- `unitforge.pi` - Alternative domain
## 🌐 Access Setup
### Add to /etc/hosts
```bash
# Replace <pi-ip> with your Pi node IP
echo "<pi-ip> unitforge.local" >> /etc/hosts
echo "<pi-ip> unitforge.pi" >> /etc/hosts
```
### Get Node IP
```bash
# Find your Pi node IP
kubectl get nodes -o wide
# Or get ingress IP
kubectl get ingress unitforge -n unitforge
```
### Access Methods
```bash
# Browser access
http://unitforge.local
http://unitforge.pi
# Port forwarding
kubectl port-forward service/unitforge 8080:80 -n unitforge
# Then: http://localhost:8080
# Direct pod access
kubectl port-forward pod/<pod-name> 8080:8000 -n unitforge
```
## 📊 Pi Cluster Management
### Check Deployment
```bash
# Overall status (replace unitforge with your namespace)
kubectl get all -n unitforge
# Pod details
kubectl describe pod -l app=unitforge -n unitforge
# Logs
kubectl logs -f deployment/unitforge -n unitforge
# Resource usage
kubectl top pods -n unitforge
# If using current namespace, omit -n flag
kubectl get all
kubectl logs -f deployment/unitforge
```
### Common Operations
```bash
# Restart deployment (adjust namespace as needed)
kubectl rollout restart deployment/unitforge -n unitforge
# Scale (if needed)
kubectl scale deployment unitforge --replicas=2 -n unitforge
# Update image
kubectl set image deployment/unitforge unitforge=new-image:tag -n unitforge
# Delete everything
kubectl delete namespace unitforge
# Or if using default namespace
kubectl delete -f k8s/
```
### Troubleshooting
```bash
# Check events (adjust namespace as needed)
kubectl get events -n unitforge --sort-by='.lastTimestamp'
# Pod shell access
kubectl exec -it deployment/unitforge -n unitforge -- /bin/bash
# Check node resources
kubectl describe node <pi-node-name>
# Check disk space
kubectl exec -it deployment/unitforge -n unitforge -- df -h
# For current namespace, omit -n flag
kubectl get events --sort-by='.lastTimestamp'
kubectl exec -it deployment/unitforge -- /bin/bash
```
## 🤖 Vertical Pod Autoscaler (VPA)
### VPA Benefits for Pi Clusters
- **Automatic optimization**: Adjusts resource requests based on actual usage
- **Pi hardware awareness**: Conservative limits for ARM64 architecture
- **Memory efficiency**: Critical for Pi nodes with limited RAM
- **Cost optimization**: Right-sizing for Pi cluster resources
### VPA Configuration
```bash
# Check if VPA is installed
kubectl get crd verticalpodautoscalers.autoscaling.k8s.io
# Apply VPA configuration
kubectl apply -f vpa.yaml -n unitforge
# Monitor VPA recommendations
kubectl get vpa unitforge-vpa -n unitforge
kubectl describe vpa unitforge-vpa -n unitforge
# Check current pod resources
kubectl get pods -l app=unitforge -n unitforge -o wide
kubectl top pods -l app=unitforge -n unitforge
```
### VPA Resource Bounds (Pi Optimized)
```yaml
# CPU bounds for Pi 5
minAllowed:
cpu: 50m # Minimal baseline
memory: 64Mi # Absolute minimum
maxAllowed:
cpu: 500m # Conservative Pi 5 limit
memory: 512Mi # Safe for 4-8GB Pi
```
### Installing VPA on Pi Cluster
```bash
# Install VPA components (if not already installed)
kubectl apply -f https://github.com/kubernetes/autoscaler/releases/latest/download/vpa-release.yaml
# Verify VPA installation
kubectl get pods -n kube-system | grep vpa
# Check VPA CRDs
kubectl get crd | grep verticalpodautoscaler
```
### VPA Management Commands
```bash
# Check VPA status
kubectl get vpa unitforge-vpa -n unitforge -o wide
# Apply VPA to unitforge namespace
kubectl apply -f vpa.yaml -n unitforge
# Monitor resource usage
kubectl top pods -l app=unitforge -n unitforge
kubectl describe pods -l app=unitforge -n unitforge
# Restart deployment to apply recommendations
kubectl rollout restart deployment/unitforge -n unitforge
# Delete VPA if needed
kubectl delete vpa unitforge-vpa -n unitforge
```
### VPA Monitoring
```bash
# View VPA recommendations
kubectl describe vpa unitforge-vpa -n unitforge
# Check current vs recommended resources
kubectl get vpa unitforge-vpa -n unitforge -o yaml
# Monitor pod resource usage
kubectl top pods -l app=unitforge -n unitforge --containers
# Pi-specific monitoring
vcgencmd measure_temp # Pi temperature
htop # System resources
iostat -x 1 5 # I/O performance
# Simple VPA status check
kubectl get vpa -n unitforge
```
## 🔧 Configuration
### Environment Variables (ConfigMap)
```yaml
# Key Pi-optimized settings
WORKERS: "2" # Reduced for Pi
MAX_CONNECTIONS: "50" # Lower limit
REQUEST_TIMEOUT: "60" # Longer for Pi
ENABLE_API_METRICS: "false" # Disabled to save resources
COMPRESS_RESPONSES: "true" # Reduce bandwidth
```
### Resource Tuning
```yaml
# For Pi 4 (4GB) - reduce further
resources:
requests:
memory: "96Mi"
cpu: "50m"
limits:
memory: "192Mi"
cpu: "200m"
# For Pi 5 (8GB) - can increase
resources:
requests:
memory: "256Mi"
cpu: "200m"
limits:
memory: "512Mi"
cpu: "500m"
```
## 🍓 Pi-Specific Tips
### Performance
- **Use fast SD cards**: Class 10, U3, or A1/A2 rated
- **Enable cgroups**: Add to `/boot/cmdline.txt`:
```
cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory
```
- **Increase swap**: For memory-constrained Pis
- **Use SSD**: Boot from SSD for better I/O performance
### Networking
- **Use wired connections**: Ethernet preferred over WiFi
- **Local DNS**: Consider Pi-hole for local resolution
- **MetalLB**: For LoadBalancer services in bare metal
### Storage
- **EmptyDir volumes**: Used for temporary files
- **Local storage**: Consider local-path-provisioner
- **NFS**: For shared storage across Pi nodes
## 🔍 Monitoring on Pi
### Basic Monitoring
```bash
# Node resources
kubectl top nodes
# Pod resources (adjust namespace as needed)
kubectl top pods -n unitforge
# Or current namespace
kubectl top pods
# System resources on Pi
htop
iostat
free -h
df -h
```
### Simple Metrics
```bash
# Application health
curl http://unitforge.local/health
# Basic load test
for i in {1..10}; do
curl -s http://unitforge.local/health > /dev/null
echo "Request $i completed"
done
```bash
# VPA resource monitoring
kubectl get vpa -n unitforge
kubectl describe vpa unitforge-vpa -n unitforge
# Watch VPA recommendations
watch kubectl describe vpa unitforge-vpa -n unitforge
```
## 🚨 Common Pi Issues
### Memory Pressure
```bash
# Check memory usage
kubectl describe node <pi-node>
# Check pod memory usage
kubectl top pods -n unitforge
# Check VPA recommendations
kubectl describe vpa unitforge-vpa -n unitforge
# Apply VPA recommendations
kubectl rollout restart deployment/unitforge -n unitforge
# Reduce resource requests manually if needed
# Edit deployment.yaml resources section
```
### Storage Full
```bash
# Check disk usage (adjust namespace as needed)
kubectl exec -it deployment/unitforge -n unitforge -- df -h
# Clean Docker images on nodes
docker system prune -f
```
### Slow Performance
```bash
# Check I/O wait
iostat -x 1 5
# Consider moving to SSD
# Check SD card health
```
### Network Issues
```bash
# Check ingress controller
kubectl get pods -n ingress-nginx
# Test internal networking (adjust namespace as needed)
kubectl exec -it deployment/unitforge -n unitforge -- wget -qO- http://unitforge/health
# Test service connectivity
kubectl exec -it deployment/unitforge -n unitforge -- wget -qO- http://unitforge.unitforge.svc.cluster.local/health
```
## 📚 Standard Kubernetes Workflows
### Deployment Management
```bash
# Check deployment status
kubectl rollout status deployment/unitforge -n unitforge
# View deployment history
kubectl rollout history deployment/unitforge -n unitforge
# Rollback deployment
kubectl rollout undo deployment/unitforge -n unitforge
# Restart deployment
kubectl rollout restart deployment/unitforge -n unitforge
```
### Configuration Updates
```bash
# Update configmap
kubectl apply -f k8s/configmap.yaml -n unitforge
# Force pod restart to pick up config changes
kubectl rollout restart deployment/unitforge -n unitforge
# Edit configmap directly
kubectl edit configmap unitforge-config -n unitforge
```
### Resource Management
```bash
# Scale deployment
kubectl scale deployment unitforge --replicas=2 -n unitforge
# VPA-based resource optimization
kubectl apply -f vpa.yaml -n unitforge
kubectl rollout restart deployment/unitforge -n unitforge
# Manual resource updates (if VPA not used)
kubectl patch deployment unitforge -n unitforge -p '{"spec":{"template":{"spec":{"containers":[{"name":"unitforge","resources":{"limits":{"memory":"512Mi"}}}]}}}}'
# Get resource usage and VPA recommendations
kubectl top pods -n unitforge
kubectl describe vpa unitforge-vpa -n unitforge
kubectl describe deployment unitforge -n unitforge
```
## 📚 Pi Cluster Resources
### K3s Installation
```bash
# Master node
curl -sfL https://get.k3s.io | sh -
# Worker nodes
curl -sfL https://get.k3s.io | K3S_URL=https://<master-ip>:6443 K3S_TOKEN=<token> sh -
```
### Useful Pi Tools
- **k3s**: Lightweight Kubernetes for Pi
- **kubectl**: Standard Kubernetes CLI (no kustomize needed)
- **k9s**: Terminal UI for Kubernetes
- **htop**: System monitoring
- **vcgencmd**: Pi-specific commands
## 🎯 Production on Pi
### High Availability
- **Multiple Pi nodes**: 3+ for redundancy
- **Shared storage**: NFS or distributed storage
- **Load balancing**: MetalLB or external LB
- **Backup strategy**: Regular etcd backups
### Security
- **Network segmentation**: VLANs for cluster traffic
- **Firewall rules**: iptables or ufw configuration
- **Regular updates**: Keep Pi OS and k3s updated
- **Monitoring**: Basic Prometheus setup
### Scaling
- **Horizontal**: Add more Pi nodes
- **Vertical**: Upgrade to Pi 5 with more RAM
- **Storage**: Add USB SSDs for better performance
- **Network**: Ensure gigabit switches
---
**UnitForge on Pi** - Making systemd management portable! 🍓🚀

58
k8s/configmap.yaml Normal file
View File

@@ -0,0 +1,58 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: unitforge-config
labels:
app: unitforge
component: config
data:
# Application Information
APP_NAME: "UnitForge"
APP_VERSION: "1.0.0"
APP_DESCRIPTION: "Create, validate, and manage systemd unit files"
# Server Configuration
HOST: "0.0.0.0"
PORT: "8000"
DEBUG: "false"
ENVIRONMENT: "production"
LOG_LEVEL: "info"
RELOAD: "false"
WORKERS: "2"
# API Configuration
DOCS_URL: "/api/docs"
REDOC_URL: "/api/redoc"
# CORS Configuration
CORS_ORIGINS: "*"
# File Upload Settings
MAX_UPLOAD_SIZE: "2097152"
ALLOWED_EXTENSIONS: "['.service', '.timer', '.socket', '.mount', '.target', '.path']"
# Feature Flags
ENABLE_API_METRICS: "false"
ENABLE_REQUEST_LOGGING: "true"
ENABLE_TEMPLATE_CACHING: "true"
ENABLE_VALIDATION_CACHING: "true"
# Performance Settings (optimized for Pi)
REQUEST_TIMEOUT: "60"
KEEPALIVE_TIMEOUT: "10"
MAX_CONNECTIONS: "50"
# Monitoring
HEALTH_CHECK_ENABLED: "true"
METRICS_ENABLED: "false"
# Asset Optimization
MINIFY_ASSETS: "true"
COMPRESS_RESPONSES: "true"
HOT_RELOAD: "false"
SOURCE_MAPS: "false"
# Documentation
API_DOCS_ENABLED: "true"
SWAGGER_UI_ENABLED: "true"
REDOC_ENABLED: "true"

74
k8s/deployment.yaml Normal file
View File

@@ -0,0 +1,74 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: unitforge
labels:
app: unitforge
component: webapp
spec:
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: unitforge
template:
metadata:
labels:
app: unitforge
component: webapp
spec:
containers:
- name: unitforge
image: gitea-http.taildb3494.ts.net/will/unitforge:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 8000
protocol: TCP
env:
- name: HOST
value: "0.0.0.0"
- name: PORT
value: "8000"
- name: DEBUG
value: "false"
- name: ENVIRONMENT
value: "production"
- name: LOG_LEVEL
value: "info"
- name: RELOAD
value: "false"
- name: WORKERS
value: "2"
envFrom:
- configMapRef:
name: unitforge-config
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "300m"
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
restartPolicy: Always
terminationGracePeriodSeconds: 30

27
k8s/ingress.yaml Normal file
View File

@@ -0,0 +1,27 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: unitforge
labels:
app: unitforge
component: ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/proxy-body-size: "5m"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "10"
nginx.ingress.kubernetes.io/proxy-send-timeout: "30"
nginx.ingress.kubernetes.io/proxy-read-timeout: "30"
spec:
ingressClassName: nginx
rules:
- host: app.unitforge.192.168.153.243.nip.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: unitforge
port:
number: 8000

16
k8s/service.yaml Normal file
View File

@@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: unitforge
labels:
app: unitforge
component: webapp
spec:
type: ClusterIP
ports:
- name: http
port: 8000
targetPort: http
protocol: TCP
selector:
app: unitforge

29
k8s/vpa.yaml Normal file
View File

@@ -0,0 +1,29 @@
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: unitforge-vpa
labels:
app: unitforge
component: vpa
platform: raspberry-pi
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: unitforge
updatePolicy:
updateMode: "Auto"
minReplicas: 1
resourcePolicy:
containerPolicies:
- containerName: unitforge
# Pi 5 optimized resource bounds
minAllowed:
cpu: 50m
memory: 64Mi
maxAllowed:
cpu: 500m # Conservative limit for Pi 5
memory: 512Mi # Pi 5 can handle this but keep reasonable
# Controlled resource recommendations for Pi hardware
controlledResources: ["cpu", "memory"]
controlledValues: Requests