infra: add haproxy to as central reverse proxy
- add haproxy to work as central reverse proxy - based on the domain, it can route to either docker or k8s proxy
This commit is contained in:
93
infra/haproxy/README.md
Normal file
93
infra/haproxy/README.md
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
# HAProxy Configuration
|
||||||
|
|
||||||
|
## Rationale
|
||||||
|
|
||||||
|
This HAProxy instance serves as the primary entry point for the
|
||||||
|
homeserver infrastructure. It acts as a unified reverse proxy that
|
||||||
|
allows services from both Docker and Kubernetes environments to be
|
||||||
|
exposed behind a single, cohesive frontend. By using HAProxy with
|
||||||
|
SNI-based routing, the following can be achieved:
|
||||||
|
|
||||||
|
- **Centralize SSL/TLS termination** across multiple backend
|
||||||
|
environments
|
||||||
|
- **Route traffic dynamically** based on the requested domain to either
|
||||||
|
Docker or Kubernetes services
|
||||||
|
- **Maintain a single point of entry** for external clients while
|
||||||
|
distributing load across heterogeneous backends
|
||||||
|
- **Simplify certificate management** by terminating SSL at one
|
||||||
|
location
|
||||||
|
- **Note**: TLS termination and certificate management are not handled in this
|
||||||
|
setup; SSL/TLS traffic is passed through to backend services
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
HAProxy is used as a reverse proxy and load balancer to route incoming
|
||||||
|
HTTPS traffic to the appropriate backend services in the homeserver
|
||||||
|
setup.
|
||||||
|
|
||||||
|
This HAProxy configuration implements SNI (Server Name Indication)
|
||||||
|
based routing to direct traffic to either the Kubernetes cluster or
|
||||||
|
Docker backend based on the requested domain.
|
||||||
|
|
||||||
|
## Global Settings
|
||||||
|
|
||||||
|
- **Logging**: Logs are written to syslog at `/dev/log` (local0) and
|
||||||
|
localhost (local2)
|
||||||
|
- **Admin Socket**: Accessible at `/run/haproxy/admin.sock` for
|
||||||
|
statistics and administration
|
||||||
|
- **Max Connections**: 10,000 concurrent connections
|
||||||
|
- **User/Group**: Runs as `haproxy` user and group
|
||||||
|
|
||||||
|
## Default Timeout Settings
|
||||||
|
|
||||||
|
- **Connect Timeout**: 5 seconds
|
||||||
|
- **Client Timeout**: 3600 seconds (1 hour)
|
||||||
|
- **Server Timeout**: 3600 seconds (1 hour)
|
||||||
|
|
||||||
|
## Frontend Configuration
|
||||||
|
|
||||||
|
The HAProxy frontend listens on port 443 (HTTPS) and TCP mode is used
|
||||||
|
for SSL/TLS traffic.
|
||||||
|
|
||||||
|
### SNI-Based Routing
|
||||||
|
|
||||||
|
Traffic is routed based on the SSL SNI (Server Name Indication)
|
||||||
|
hostname:
|
||||||
|
|
||||||
|
**Kubernetes Backend** (`k8s_backend`):
|
||||||
|
|
||||||
|
- Domains ending with `.mydomain.com`
|
||||||
|
|
||||||
|
**Docker Backend** (`docker_backend`):
|
||||||
|
|
||||||
|
- Domains ending with `.docker.mydomain.com`
|
||||||
|
|
||||||
|
## Backend Configuration
|
||||||
|
|
||||||
|
### Kubernetes Backend
|
||||||
|
|
||||||
|
- **Server**: `k8s-ingress` at `192.168.1.141:443`
|
||||||
|
- **Mode**: TCP
|
||||||
|
- **Health Checks**: Enabled (10s interval, 3 failures to mark
|
||||||
|
down, 2 successes to mark up)
|
||||||
|
|
||||||
|
### Docker Backend
|
||||||
|
|
||||||
|
- **Server**: `docker-proxy` at `192.168.1.135:443`
|
||||||
|
- **Mode**: TCP
|
||||||
|
- **Health Checks**: Enabled (10s interval, 3 failures to mark
|
||||||
|
down, 2 successes to mark up)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
The SSL hello packet is automatically inspected to determine the SNI
|
||||||
|
hostname, and the connection is routed to the appropriate backend
|
||||||
|
service.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- TCP mode is used to preserve SSL/TLS encryption end-to-end
|
||||||
|
- Domain patterns marked with `# example` are placeholders and should
|
||||||
|
be customized for the setup
|
||||||
|
- The TCP routing logs can be monitored via journald for debugging and
|
||||||
|
verification purposes. `journalctl -u haproxy -f`
|
||||||
42
infra/haproxy/haproxy.cfg
Normal file
42
infra/haproxy/haproxy.cfg
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
global
|
||||||
|
log /dev/log local0
|
||||||
|
log 127.0.0.1 local2
|
||||||
|
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
|
||||||
|
stats timeout 30s
|
||||||
|
user haproxy
|
||||||
|
group haproxy
|
||||||
|
daemon
|
||||||
|
maxconn 10000
|
||||||
|
|
||||||
|
defaults
|
||||||
|
log global
|
||||||
|
mode tcp
|
||||||
|
option dontlognull
|
||||||
|
timeout connect 5s
|
||||||
|
timeout client 3600s
|
||||||
|
timeout server 3600s
|
||||||
|
|
||||||
|
frontend https-in
|
||||||
|
bind *:443
|
||||||
|
mode tcp
|
||||||
|
option tcplog
|
||||||
|
|
||||||
|
tcp-request inspect-delay 5s
|
||||||
|
tcp-request content accept if { req_ssl_hello_type 1 }
|
||||||
|
|
||||||
|
acl is_docker req_ssl_sni -i -m end .docker.mydomain.com
|
||||||
|
acl is_k8s req_ssl_sni -i -m end .mydomain.com
|
||||||
|
|
||||||
|
# More specific wins → put docker rule first
|
||||||
|
use_backend docker_backend if is_docker
|
||||||
|
use_backend k8s_backend if is_k8s
|
||||||
|
|
||||||
|
default_backend k8s_backend
|
||||||
|
|
||||||
|
backend k8s_backend
|
||||||
|
mode tcp
|
||||||
|
server k8s-ingress 192.168.1.141:443 check inter 10s fall 3 rise 2
|
||||||
|
|
||||||
|
backend docker_backend
|
||||||
|
mode tcp
|
||||||
|
server docker-proxy 192.168.1.135:443 check inter 10s fall 3 rise 2
|
||||||
@@ -3,28 +3,28 @@ pm_ssh_public_key_path = "/home/taqi/.ssh/homeserver.pub"
|
|||||||
pm_ssh_private_key_path = "/home/taqi/.ssh/homeserver"
|
pm_ssh_private_key_path = "/home/taqi/.ssh/homeserver"
|
||||||
|
|
||||||
vms = [
|
vms = [
|
||||||
{
|
# {
|
||||||
name = "vm6"
|
# name = "vm6"
|
||||||
node_name = "homeserver1"
|
# node_name = "homeserver1"
|
||||||
vm_id = 105
|
# vm_id = 105
|
||||||
ip_address = "192.168.1.151/24"
|
# ip_address = "192.168.1.151/24"
|
||||||
gateway = "192.168.1.1"
|
# gateway = "192.168.1.1"
|
||||||
dns_servers = ["1.1.1.1"]
|
# dns_servers = ["1.1.1.1"]
|
||||||
cores = 2
|
# cores = 2
|
||||||
memory = 4096
|
# memory = 4096
|
||||||
disk_size = 20
|
# disk_size = 20
|
||||||
},
|
# },
|
||||||
{
|
# {
|
||||||
name = "vm7"
|
# name = "vm7"
|
||||||
node_name = "homeserver2"
|
# node_name = "homeserver2"
|
||||||
vm_id = 205
|
# vm_id = 205
|
||||||
ip_address = "192.168.1.161/24"
|
# ip_address = "192.168.1.161/24"
|
||||||
gateway = "192.168.1.1"
|
# gateway = "192.168.1.1"
|
||||||
dns_servers = ["1.1.1.1"]
|
# dns_servers = ["1.1.1.1"]
|
||||||
cores = 2
|
# cores = 2
|
||||||
memory = 4096
|
# memory = 4096
|
||||||
disk_size = 20
|
# disk_size = 20
|
||||||
},
|
# },
|
||||||
{
|
{
|
||||||
name = "vm8"
|
name = "vm8"
|
||||||
node_name = "homeserver3"
|
node_name = "homeserver3"
|
||||||
@@ -57,6 +57,17 @@ vms = [
|
|||||||
cores = 2
|
cores = 2
|
||||||
memory = 2048
|
memory = 2048
|
||||||
disk_size = 20
|
disk_size = 20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name = "vm11"
|
||||||
|
node_name = "homeserver3"
|
||||||
|
vm_id = 304
|
||||||
|
ip_address = "192.168.1.175/24"
|
||||||
|
gateway = "192.168.1.1"
|
||||||
|
dns_servers = ["1.1.1.1"]
|
||||||
|
cores = 2
|
||||||
|
memory = 2048
|
||||||
|
disk_size = 20
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user