Architecture Overview¶
Overview¶
The haproxy-template-ingress-controller is a Kubernetes operator that manages HAProxy load balancer configurations through template-driven configuration generation. The system continuously monitors Kubernetes resources and translates them into HAProxy configuration files using a powerful templating engine.
Core Capabilities:
- Template-Driven Configuration: Uses a feature-rich template engine to generate HAProxy configurations from Kubernetes resources
- Dynamic Resource Watching: Monitors user-defined Kubernetes resource types (Ingress, Service, ConfigMap, custom CRDs)
- Validation-First Deployment: All configurations are parsed and validated before deployment to production instances
- Zero-Reload Optimization: Leverages HAProxy Runtime API for configuration changes that don't require process reloads
- Structured Comparison: Intelligently compares configurations to minimize deployments and maximize use of runtime operations
Operational Model:
The controller operates through event-driven coordination where components communicate exclusively via EventBus pub/sub:
- Resource Watchers monitor Kubernetes resources and publish change events to EventBus
- Reconciler subscribes to change events, debounces rapid changes, and publishes reconciliation trigger events
- Renderer subscribes to reconciliation trigger events, queries indexed resources from k8s stores, renders templates using pkg/templating, and publishes rendered configuration events
- HAProxyValidator subscribes to rendered configuration events, performs two-phase validation (client-native parser + haproxy binary via pkg/dataplane), and publishes validation result events
- DeploymentScheduler subscribes to validation events, enforces rate limiting, queues deployments if needed, and publishes deployment scheduled events
- Deployer subscribes to deployment scheduled events, executes parallel deployments to all HAProxy endpoints using pkg/dataplane, and publishes deployment completion events
- Executor subscribes to key lifecycle events for observability and publishes reconciliation completion events
- EventBus coordinates all component interactions - no direct component-to-component function calls
- All components publish completion/failure events for metrics, logging, and further coordination
Key Design Principles:
- Fail-Safe: Invalid configurations are rejected before reaching production
- Performance: Debouncing prevents rapid successive renders, indexing enables fast lookups
- Observability: Comprehensive metrics (Prometheus) and distributed tracing (OpenTelemetry)
- Flexibility: Templates provide complete control over HAProxy configuration, no annotation limitations
Component Diagrams¶
High-Level System Components¶
graph TB
subgraph "Kubernetes Cluster"
K8S[Kubernetes API Server]
subgraph "Controller Pod"
CTRL[Controller<br/>- Resource Watching<br/>- Template Rendering<br/>- Config Validation<br/>- Deployment Orchestration]
VAL[Validation Module<br/>- client-native Parser<br/>- haproxy Binary Check]
end
subgraph "HAProxy Pod 1"
HAP1[HAProxy<br/>Load Balancer]
DP1[Dataplane API<br/>:5555]
end
subgraph "HAProxy Pod 2"
HAP2[HAProxy<br/>Load Balancer]
DP2[Dataplane API<br/>:5555]
end
CONFIG[ConfigMap<br/>Controller Configuration]
RES[Resources<br/>Ingress, Service, etc.]
end
K8S -->|Watch Events| CTRL
CONFIG -->|Read Config| CTRL
RES -->|Watch Events| CTRL
CTRL -->|Render & Validate| VAL
VAL -->|Deploy Config| DP1
VAL -->|Deploy Config| DP2
DP1 -->|Configure| HAP1
DP2 -->|Configure| HAP2
HAP1 -->|Stats/Health| DP1
HAP2 -->|Stats/Health| DP2
style CTRL fill:#4CAF50
style VAL fill:#2196F3
style HAP1 fill:#FF9800
style HAP2 fill:#FF9800
Component Descriptions:
- Controller: Main controller process that watches Kubernetes resources, renders templates, and orchestrates configuration deployment
- Validation Module: Integrated validation using haproxytech/client-native library for parsing and haproxy binary for configuration checks
- Dataplane API: HAProxy's management interface for receiving configuration updates and performing runtime operations
- HAProxy: Production load balancer instances that serve traffic
Controller Internal Architecture¶
graph TB
subgraph ext["External Systems"]
K8S["Kubernetes API<br/>(Resource Events)"]
HAP["HAProxy Instances<br/>(Dataplane API)"]
end
subgraph controller["Controller Process - Event-Driven Architecture"]
direction TB
EB["EventBus<br/>Central Pub/Sub Coordinator<br/>~50 Event Types"]
subgraph watchers["Resource Watchers"]
direction LR
CW["Config<br/>Watcher"]
RW["Resource<br/>Watcher"]
end
subgraph reconciliation["Reconciliation Components"]
direction LR
RC["Reconciler<br/>(Debouncer)"]
EX["Executor<br/>(Observability)"]
end
subgraph pipeline["Event-Driven Pipeline"]
direction LR
REND["Renderer"]
VAL["HAProxy<br/>Validator"]
SCHED["Deployment<br/>Scheduler"]
DEPL["Deployer"]
end
subgraph support["Support Components"]
direction LR
DISC["Discovery"]
METR["Metrics"]
COMM["Commentator"]
end
CW & RW -->|Publish| EB
EB -->|Subscribe| RC
RC -->|Publish| EB
EB -->|Subscribe| REND
REND -->|Publish| EB
EB -->|Subscribe| VAL
VAL -->|Publish| EB
EB -->|Subscribe| SCHED
SCHED -->|Publish| EB
EB -->|Subscribe| DEPL
DEPL -->|Publish| EB
EB -->|Subscribe| EX & DISC & METR & COMM
EX & DISC -->|Publish| EB
end
K8S -->|Watch| RW
DEPL -->|Deploy| HAP
style EB fill:#FFC107,stroke:#F57C00,stroke-width:4px
style watchers fill:#E3F2FD
style reconciliation fill:#F3E5F5
style pipeline fill:#C8E6C9
style support fill:#FFF9C4
style ext fill:#F5F5F5
Event-Driven Data Flow:
- Config/Resource Watchers receive Kubernetes changes and publish events to EventBus
- Reconciler subscribes to change events, debounces rapid changes (default 500ms), filters initial sync events, and publishes ReconciliationTriggeredEvent
- Renderer subscribes to ReconciliationTriggeredEvent, queries k8s stores for resources, renders templates via pkg/templating pure library, publishes TemplateRenderedEvent
- HAProxyValidator subscribes to TemplateRenderedEvent, validates using pkg/dataplane pure validation functions (syntax + semantics), publishes ValidationCompletedEvent or ValidationFailedEvent
- DeploymentScheduler subscribes to ValidationCompletedEvent and HAProxyPodsDiscoveredEvent, enforces rate limiting (default 2s minimum interval), implements "latest wins" queueing, publishes DeploymentScheduledEvent
- Deployer subscribes to DeploymentScheduledEvent, executes parallel deployments to all HAProxy endpoints using pkg/dataplane client, publishes InstanceDeployedEvent and DeploymentCompletedEvent
- Executor subscribes to key lifecycle events for observability, publishes ReconciliationStartedEvent and ReconciliationCompletedEvent with duration metrics
- Support Components (Discovery, Metrics, Commentator) subscribe to relevant events for their specific purposes
- All components publish completion/failure events that flow back through EventBus for metrics, logging, and coordination
Key Architecture Properties:
- EventBus is the single coordination mechanism - zero direct component-to-component function calls
- Event-Driven Components (Renderer, Validator, Scheduler, Deployer) are wrappers around pure libraries (pkg/templating, pkg/dataplane, pkg/k8s)
- Pure Libraries (pkg/templating, pkg/dataplane, pkg/k8s) contain testable business logic with no event dependencies
- Event Adapters translate between EventBus pub/sub and pure library function calls
- Extensibility - new features can subscribe to existing events without modifying existing code
- Independent Testing - pure libraries can be unit tested, event adapters can be integration tested
Validation Flow¶
graph TD
RENDER[Rendered Configuration]
PARSE[client-native Parser<br/>Syntax & Structure Check]
BIN[haproxy Binary<br/>Semantic Validation]
DEPLOY[Deploy to Production]
ERROR[Reject & Log Error]
RENDER --> PARSE
PARSE -->|Valid Syntax| BIN
PARSE -->|Invalid| ERROR
BIN -->|Valid Semantics| DEPLOY
BIN -->|Invalid| ERROR
style PARSE fill:#2196F3
style BIN fill:#4CAF50
style DEPLOY fill:#FF9800
style ERROR fill:#F44336
Validation Strategy:
The two-phase validation eliminates the need for a separate validation sidecar container:
- Phase 1 - Syntax Parsing: client-native library parses configuration structure and validates against HAProxy config grammar
- Phase 2 - Semantic Validation: haproxy binary (
haproxy -c -f config) performs full semantic validation including resource availability checks. Writes auxiliary files to actual HAProxy directories (with mutex locking) to match Dataplane API validation behavior exactly.
This approach provides the same validation guarantees as running a full HAProxy instance while being more lightweight and faster.