Deployment Guide
Prerequisites
| Requirement | Minimum | Recommended |
|---|---|---|
| Kubernetes | 1.26+ | 1.28+ |
| Nodes | 3 | 5+ |
| CPU (total) | 8 cores | 16+ cores |
| Memory (total) | 16 GB | 32+ GB |
| Helm | 3.12+ | Latest |
| Storage Class | Standard | SSD-backed |
External dependencies:
- PostgreSQL 14+ — AWS RDS, GCP Cloud SQL, Azure Database, or self-hosted
- Redis 7+ — AWS ElastiCache, GCP Memorystore, or self-hosted
- Load Balancer — AWS NLB, GCP Network LB, Azure LB, or MetalLB (on-premise)
- TLS Certificates — cert-manager with Let’s Encrypt (recommended) or manual
Quick Start (Docker Compose)
For local development and evaluation:
git clone https://github.com/ShaneDolphin/avons-corners.git
cd avons-corners
docker compose up -d
docker compose ps This starts all services locally:
| Service | Port | Protocol |
|---|---|---|
| Gateway | 4600 | UDP |
| Auth | 50051 | gRPC |
| CA | 50052 | gRPC |
| Pulse | 50053 | gRPC |
| Policy Engine | 8081 | HTTP |
| Admin API | 8080 | HTTP |
| PostgreSQL | 5432 | TCP |
| Redis | 6379 | TCP |
Kubernetes Deployment
Step 1: Create Namespace
kubectl create namespace avon Step 2: Configure Secrets
Create a secrets file — do not commit this to version control:
apiVersion: v1
kind: Secret
metadata:
name: avon-secrets
namespace: avon
type: Opaque
stringData:
jwt-secret: "your-secure-jwt-secret-minimum-32-characters"
database-url: "postgresql://avon:password@postgres-host:5432/avon"
redis-url: "redis://:password@redis-host:6379"
database-password: "your-database-password"
redis-password: "your-redis-password" kubectl apply -f secrets.yaml Step 3: Install with Helm
Development:
helm install avon deploy/helm/avon
-f deploy/helm/avon/values-dev.yaml
--namespace avon
--set secrets.existingSecret=avon-secrets Staging:
helm install avon deploy/helm/avon
-f deploy/helm/avon/values-staging.yaml
--namespace avon
--set secrets.existingSecret=avon-secrets Production:
helm install avon deploy/helm/avon
-f deploy/helm/avon/values-production.yaml
--namespace avon
--set secrets.existingSecret=avon-secrets
--set externalDatabase.host=your-rds-endpoint.amazonaws.com
--set externalRedis.host=your-elasticache-endpoint.amazonaws.com Step 4: Verify
kubectl get pods -n avon Expected output:
NAME READY STATUS RESTARTS AGE
avon-gateway-xxxxx 1/1 Running 0 2m
avon-gateway-xxxxx 1/1 Running 0 2m
avon-gateway-xxxxx 1/1 Running 0 2m
avon-auth-xxxxx 1/1 Running 0 2m
avon-ca-0 1/1 Running 0 2m
avon-pulse-xxxxx 1/1 Running 0 2m
avon-policy-engine-xxxxx 1/1 Running 0 2m
avon-admin-api-xxxxx 1/1 Running 0 2m Get the gateway external IP:
kubectl get svc avon-gateway -n avon
-o jsonpath='{.status.loadBalancer.ingress[0].ip}' Cloud-Specific Deployments
AWS (EKS)
# values-aws.yaml
gateway:
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
ca:
hsm:
enabled: true
provider: "aws-cloudhsm"
adminApi:
ingress:
enabled: true
className: alb
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-1:ACCOUNT:certificate/CERT-ID
hosts:
- host: admin.avon.example.com
paths:
- path: /
pathType: Prefix helm install avon deploy/helm/avon
-f deploy/helm/avon/values-production.yaml
-f values-aws.yaml
--namespace avon
--set secrets.existingSecret=avon-secrets
--set externalDatabase.host=avon-db.cluster-xxxxx.us-east-1.rds.amazonaws.com
--set externalRedis.host=avon-cache.xxxxx.0001.use1.cache.amazonaws.com GCP (GKE)
# values-gcp.yaml
gateway:
service:
type: LoadBalancer
annotations:
cloud.google.com/l4-rbs: "enabled"
networking.gke.io/load-balancer-type: "External"
ca:
hsm:
enabled: true
provider: "gcp-kms"
adminApi:
ingress:
enabled: true
className: gce
annotations:
kubernetes.io/ingress.global-static-ip-name: avon-admin-ip
networking.gke.io/managed-certificates: avon-admin-cert
hosts:
- host: admin.avon.example.com
paths:
- path: /
pathType: Prefix helm install avon deploy/helm/avon
-f deploy/helm/avon/values-production.yaml
-f values-gcp.yaml
--namespace avon
--set secrets.existingSecret=avon-secrets
--set externalDatabase.host=/cloudsql/PROJECT:REGION:INSTANCE
--set externalRedis.host=10.0.0.3 Azure (AKS)
# values-azure.yaml
gateway:
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/azure-load-balancer-external: "true"
ca:
hsm:
enabled: true
provider: "azure-dedicated-hsm"
adminApi:
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
hosts:
- host: admin.avon.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: admin-tls
hosts:
- admin.avon.example.com helm install avon deploy/helm/avon
-f deploy/helm/avon/values-production.yaml
-f values-azure.yaml
--namespace avon
--set secrets.existingSecret=avon-secrets
--set externalDatabase.host=avon-db.postgres.database.azure.com
--set externalRedis.host=avon-cache.redis.cache.windows.net Bare Metal / On-Premise Deployment
For environments without cloud load balancers, use MetalLB and self-hosted databases.
Prerequisites
Install MetalLB for LoadBalancer service support:
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.5/config/manifests/metallb-native.yaml Configure an IP address pool:
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: avon-pool
namespace: metallb-system
spec:
addresses:
- 192.168.1.200-192.168.1.210
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: avon-l2
namespace: metallb-system
spec:
ipAddressPools:
- avon-pool Deployment
# values-bare-metal.yaml
gateway:
service:
type: LoadBalancer
port: 4600
ca:
persistence:
enabled: true
size: 10Gi
storageClass: "local-path"
adminApi:
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
hosts:
- host: admin.avon.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: admin-tls
hosts:
- admin.avon.example.com helm install avon deploy/helm/avon
-f deploy/helm/avon/values-production.yaml
-f values-bare-metal.yaml
--namespace avon
--set secrets.existingSecret=avon-secrets
--set externalDatabase.host=postgres.internal.example.com
--set externalRedis.host=redis.internal.example.com Firewall Rules
| Source | Destination | Port | Protocol | Purpose |
|---|---|---|---|---|
| Agents (any) | Gateway | 4600 | UDP | Agent tunnels |
| Gateway | Auth | 50051 | TCP | Authentication |
| Gateway | Pulse | 50053 | TCP | Heartbeats |
| Auth | CA | 50052 | TCP | Certificate operations |
| Admins | Admin API | 443 | TCP | Management interface |