Make Traefik health checks label-configurable with Marathon.
For the two existing health check parameters (path and interval), we add support for Marathon labels. Changes in detail: - Extend the Marathon provider and template. - Refactor Server.loadConfig to reduce duplication. - Refactor the healthcheck package slightly to accommodate the changes and allow extending by future parameters. - Update documentation.
This commit is contained in:
parent
441d5442a1
commit
d57f83c31c
8 changed files with 371 additions and 45 deletions
|
@ -12,6 +12,9 @@ import (
|
|||
"github.com/vulcand/oxy/roundrobin"
|
||||
)
|
||||
|
||||
// DefaultInterval is the default health check interval.
|
||||
const DefaultInterval = 30 * time.Second
|
||||
|
||||
var singleton *HealthCheck
|
||||
var once sync.Once
|
||||
|
||||
|
@ -23,16 +26,19 @@ func GetHealthCheck() *HealthCheck {
|
|||
return singleton
|
||||
}
|
||||
|
||||
// BackendHealthCheck HealthCheck configuration for a backend
|
||||
type BackendHealthCheck struct {
|
||||
Path string
|
||||
Interval time.Duration
|
||||
DisabledURLs []*url.URL
|
||||
requestTimeout time.Duration
|
||||
lb loadBalancer
|
||||
// Options are the public health check options.
|
||||
type Options struct {
|
||||
Path string
|
||||
Interval time.Duration
|
||||
LB LoadBalancer
|
||||
}
|
||||
|
||||
var launch = false
|
||||
// BackendHealthCheck HealthCheck configuration for a backend
|
||||
type BackendHealthCheck struct {
|
||||
Options
|
||||
disabledURLs []*url.URL
|
||||
requestTimeout time.Duration
|
||||
}
|
||||
|
||||
//HealthCheck struct
|
||||
type HealthCheck struct {
|
||||
|
@ -40,7 +46,8 @@ type HealthCheck struct {
|
|||
cancel context.CancelFunc
|
||||
}
|
||||
|
||||
type loadBalancer interface {
|
||||
// LoadBalancer includes functionality for load-balancing management.
|
||||
type LoadBalancer interface {
|
||||
RemoveServer(u *url.URL) error
|
||||
UpsertServer(u *url.URL, options ...roundrobin.ServerOption) error
|
||||
Servers() []*url.URL
|
||||
|
@ -53,12 +60,10 @@ func newHealthCheck() *HealthCheck {
|
|||
}
|
||||
|
||||
// NewBackendHealthCheck Instantiate a new BackendHealthCheck
|
||||
func NewBackendHealthCheck(Path string, interval time.Duration, lb loadBalancer) *BackendHealthCheck {
|
||||
func NewBackendHealthCheck(options Options) *BackendHealthCheck {
|
||||
return &BackendHealthCheck{
|
||||
Path: Path,
|
||||
Interval: interval,
|
||||
Options: options,
|
||||
requestTimeout: 5 * time.Second,
|
||||
lb: lb,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,24 +103,24 @@ func (hc *HealthCheck) execute(ctx context.Context, backendID string, backend *B
|
|||
}
|
||||
|
||||
func checkBackend(currentBackend *BackendHealthCheck) {
|
||||
enabledURLs := currentBackend.lb.Servers()
|
||||
enabledURLs := currentBackend.LB.Servers()
|
||||
var newDisabledURLs []*url.URL
|
||||
for _, url := range currentBackend.DisabledURLs {
|
||||
for _, url := range currentBackend.disabledURLs {
|
||||
if checkHealth(url, currentBackend) {
|
||||
log.Debugf("HealthCheck is up [%s]: Upsert in server list", url.String())
|
||||
currentBackend.lb.UpsertServer(url, roundrobin.Weight(1))
|
||||
currentBackend.LB.UpsertServer(url, roundrobin.Weight(1))
|
||||
} else {
|
||||
log.Warnf("HealthCheck is still failing [%s]", url.String())
|
||||
newDisabledURLs = append(newDisabledURLs, url)
|
||||
}
|
||||
}
|
||||
currentBackend.DisabledURLs = newDisabledURLs
|
||||
currentBackend.disabledURLs = newDisabledURLs
|
||||
|
||||
for _, url := range enabledURLs {
|
||||
if !checkHealth(url, currentBackend) {
|
||||
log.Warnf("HealthCheck has failed [%s]: Remove from server list", url.String())
|
||||
currentBackend.lb.RemoveServer(url)
|
||||
currentBackend.DisabledURLs = append(currentBackend.DisabledURLs, url)
|
||||
currentBackend.LB.RemoveServer(url)
|
||||
currentBackend.disabledURLs = append(currentBackend.disabledURLs, url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,12 +148,16 @@ func TestSetBackendsConfiguration(t *testing.T) {
|
|||
defer ts.Close()
|
||||
|
||||
lb := &testLoadBalancer{RWMutex: &sync.RWMutex{}}
|
||||
backend := NewBackendHealthCheck("/path", healthCheckInterval, lb)
|
||||
backend := NewBackendHealthCheck(Options{
|
||||
Path: "/path",
|
||||
Interval: healthCheckInterval,
|
||||
LB: lb,
|
||||
})
|
||||
serverURL := MustParseURL(ts.URL)
|
||||
if test.startHealthy {
|
||||
lb.servers = append(lb.servers, serverURL)
|
||||
} else {
|
||||
backend.DisabledURLs = append(backend.DisabledURLs, serverURL)
|
||||
backend.disabledURLs = append(backend.disabledURLs, serverURL)
|
||||
}
|
||||
|
||||
healthCheck := HealthCheck{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue