Charon is a production-ready Kubernetes infrastructure platform designed around category-based namespace isolation, secure VPN mesh networking, and centralized identity management.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β External Access Layer β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Internet βββΆ LoadBalancer βββΆ nginx-ingress βββΆ cert-manager β
β (Linode LKE) (external) (Let's Encrypt) β
β β
ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β VPN Coordination Layer β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Headscale (core namespace) β
β ββ Control server for Tailscale mesh VPN β
β ββ User and pre-auth key management β
β ββ 100.64.0.0/10 address allocation β
β ββ External HTTPS endpoint for enrollment β
β β
ββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Kubernetes Cluster (LKE) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β core Namespace β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
β β βͺ Headscale (VPN coordination) β β
β β βͺ FreeIPA (LDAP/Kerberos identity management) β β
β β βͺ Container Registry (future) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β monitoring Namespace β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
β β βͺ Prometheus (metrics, 35+ targets, 15d retention) β β
β β βͺ Thanos (long-term storage, optional) β β
β β βͺ Grafana (dashboards, git-sync, Tempo correlations) β β
β β βͺ Loki (log aggregation, emptyDir) β β
β βͺ Tempo (distributed tracing, OTLP/gRPC) β β
β β βͺ Promtail (log collection, DaemonSet) β β
β β βͺ AlertManager (alert routing) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β gitops Namespace β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
β β βͺ Redmine (project management, PostgreSQL external) β β
β β βͺ GitLab (future) β β
β β βͺ ArgoCD (future) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β inference Namespace β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
β β βͺ Open-WebUI (AI chat interface) β β
β β βͺ Ollama (LLM inference) β β
β β βͺ vLLM (future, GPU workloads) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β infra Namespace β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
β β βͺ NetBox (future, IPAM) β β
β β βͺ Vault (future, secret management) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Services are organized into functional categories with strict RBAC boundaries:
| Namespace | Purpose | Services |
|---|---|---|
| core | Infrastructure dependencies | Headscale, FreeIPA |
| monitoring | Observability stack | Prometheus, Grafana, Loki, Thanos |
| gitops | Development tooling | Redmine, GitLab (future), ArgoCD (future) |
| inference | AI/ML workloads | Open-WebUI, Ollama, vLLM (future) |
| infra | Operations tools | NetBox (future), Vault (future) |
Benefits:
- Clear security and trust boundaries
- Independent resource quotas and limits
- Simplified RBAC management
- Logical grouping of related services
- Easy to add new categories
See Namespaces Configuration for Terraform variables.
Headscale provides self-hosted Tailscale control server for secure mesh VPN:
- Address Range: 100.64.0.0/10 (CGNAT space)
- Protocol: WireGuard
- Enrollment: Pre-auth keys via kubectl exec
- Client: Official Tailscale client on all platforms
- Access: All services VPN-only (no public exposure)
Architecture:
βββββββββββββββ ββββββββββββββββ ββββββββββββββ
β Laptop β β Desktop β β Kubernetes β
β Tailscale ββββββββββββΆβ Tailscale βββββββββββΆβ Pods β
β 100.64.x.x β β 100.64.x.x β β (sidecars) β
βββββββββββββββ ββββββββββββββββ ββββββββββββββ
β β β
βββββββββββββββββββββββββββΌββββββββββββββββββββββββββ
βΌ
βββββββββββββββββ
β Headscale β
β (core ns) β
β 100.64.0.1 β
βββββββββββββββββ
See Networking Architecture and VPN Enrollment Guide.
FreeIPA provides centralized authentication and user management:
- Protocol: LDAPS (port 636)
- Base DN:
dc=example,dc=org(configured via Terraform) - Services: LDAP directory, Kerberos KDC, certificate authority
- Integration: All services authenticate via FreeIPA
- Web UI:
https://ipa.example.com(VPN-only)
LDAP Integration:
- Redmine project management
- Grafana dashboarding
- Future services (GitLab, NetBox, Vault)
See FreeIPA Service and LDAP Integration Guide.
All services use standardized 3-container (or 5-container with lifecycle) architecture:
Core Containers:
- nginx-tls - HTTPS termination (port 443), proxies to localhost
- Application - Main service on localhost (not exposed externally)
- Tailscale - VPN sidecar for mesh connectivity
Lifecycle Containers (when Tailscale enabled): 4. lifecycle-cleanup (init) - Cleans up old Headscale nodes and DNS records before startup 5. lifecycle-dns-create (sidecar) - Creates DNS record after Tailscale registers VPN IP
Benefits:
- Security isolation (app never exposed directly)
- Automatic cleanup of orphaned resources
- Self-healing DNS on pod recreation
- VPN-only access enforcement
- Consistent deployment pattern
See StatefulSet Pattern Details.
User βββΆ VPN βββΆ DNS βββΆ nginx-tls βββΆ Application
(WG) (A) (HTTPS) (localhost)
- User connects to VPN (Tailscale client β Headscale)
- DNS resolves service hostname to pod VPN IP
- nginx-tls terminates TLS, validates VPN IP range
- nginx-tls proxies request to application on localhost
- Application processes request (may authenticate via FreeIPA LDAP)
Pods βββΆ Prometheus βββΆ Thanos βββΆ Grafana
(scrape) (store) (query)
β²
Pods βββΆ Promtail βββΆ Loki ββββββββββ
(push) (index)
- Prometheus scrapes
/metricsendpoints (ServiceMonitor auto-discovery) - Thanos optionally archives and downsamples metrics for long-term storage
- Promtail DaemonSet collects logs from all pods
- Loki indexes logs with Kubernetes metadata labels
- Grafana queries Prometheus/Thanos for metrics and Loki for logs
See Monitoring Guide.
Terraform βββΆ Cloudflare API βββΆ DNS Records
(create A record)
β
βΌ
Init Container βββΆ Update IP βββΆ Service VPN IP
(lifecycle) (on startup)
β
βΌ
DNS Sidecar βββββΆ Update IP βββΆ Final VPN IP
(lifecycle) (after VPN up)
- Terraform creates DNS A record with fallback IP (node IP)
- Init container updates DNS to pod's VPN IP on startup
- DNS sidecar waits for Tailscale connection, updates to final VPN IP
- Cleanup on deletion: Init container removes old records before starting
See DNS Management Guide.
- VPN-only access: All services accessible only via Tailscale VPN (100.64.0.0/10)
- nginx IP restrictions:
allow 100.64.0.0/10; deny all; - No public exposure: Services not accessible from internet
- TLS everywhere: cert-manager + Let's Encrypt for all HTTPS
- External ingress: Only Headscale enrollment endpoint public
- Centralized auth: FreeIPA LDAP for all service logins
- LDAPS encryption: Port 636 for LDAP communication
- RBAC boundaries: Kubernetes namespaces with strict RoleBindings
- Cross-namespace RBAC: Explicit bindings for lifecycle scripts
- Service accounts: Minimal permissions per service
- Kubernetes secrets: Passwords, tokens, keys
- Terraform sensitive vars: Marked
sensitive = true - Never committed:
.env,*.tfvars, credentials gitignored - Vault (future): Centralized secret storage with auto-rotation
See Security Architecture for detailed security design.
- Tool: Terraform (HCL)
- Pattern: Single
terraform applydeploys everything - State: Local state file (S3/MinIO planned)
- Variables:
terraform.tfvarsfor configuration - Modules: None (flat structure for simplicity)
- Pattern: Explicit
depends_onwithout[0]indexing - Count-based: All services toggleable via
var.service_enabled - No circular deps: Fallback IPs prevent chicken-egg scenarios
- Self-healing: Services recover automatically on failures
See Dependency Tree Management.
- ArgoCD planned: Automatic sync from Git
- Current: Manual Terraform apply
- Dashboard sync: Grafana uses git-sync sidecar pattern
- Single-replica: Most services run 1 replica (StatefulSet pattern)
- Local storage: PVCs on Linode block storage
- Thanos storage: Filesystem-backed (not S3/object storage)
- Loki retention: emptyDir (ephemeral)
Vertical Scaling:
- Adjust CPU/memory limits in Terraform variables
- Increase PVC sizes (requires storage class support)
Horizontal Scaling (Future):
- Convert StatefulSets to Deployments where applicable
- Add LoadBalancer services for multi-replica
- Implement object storage for Thanos/Loki
Node Scaling:
- Linode LKE autoscaling enabled
- Node affinity for CPU vs GPU workloads
- Toleration for specialized nodes
See Scaling Guide.
- StatefulSet Pattern - Multi-container deployment pattern
- Dependency Tree - Terraform dependency best practices
- Networking - VPN mesh, DNS, ingress architecture
- Security - TLS, RBAC, secrets management
- Headscale - VPN coordination server
- FreeIPA - Identity management
- Grafana - Monitoring dashboards
- Redmine - Project management
- Deployment - Deploy and redeploy procedures
- Monitoring - Observability stack
- Troubleshooting - Common issues
Navigation: Documentation Index | Home