diff options
author | Mohammed Al Sahaf <msaa1990@gmail.com> | 2020-09-17 19:25:34 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-17 10:25:34 -0600 |
commit | bc453fa6ae36287c90d2bf6941cb686490090df2 (patch) | |
tree | 706bbb9c7a274c3b61b780a7a758407894be8739 /modules | |
parent | e3324aa6de6c6f8f9fc14757025bb15de4801dde (diff) |
reverseproxy: Correct alternate port for active health checks (#3693)
* reverseproxy: construct active health-check transport from scratch (Fixes #3691)
* reverseproxy: do upstream health-check on the correct alternative port
* reverseproxy: add integration test for health-check on alternative port
* reverseproxy: put back the custom transport for health-check http client
* reverseproxy: cleanup health-check integration test
* reverseproxy: fix health-check of unix socket upstreams
* reverseproxy: skip unix socket tests on Windows
* tabs > spaces
Co-authored-by: Francis Lavoie <lavofr@gmail.com>
* make the linter (and @francislavoie) happy
Co-authored-by: Francis Lavoie <lavofr@gmail.com>
* One more lint fix
Co-authored-by: Francis Lavoie <lavofr@gmail.com>
Co-authored-by: Francis Lavoie <lavofr@gmail.com>
Diffstat (limited to 'modules')
-rw-r--r-- | modules/caddyhttp/reverseproxy/healthchecks.go | 33 | ||||
-rw-r--r-- | modules/caddyhttp/reverseproxy/hosts.go | 6 | ||||
-rw-r--r-- | modules/caddyhttp/reverseproxy/httptransport.go | 3 | ||||
-rw-r--r-- | modules/caddyhttp/reverseproxy/reverseproxy.go | 14 |
4 files changed, 35 insertions, 21 deletions
diff --git a/modules/caddyhttp/reverseproxy/healthchecks.go b/modules/caddyhttp/reverseproxy/healthchecks.go index 33cfd82..410b9d4 100644 --- a/modules/caddyhttp/reverseproxy/healthchecks.go +++ b/modules/caddyhttp/reverseproxy/healthchecks.go @@ -153,32 +153,27 @@ func (h *Handler) doActiveHealthCheckForAllHosts() { log.Printf("[PANIC] active health check: %v\n%s", err, debug.Stack()) } }() - networkAddr := upstream.Dial - addr, err := caddy.ParseNetworkAddress(networkAddr) - if err != nil { - h.HealthChecks.Active.logger.Error("bad network address", - zap.String("address", networkAddr), - zap.Error(err), - ) - return - } - if addr.PortRangeSize() != 1 { - h.HealthChecks.Active.logger.Error("multiple addresses (upstream must map to only one address)", - zap.String("address", networkAddr), - ) - return - } - hostAddr := addr.JoinHostPort(0) - if addr.IsUnixNetwork() { + + portStr := strconv.Itoa(upstream.activeHealthCheckPort) + hostAddr := net.JoinHostPort(upstream.networkAddress.Host, portStr) + if upstream.networkAddress.IsUnixNetwork() { // this will be used as the Host portion of a http.Request URL, and // paths to socket files would produce an error when creating URL, // so use a fake Host value instead; unix sockets are usually local hostAddr = "localhost" } - err = h.doActiveHealthCheck(DialInfo{Network: addr.Network, Address: hostAddr}, hostAddr, upstream.Host) + + dialInfo := DialInfo{ + Upstream: upstream, + Network: upstream.networkAddress.Network, + Host: upstream.networkAddress.Host, + Port: portStr, + Address: hostAddr, + } + err := h.doActiveHealthCheck(dialInfo, hostAddr, upstream.Host) if err != nil { h.HealthChecks.Active.logger.Error("active health check failed", - zap.String("address", networkAddr), + zap.String("address", hostAddr), zap.Error(err), ) } diff --git a/modules/caddyhttp/reverseproxy/hosts.go b/modules/caddyhttp/reverseproxy/hosts.go index 5870b75..b7b8c9b 100644 --- a/modules/caddyhttp/reverseproxy/hosts.go +++ b/modules/caddyhttp/reverseproxy/hosts.go @@ -92,8 +92,10 @@ type Upstream struct { // HeaderAffinity string // IPAffinity string - healthCheckPolicy *PassiveHealthChecks - cb CircuitBreaker + networkAddress caddy.NetworkAddress + activeHealthCheckPort int + healthCheckPolicy *PassiveHealthChecks + cb CircuitBreaker } func (u Upstream) String() string { diff --git a/modules/caddyhttp/reverseproxy/httptransport.go b/modules/caddyhttp/reverseproxy/httptransport.go index dce7b9e..7e3bb69 100644 --- a/modules/caddyhttp/reverseproxy/httptransport.go +++ b/modules/caddyhttp/reverseproxy/httptransport.go @@ -182,6 +182,9 @@ func (h *HTTPTransport) NewTransport(ctx caddy.Context) (*http.Transport, error) if dialInfo, ok := GetDialInfo(ctx); ok { network = dialInfo.Network address = dialInfo.Address + if dialInfo.Upstream.networkAddress.IsUnixNetwork() { + address = dialInfo.Host + } } conn, err := dialer.DialContext(ctx, network, address) if err != nil { diff --git a/modules/caddyhttp/reverseproxy/reverseproxy.go b/modules/caddyhttp/reverseproxy/reverseproxy.go index 910fbfc..138a3fc 100644 --- a/modules/caddyhttp/reverseproxy/reverseproxy.go +++ b/modules/caddyhttp/reverseproxy/reverseproxy.go @@ -208,9 +208,13 @@ func (h *Handler) Provision(ctx caddy.Context) error { if err != nil { return err } + if addr.PortRangeSize() != 1 { return fmt.Errorf("multiple addresses (upstream must map to only one address): %v", addr) } + + upstream.networkAddress = addr + // create or get the host representation for this upstream var host Host = new(upstreamHost) existingHost, loaded := hosts.LoadOrStore(upstream.String(), host) @@ -267,6 +271,16 @@ func (h *Handler) Provision(ctx caddy.Context) error { Transport: h.Transport, } + for _, upstream := range h.Upstreams { + // if there's an alternative port for health-check provided in the config, + // then use it, otherwise use the port of upstream. + if h.HealthChecks.Active.Port != 0 { + upstream.activeHealthCheckPort = h.HealthChecks.Active.Port + } else { + upstream.activeHealthCheckPort = int(upstream.networkAddress.StartPort) + } + } + if h.HealthChecks.Active.Interval == 0 { h.HealthChecks.Active.Interval = caddy.Duration(30 * time.Second) } |