Add health check label to ECS
This commit is contained in:
parent
4b91204686
commit
6d2f4a0813
7 changed files with 111 additions and 26 deletions
|
@ -117,7 +117,7 @@ func templatesDockerTmpl() (*asset, error) {
|
|||
return a, nil
|
||||
}
|
||||
|
||||
var _templatesEcsTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x53\x4d\x6f\xdb\x30\x0c\xbd\xe7\x57\x10\x46\x8e\xad\x7a\x2f\x90\xc3\xba\x0f\x74\x40\x37\x04\xeb\x61\x87\xa0\x07\xc5\x66\x6c\x21\xae\x54\x88\xf4\xb6\x40\xd0\x7f\x1f\x64\x49\x96\xbd\x64\x40\xb6\x93\x25\xf2\x3d\x8a\xef\x91\xde\xed\x65\x7d\x44\xdd\xd0\x8b\x73\x56\xea\x16\x61\x4d\x68\x7f\xa8\x1a\xbf\xca\x57\xbc\x81\xb5\xd2\xc4\x52\xd7\x48\x70\xbf\x01\xf1\x1c\x73\xe4\xfd\x0a\x60\xe2\x8a\x74\xb8\x75\x6e\x41\x07\xef\x45\x6f\x64\xb3\x97\x7d\x28\x61\x5f\x56\x00\x00\xaf\xc8\x9d\x69\x60\x03\x95\x73\xd0\x22\x3f\x19\xd9\x3c\x24\xc4\x97\x98\x2b\xaf\x7a\x5f\x8d\x24\x62\x55\x1f\x4f\xb0\x81\x73\xce\x73\x4c\xcd\x39\x23\xc5\x39\x75\x80\x4e\xd2\x98\x57\x1a\x89\x9e\xe4\x1e\xfb\x05\x10\x46\xe4\x3f\x0b\x11\x34\xd5\x8c\x9a\x00\x6a\x63\x8e\x2a\x82\x47\x65\x2d\x72\x79\xf8\x7d\x49\x9e\x4b\x73\x0e\x75\xe3\xfd\x6a\x15\x8e\x69\x06\x4a\x37\xf8\x2b\xb8\x1f\x5c\x3f\x53\x76\xb9\x5f\x25\x72\xab\xa1\x73\xb4\x94\xbe\xcb\x64\xbc\x7c\xfe\x00\xde\xe7\xd6\x07\xdb\x97\x69\x6c\xad\x61\x53\x9b\x60\x13\x78\x7f\x7f\x77\x17\xc3\x8f\x86\x38\x85\x12\xce\xd8\x14\xa8\x52\x99\x9f\xa8\xda\x8e\xa7\x11\x7d\x8f\xd7\xb5\x1a\x9b\xce\x22\x27\xb1\xbb\x83\x35\x9a\xff\x73\xf3\x32\xe3\xa0\x7a\x46\xfb\x29\x57\xba\xe0\xd4\xf4\x8a\xc8\xa7\x0b\xb3\xcd\x46\x24\x37\x83\x19\x7f\x5f\x84\x2c\xf7\x4d\x12\x05\x57\x1e\x51\x36\x68\x27\xd9\xdb\x65\x58\xa4\x46\x00\xde\xac\x32\x56\x71\xd9\xe1\x6d\x0e\x14\x0c\x6a\xb6\xa7\xad\x51\x9a\x09\x36\xb0\xcb\x32\x03\xfa\xe3\x2c\x55\x08\x95\x73\xc2\xfb\xea\x66\xbe\x48\x45\x0d\xa9\xfa\xdd\xc0\xdd\xbc\x54\x8b\xfc\x30\xc5\xaf\xa9\x73\x9d\x83\xc2\x9a\x81\x91\xe2\xe7\xf6\x0a\xab\xed\xd0\x97\x1f\x25\x0f\xf0\x5b\x08\x8a\x68\xf1\x1f\x0b\xf3\x3b\x00\x00\xff\xff\x86\x8c\x3e\xf5\xa8\x04\x00\x00")
|
||||
var _templatesEcsTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x54\x4d\x6f\xdb\x30\x0c\xbd\xe7\x57\x10\x46\x8e\xad\x7a\x2f\x90\xc3\xda\x6d\x48\x81\x6e\x30\xd6\xc3\x0e\x41\x0f\x8a\xcd\xd8\x42\x5c\xa9\x90\x98\x6e\x85\xa0\xff\x3e\xc8\xfa\xb2\x17\x0f\xc8\x7a\xb2\x4c\xf2\x91\xef\x51\xcf\xde\xed\x79\x73\x44\xd9\x9a\x67\x6b\x35\x97\x1d\xc2\xda\xa0\x7e\x13\x0d\x7e\xe7\x2f\x78\x05\x6b\x21\x0d\x71\xd9\xa0\x81\xdb\x0d\xb0\xa7\x90\x33\xce\xad\x00\x32\x96\xc5\xc3\xb5\xb5\x33\x38\x38\xc7\x06\xc5\xdb\x3d\x1f\x7c\x0b\xfd\xbc\x02\x00\x78\x41\xea\x55\x0b\x1b\xa8\xac\x85\x0e\xe9\x51\xf1\xf6\x2e\x56\x7c\x0b\xb9\x32\xd5\xb9\x6a\x04\x19\x12\xcd\xf1\x1d\x36\x70\x8e\x79\x0a\xa9\x29\x66\x84\x58\x2b\x0e\xd0\x73\x33\xe6\x85\x44\x63\x1e\xf9\x1e\x87\x59\x21\x8c\x95\xff\x2d\x84\x99\xdc\x33\x68\x02\x68\x94\x3a\x8a\x50\x3c\x2a\xeb\x90\xca\xe0\xfb\x92\x3c\x97\x66\x2d\xca\x36\x73\x86\x40\x7a\x8b\x7c\xa0\xfe\xbe\xc7\xe6\x38\xb2\x36\xd3\x9b\x88\xc5\x17\xd1\xee\xc7\x46\x8d\x6f\x94\xa8\xbe\x72\xea\x33\xc9\xc9\xa0\xda\xc7\x67\x63\xaa\x88\x10\x92\x50\xbf\xf1\x61\x09\xf5\x90\x72\x0b\xc8\x24\x6d\xe5\x8f\xd1\x5e\x42\xb6\xf8\xdb\x1b\xcb\x1b\xea\xec\xd2\x96\x35\x09\x96\xe4\x78\x75\xa8\x4d\x7c\xce\x93\xe1\xe5\xe1\x33\x38\x97\xa4\x9e\xf4\x50\x8c\x56\x6b\x45\xaa\x51\x9e\x29\x38\x77\x7b\x73\x13\xc2\x5b\x65\x28\x86\x62\x9d\xd2\x31\x90\xf4\xff\x42\xd1\xf5\x94\xdd\xf7\x33\xbc\xae\xc5\x48\x3a\x89\xcc\x62\x77\x07\xad\x24\x7d\xf0\xa3\x4a\x88\x83\x18\x08\xf5\xd7\xd4\x69\x61\x53\x79\x0a\x4b\xa7\x85\xfb\x4f\x8b\x88\xdb\xf4\xcb\xf8\xb7\x59\xaa\x6c\x10\x63\xfc\x56\xb6\xc8\x5b\xd4\x59\x76\x3d\x0f\xb3\x48\x04\xe0\x55\x0b\xa5\x05\x95\xcf\xb3\x4e\x81\x52\x83\x92\xf4\x7b\xad\x84\x24\x03\x1b\xd8\x25\x99\xbe\xfa\xcb\x24\x55\x00\x95\xb5\xcc\xb9\xea\x6a\x6a\xa4\xa2\xc6\x88\xe6\xd3\x69\xb4\x71\x6e\xd5\x21\xdd\xe5\xf8\x25\x7d\x2e\xdb\x20\xd3\xea\x44\x68\xc2\xe3\xfa\x82\x55\xeb\xd3\x50\xfe\x01\xe9\x02\x7f\xf8\x20\x0b\x2b\xfe\xcb\x30\x7f\x02\x00\x00\xff\xff\xca\x00\x13\x83\x83\x05\x00\x00")
|
||||
|
||||
func templatesEcsTmplBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
|
@ -132,7 +132,7 @@ func templatesEcsTmpl() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "templates/ecs.tmpl", size: 1192, mode: os.FileMode(436), modTime: time.Unix(1509884496, 0)}
|
||||
info := bindataFileInfo{name: "templates/ecs.tmpl", size: 1411, mode: os.FileMode(436), modTime: time.Unix(1509884496, 0)}
|
||||
a := &asset{bytes: bytes, info: info}
|
||||
return a, nil
|
||||
}
|
||||
|
@ -330,15 +330,15 @@ func AssetNames() []string {
|
|||
// _bindata is a table, holding each asset generator, mapped to its name.
|
||||
var _bindata = map[string]func() (*asset, error){
|
||||
"templates/consul_catalog.tmpl": templatesConsul_catalogTmpl,
|
||||
"templates/docker.tmpl": templatesDockerTmpl,
|
||||
"templates/ecs.tmpl": templatesEcsTmpl,
|
||||
"templates/eureka.tmpl": templatesEurekaTmpl,
|
||||
"templates/kubernetes.tmpl": templatesKubernetesTmpl,
|
||||
"templates/kv.tmpl": templatesKvTmpl,
|
||||
"templates/marathon.tmpl": templatesMarathonTmpl,
|
||||
"templates/mesos.tmpl": templatesMesosTmpl,
|
||||
"templates/notFound.tmpl": templatesNotfoundTmpl,
|
||||
"templates/rancher.tmpl": templatesRancherTmpl,
|
||||
"templates/docker.tmpl": templatesDockerTmpl,
|
||||
"templates/ecs.tmpl": templatesEcsTmpl,
|
||||
"templates/eureka.tmpl": templatesEurekaTmpl,
|
||||
"templates/kubernetes.tmpl": templatesKubernetesTmpl,
|
||||
"templates/kv.tmpl": templatesKvTmpl,
|
||||
"templates/marathon.tmpl": templatesMarathonTmpl,
|
||||
"templates/mesos.tmpl": templatesMesosTmpl,
|
||||
"templates/notFound.tmpl": templatesNotfoundTmpl,
|
||||
"templates/rancher.tmpl": templatesRancherTmpl,
|
||||
}
|
||||
|
||||
// AssetDir returns the file names below a certain
|
||||
|
@ -380,19 +380,18 @@ type bintree struct {
|
|||
Func func() (*asset, error)
|
||||
Children map[string]*bintree
|
||||
}
|
||||
|
||||
var _bintree = &bintree{nil, map[string]*bintree{
|
||||
"templates": &bintree{nil, map[string]*bintree{
|
||||
"consul_catalog.tmpl": &bintree{templatesConsul_catalogTmpl, map[string]*bintree{}},
|
||||
"docker.tmpl": &bintree{templatesDockerTmpl, map[string]*bintree{}},
|
||||
"ecs.tmpl": &bintree{templatesEcsTmpl, map[string]*bintree{}},
|
||||
"eureka.tmpl": &bintree{templatesEurekaTmpl, map[string]*bintree{}},
|
||||
"kubernetes.tmpl": &bintree{templatesKubernetesTmpl, map[string]*bintree{}},
|
||||
"kv.tmpl": &bintree{templatesKvTmpl, map[string]*bintree{}},
|
||||
"marathon.tmpl": &bintree{templatesMarathonTmpl, map[string]*bintree{}},
|
||||
"mesos.tmpl": &bintree{templatesMesosTmpl, map[string]*bintree{}},
|
||||
"notFound.tmpl": &bintree{templatesNotfoundTmpl, map[string]*bintree{}},
|
||||
"rancher.tmpl": &bintree{templatesRancherTmpl, map[string]*bintree{}},
|
||||
"docker.tmpl": &bintree{templatesDockerTmpl, map[string]*bintree{}},
|
||||
"ecs.tmpl": &bintree{templatesEcsTmpl, map[string]*bintree{}},
|
||||
"eureka.tmpl": &bintree{templatesEurekaTmpl, map[string]*bintree{}},
|
||||
"kubernetes.tmpl": &bintree{templatesKubernetesTmpl, map[string]*bintree{}},
|
||||
"kv.tmpl": &bintree{templatesKvTmpl, map[string]*bintree{}},
|
||||
"marathon.tmpl": &bintree{templatesMarathonTmpl, map[string]*bintree{}},
|
||||
"mesos.tmpl": &bintree{templatesMesosTmpl, map[string]*bintree{}},
|
||||
"notFound.tmpl": &bintree{templatesNotfoundTmpl, map[string]*bintree{}},
|
||||
"rancher.tmpl": &bintree{templatesRancherTmpl, map[string]*bintree{}},
|
||||
}},
|
||||
}}
|
||||
|
||||
|
@ -442,3 +441,4 @@ func _filePath(dir, name string) string {
|
|||
cannonicalName := strings.Replace(name, "\\", "/", -1)
|
||||
return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
|
||||
}
|
||||
|
||||
|
|
|
@ -134,6 +134,8 @@ Labels can be used on task containers to override default behaviour:
|
|||
| `traefik.backend.loadbalancer.stickiness=true` | enable backend sticky sessions |
|
||||
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions |
|
||||
| `traefik.backend.loadbalancer.sticky=true` | enable backend sticky sessions (DEPRECATED) |
|
||||
| `traefik.backend.healthcheck.path=/health` | enable health checks for the backend, hitting the container at `path` |
|
||||
| `traefik.backend.healthcheck.interval=1s` | configure the health check interval |
|
||||
| `traefik.frontend.rule=Host:test.traefik.io` | override the default frontend rule (Default: `Host:{containerName}.{domain}`). |
|
||||
| `traefik.frontend.passHostHeader=true` | forward client `Host` header to the backend. |
|
||||
| `traefik.frontend.priority=10` | override default frontend priority |
|
||||
|
|
|
@ -28,10 +28,11 @@ func GetHealthCheck() *HealthCheck {
|
|||
|
||||
// Options are the public health check options.
|
||||
type Options struct {
|
||||
Path string
|
||||
Port int
|
||||
Interval time.Duration
|
||||
LB LoadBalancer
|
||||
Path string
|
||||
Port int
|
||||
Transport http.RoundTripper
|
||||
Interval time.Duration
|
||||
LB LoadBalancer
|
||||
}
|
||||
|
||||
func (opt Options) String() string {
|
||||
|
@ -146,7 +147,8 @@ func (backend *BackendHealthCheck) newRequest(serverURL *url.URL) (*http.Request
|
|||
|
||||
func checkHealth(serverURL *url.URL, backend *BackendHealthCheck) bool {
|
||||
client := http.Client{
|
||||
Timeout: backend.requestTimeout,
|
||||
Timeout: backend.requestTimeout,
|
||||
Transport: backend.Options.Transport,
|
||||
}
|
||||
req, err := backend.newRequest(serverURL)
|
||||
if err != nil {
|
||||
|
|
|
@ -195,6 +195,9 @@ func (p *Provider) generateECSConfig(services map[string][]ecsInstance) (*types.
|
|||
"getPassHostHeader": p.getPassHostHeader,
|
||||
"getPriority": p.getPriority,
|
||||
"getEntryPoints": p.getEntryPoints,
|
||||
"hasHealthCheckLabels": p.hasHealthCheckLabels,
|
||||
"getHealthCheckPath": p.getHealthCheckPath,
|
||||
"getHealthCheckInterval": p.getHealthCheckInterval,
|
||||
}
|
||||
return p.GetConfiguration("templates/ecs.tmpl", ecsFuncMap, struct {
|
||||
Services map[string][]ecsInstance
|
||||
|
@ -526,6 +529,18 @@ func (p *Provider) getLoadBalancerMethod(instances []ecsInstance) string {
|
|||
return "wrr"
|
||||
}
|
||||
|
||||
func (p *Provider) hasHealthCheckLabels(instances []ecsInstance) bool {
|
||||
return p.getHealthCheckPath(instances) != ""
|
||||
}
|
||||
|
||||
func (p *Provider) getHealthCheckPath(instances []ecsInstance) string {
|
||||
return p.getFirstInstanceLabel(instances, types.LabelBackendHealthcheckPath)
|
||||
}
|
||||
|
||||
func (p *Provider) getHealthCheckInterval(instances []ecsInstance) string {
|
||||
return p.getFirstInstanceLabel(instances, types.LabelBackendHealthcheckInterval)
|
||||
}
|
||||
|
||||
// Provider expects no more than 100 parameters be passed to a DescribeTask call; thus, pack
|
||||
// each string into an array capped at 100 elements
|
||||
func (p *Provider) chunkedTaskArns(tasks []*string) [][]*string {
|
||||
|
|
|
@ -643,6 +643,65 @@ func TestGenerateECSConfig(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "config parsed successfully with health check labels",
|
||||
services: map[string][]ecsInstance{
|
||||
"testing": {
|
||||
{
|
||||
Name: "instance-1",
|
||||
containerDefinition: &ecs.ContainerDefinition{
|
||||
DockerLabels: map[string]*string{
|
||||
types.LabelBackendHealthcheckPath: func(s string) *string { return &s }("/health"),
|
||||
types.LabelBackendHealthcheckInterval: func(s string) *string { return &s }("1s"),
|
||||
},
|
||||
},
|
||||
machine: &ec2.Instance{
|
||||
PrivateIpAddress: func(s string) *string { return &s }("10.0.0.1"),
|
||||
},
|
||||
container: &ecs.Container{
|
||||
NetworkBindings: []*ecs.NetworkBinding{
|
||||
{
|
||||
HostPort: func(i int64) *int64 { return &i }(1337),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
exp: &types.Configuration{
|
||||
Backends: map[string]*types.Backend{
|
||||
"backend-instance-1": {
|
||||
Servers: map[string]types.Server{
|
||||
"server-instance-1": {
|
||||
URL: "http://10.0.0.1:1337",
|
||||
},
|
||||
},
|
||||
},
|
||||
"backend-testing": {
|
||||
LoadBalancer: &types.LoadBalancer{
|
||||
Method: "wrr",
|
||||
},
|
||||
HealthCheck: &types.HealthCheck{
|
||||
Path: "/health",
|
||||
Interval: "1s",
|
||||
},
|
||||
},
|
||||
},
|
||||
Frontends: map[string]*types.Frontend{
|
||||
"frontend-testing": {
|
||||
EntryPoints: []string{},
|
||||
Backend: "backend-testing",
|
||||
Routes: map[string]types.Route{
|
||||
"route-frontend-testing": {
|
||||
Rule: "Host:instance-1.",
|
||||
},
|
||||
},
|
||||
PassHostHeader: true,
|
||||
BasicAuth: []string{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
|
@ -1019,6 +1019,7 @@ func (server *Server) loadConfig(configurations types.Configurations, globalConf
|
|||
hcOpts := parseHealthCheckOptions(rebalancer, frontend.Backend, config.Backends[frontend.Backend].HealthCheck, globalConfiguration.HealthCheck)
|
||||
if hcOpts != nil {
|
||||
log.Debugf("Setting up backend health check %s", *hcOpts)
|
||||
hcOpts.Transport = server.defaultForwardingRoundTripper
|
||||
backendsHealthCheck[entryPointName+frontend.Backend] = healthcheck.NewBackendHealthCheck(*hcOpts)
|
||||
}
|
||||
lb = middlewares.NewEmptyBackendHandler(rebalancer, lb)
|
||||
|
@ -1040,6 +1041,7 @@ func (server *Server) loadConfig(configurations types.Configurations, globalConf
|
|||
hcOpts := parseHealthCheckOptions(rr, frontend.Backend, config.Backends[frontend.Backend].HealthCheck, globalConfiguration.HealthCheck)
|
||||
if hcOpts != nil {
|
||||
log.Debugf("Setting up backend health check %s", *hcOpts)
|
||||
hcOpts.Transport = server.defaultForwardingRoundTripper
|
||||
backendsHealthCheck[entryPointName+frontend.Backend] = healthcheck.NewBackendHealthCheck(*hcOpts)
|
||||
}
|
||||
lb = middlewares.NewEmptyBackendHandler(rr, lb)
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
[backends.backend-{{ $serviceName }}.loadbalancer.stickiness]
|
||||
cookieName = "{{getStickinessCookieName $instances}}"
|
||||
{{end}}
|
||||
{{ if hasHealthCheckLabels $instances }}
|
||||
[backends.backend-{{ $serviceName }}.healthcheck]
|
||||
path = "{{getHealthCheckPath $instances }}"
|
||||
interval = "{{getHealthCheckInterval $instances }}"
|
||||
{{end}}
|
||||
|
||||
{{range $index, $i := $instances}}
|
||||
[backends.backend-{{ $i.Name }}.servers.server-{{ $i.Name }}{{ $i.ID }}]
|
||||
|
|
Loading…
Reference in a new issue