Gateway-Pool: Load-Balancing aktivieren
Load-Balancing-Mode im Detail
Aktivierung
Eine Route nutzt LB nur, wenn alle drei Bedingungen stimmen:
route.target_pool_idgesetzt (NICHTtarget_peer_id)- Pool-
mode = 'load_balancing' - Pool-
lb_policy ∈ {round_robin, least_conn, ip_hash}
Caddy-Konfiguration (HTTP)
Beim Build-Cycle ruft caddyConfig.resolveRouteUpstreams gatewayPool.resolveActivePeers(snapshot) auf — die gibt alle alive Pool-Member zurück:
"reverse_proxy": {
"upstreams": [
{ "dial": "10.8.0.2:18080" },
{ "dial": "10.8.0.8:18080" }
],
"load_balancing": {
"selection_policy": { "policy": "round_robin" }
},
"health_checks": {
"passive": {
"fail_duration": "30s",
"max_fails": 3,
"unhealthy_status": [500, 502, 503, 504]
}
}
}
LB-Policies
| Policy | Verhalten | Wann sinnvoll |
|---|---|---|
round_robin |
Reihum durch die Upstream-Liste | Symmetrische Last, identische Member |
least_conn |
Member mit wenigsten aktiven Connections | Lange Streams (Jellyfin-Streaming, Backups) |
ip_hash |
Hash über Client-IP → fester Member | Session-Affinität ohne Cookies (Legacy-Apps) |
Trusted Proxies (für ip_hash hinter CDN/LB)
Wenn GateControl hinter einer privaten LB oder einem CDN steht, sieht der Server-Caddy als Remote-IP nur die Proxy-IP — ip_hash wäre dann wirkungslos (alle Requests gleichen Bucket). Workaround ist im srv0-HTTP-Server eingebaut:
{
"trusted_proxies": {
"source": "static",
"ranges": [
"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16",
"100.64.0.0/10", "fd00::/8", "::1/128", "127.0.0.0/8"
]
},
"client_ip_headers": ["X-Forwarded-For"]
}
X-Forwarded-For wird nur geehrt wenn die Connection aus einer der gelisteten Ranges kommt. Direkt aus dem Internet kommende Clients können XFF nicht spoofen, weil ihre Source-IP nicht in der Trust-Liste steht.
Passive Health-Checks
Zusätzlich zum gatewayHealth-Watchdog (alle 30 s) prüft Caddy selbst passiv:
- Schickt eine Anfrage an Member X
- X antwortet mit 5xx-Status (oder Connection-Fail)
- Nach
max_fails=3solchen Fehlern wird X fürfail_duration=30saus der Rotation genommen - Nach 30 s wieder probieren
Damit greift Circuit-Breaking sekündlich, statt erst nach dem 90s-gateway_down_threshold der globalen Health-Logik.
L4-Load-Balancing (TCP/UDP)
Funktioniert genauso für L4-Routen — caddy-l4's proxy-handler bekommt mehrere upstreams[] plus load_balancing.selection_policy:
{
"handler": "proxy",
"upstreams": [
{ "dial": ["10.8.0.2:13389"] },
{ "dial": ["10.8.0.8:13389"] }
],
"load_balancing": {
"selection_policy": { "policy": "round_robin" }
},
"health_checks": {
"passive": { "fail_duration": "30s", "max_fails": 3 }
}
}
L4-Routen müssen route_type='l4' sein und Pool-gebunden über target_pool_id.