Kubernetes Deployment Guide — HenKaiPan ASPM
This guide covers deploying HenKaiPan ASPM to a Kubernetes cluster.
Prerequisites
- Kubernetes cluster (kind, minikube, EKS, GKE, AKS, etc.)
- kubectl configured to access your cluster
- StorageClass configured for PersistentVolumes
- (Optional) NGINX Ingress Controller
- (Optional) cert-manager for TLS
Quick Deployment (Testing Only)
For a quick test deployment:
# Apply all-in-one manifest
kubectl apply -f kubernetes/all-in-one.yaml
# Check status
kubectl get pods -n henkaipan
kubectl get services -n henkaipan
# Access the API
kubectl port-forward svc/henkaipan-api 8080:8080 -n henkaipan
# Open http://localhost:8080Default credentials: admin / admin
Production Deployment
1. Configure Secrets
Edit kubernetes/secrets.yaml and set:
stringData:
JWT_SECRET: "<random-32-char-string>"
SECRET_ENCRYPTION_KEY: "<random-64-char-hex-string>"
ADMIN_PASS: "<your-admin-password>"
# Optional: License key
# LICENSE_KEY: "HENKAI..."Generate secure values:
# JWT_SECRET
openssl rand -base64 32
# SECRET_ENCRYPTION_KEY
openssl rand -hex 32Apply secrets:
kubectl apply -f kubernetes/secrets.yaml2. Configure ConfigMap
Edit kubernetes/configmap.yaml to customize:
CORS_ALLOWED_ORIGINS— Your frontend domainsCOOKIE_SECURE— Set to"true"behind HTTPS- AI provider settings (Ollama, OpenRouter, Cloudflare)
Apply:
kubectl apply -f kubernetes/configmap.yaml3. Deploy Infrastructure
# Namespace
kubectl apply -f kubernetes/namespace.yaml
# PostgreSQL
kubectl apply -f kubernetes/postgres.yaml
# Redis
kubectl apply -f kubernetes/redis.yaml4. Deploy Application
# API
kubectl apply -f kubernetes/api.yaml
# Worker
kubectl apply -f kubernetes/worker.yaml5. Configure Ingress (Optional)
Edit kubernetes/ingress.yaml:
spec:
tls:
- hosts:
- aspm.yourcompany.com # Change this
secretName: henkaipan-tls
rules:
- host: aspm.yourcompany.com # Change thisApply:
kubectl apply -f kubernetes/ingress.yamlAccessing the Application
Via Port Forward (Testing)
kubectl port-forward svc/henkaipan-api 8080:8080 -n henkaipan
# Open http://localhost:8080Via Ingress (Production)
kubectl get ingress -n henkaipan
# Access https://aspm.yourcompany.comVia NodePort
If using the all-in-one manifest:
kubectl get nodes -o wide
# Access http://<node-ip>:30080Monitoring
Prometheus Metrics
Metrics are exposed on port 9090:
kubectl port-forward svc/henkaipan-api 9090:9090 -n henkaipan
# Open http://localhost:9090/metricsHealth Check
kubectl port-forward svc/henkaipan-api 8080:8080 -n henkaipan
curl http://localhost:8080/api/healthLogs
# API logs
kubectl logs -n henkaipan -l app=henkaipan-api -f
# Worker logs
kubectl logs -n henkaipan -l app=henkaipan-worker -f
# PostgreSQL logs
kubectl logs -n henkaipan -l app=postgres -fScaling
Horizontal Scaling (API)
kubectl scale deployment api -n henkaipan --replicas=3Note: Worker should typically remain at 1 replica to avoid duplicate job processing.
Resource Limits
Adjust resource requests/limits in the deployment manifests based on your workload:
- API: 512Mi-2Gi memory, 250m-1000m CPU
- Worker: 1-4Gi memory, 500m-2000m CPU (scanner execution is memory-intensive)
- PostgreSQL: 512Mi-2Gi memory, 250m-1000m CPU
- Redis: 256-512Mi memory, 100-500m CPU
Backup & Restore
Database Backup
# Create backup
kubectl exec -n henkaipan $(kubectl get pod -n henkaipan -l app=postgres -o jsonpath='{.items[0].metadata.name}') \
-- pg_dump -U aspm aspm > backup.sql
# Restore
kubectl exec -n henkaipan $(kubectl get pod -n henkaipan -l app=postgres -o jsonpath='{.items[0].metadata.name}') \
-- psql -U aspm aspm < backup.sqlFor automated backups, consider using tools like Velero or Stash.
Updating
# Pull latest images
kubectl rollout restart deployment/api -n henkaipan
kubectl rollout restart deployment/worker -n henkaipan
# Check status
kubectl rollout status deployment/api -n henkaipan
kubectl rollout status deployment/worker -n henkaipanTroubleshooting
Worker cannot run scans
Verify scanner binaries are available:
kubectl exec -n henkaipan $(kubectl get pod -n henkaipan -l app=henkaipan-worker -o jsonpath='{.items[0].metadata.name}') \
-- which semgrep trivy gitleaksIf this fails, ensure the worker image includes all scanner binaries.
Database connection errors
Check PostgreSQL is running:
kubectl get pods -n henkaipan -l app=postgres
kubectl logs -n henkaipan -l app=postgresVerify connection string in ConfigMap:
kubectl get configmap henkaipan-config -n henkaipan -o yamlAPI crashes on startup
Check logs:
kubectl logs -n henkaipan -l app=henkaipan-apiCommon causes:
- Missing required env vars (
DATABASE_URL,JWT_SECRET,SECRET_ENCRYPTION_KEY) - Database not ready (check PostgreSQL health)
- Invalid configuration values
Security Considerations
- Run as non-root: All deployments are configured with
runAsNonRoot: true - Drop capabilities:
capabilities.drop: ALLis set - Read-only root filesystem: Consider adding for additional hardening
- Network policies: Implement network policies to restrict pod-to-pod communication
- Secrets management: Consider using external secret managers (HashiCorp Vault, AWS Secrets Manager)
- Pod Security Standards: Ensure your cluster enforces appropriate PSS levels
Architecture
┌─────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Ingress │ │ PostgreSQL│ │
│ │ (optional) │ │ (Stateful)│ │
│ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │
│ ┌──────▼──────┐ ┌──────▼──────┐ │
│ │ API │◀───┤ Redis │ │
│ │ (Port 8080)│ │ (Cache/QL) │ │
│ └──────┬──────┘ └─────────────┘ │
│ │ │
│ ┌──────▼──────┐ │
│ │ Worker │ │
│ │ (No ports) │ (embedded scanner binaries) │
│ └─────────────┘ │
└─────────────────────────────────────────────────────┘File Reference
| File | Purpose |
|---|---|
kubernetes/namespace.yaml |
Namespace definition |
kubernetes/configmap.yaml |
Non-sensitive configuration |
kubernetes/secrets.yaml |
Sensitive credentials |
kubernetes/postgres.yaml |
PostgreSQL deployment + PVC + service |
kubernetes/redis.yaml |
Redis deployment + service |
kubernetes/api.yaml |
API deployment + service |
kubernetes/worker.yaml |
Worker deployment (no service) |
kubernetes/ingress.yaml |
Ingress with TLS (optional) |
kubernetes/all-in-one.yaml |
Single manifest for testing |
Support
- Documentation: https://henkaipan.dyallab.com.ar/docs/
- GitHub Issues: Report bugs or feature requests
- Sales: [email protected]