Add option to keep only healthy ECS tasks

This commit is contained in:
Michael Hampton 2022-09-20 06:42:08 -07:00 committed by GitHub
parent d6b69e1347
commit df99a9fb57
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 63 additions and 26 deletions

View file

@ -169,6 +169,30 @@ providers:
# ... # ...
``` ```
### `healthyTasksOnly`
_Optional, Default=false_
Determines whether Traefik discovers only healthy tasks (`HEALTHY` healthStatus).
```yaml tab="File (YAML)"
providers:
ecs:
healthyTasksOnly: true
# ...
```
```toml tab="File (TOML)"
[providers.ecs]
healthyTasksOnly = true
# ...
```
```bash tab="CLI"
--providers.ecs.healthyTasksOnly=true
# ...
```
### `defaultRule` ### `defaultRule`
_Optional, Default=```Host(`{{ normalize .Name }}`)```_ _Optional, Default=```Host(`{{ normalize .Name }}`)```_

View file

@ -559,13 +559,13 @@ Watch Docker Swarm events. (Default: ```true```)
Enable AWS ECS backend with default settings. (Default: ```false```) Enable AWS ECS backend with default settings. (Default: ```false```)
`--providers.ecs.accesskeyid`: `--providers.ecs.accesskeyid`:
The AWS credentials access key to use for making requests AWS credentials access key ID to use for making requests.
`--providers.ecs.autodiscoverclusters`: `--providers.ecs.autodiscoverclusters`:
Auto discover cluster (Default: ```false```) Auto discover cluster. (Default: ```false```)
`--providers.ecs.clusters`: `--providers.ecs.clusters`:
ECS Clusters name (Default: ```default```) ECS Cluster names. (Default: ```default```)
`--providers.ecs.constraints`: `--providers.ecs.constraints`:
Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container. Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container.
@ -574,19 +574,22 @@ Constraints is an expression that Traefik matches against the container's labels
Default rule. (Default: ```Host(`{{ normalize .Name }}`)```) Default rule. (Default: ```Host(`{{ normalize .Name }}`)```)
`--providers.ecs.ecsanywhere`: `--providers.ecs.ecsanywhere`:
Enable ECS Anywhere support (Default: ```false```) Enable ECS Anywhere support. (Default: ```false```)
`--providers.ecs.exposedbydefault`: `--providers.ecs.exposedbydefault`:
Expose services by default (Default: ```true```) Expose services by default. (Default: ```true```)
`--providers.ecs.healthytasksonly`:
Determines whether to discover only healthy tasks. (Default: ```false```)
`--providers.ecs.refreshseconds`: `--providers.ecs.refreshseconds`:
Polling interval (in seconds) (Default: ```15```) Polling interval (in seconds). (Default: ```15```)
`--providers.ecs.region`: `--providers.ecs.region`:
The AWS region to use for requests AWS region to use for requests.
`--providers.ecs.secretaccesskey`: `--providers.ecs.secretaccesskey`:
The AWS credentials access key to use for making requests AWS credentials access key to use for making requests.
`--providers.etcd`: `--providers.etcd`:
Enable Etcd backend with default settings. (Default: ```false```) Enable Etcd backend with default settings. (Default: ```false```)

View file

@ -559,13 +559,13 @@ Watch Docker Swarm events. (Default: ```true```)
Enable AWS ECS backend with default settings. (Default: ```false```) Enable AWS ECS backend with default settings. (Default: ```false```)
`TRAEFIK_PROVIDERS_ECS_ACCESSKEYID`: `TRAEFIK_PROVIDERS_ECS_ACCESSKEYID`:
The AWS credentials access key to use for making requests AWS credentials access key ID to use for making requests.
`TRAEFIK_PROVIDERS_ECS_AUTODISCOVERCLUSTERS`: `TRAEFIK_PROVIDERS_ECS_AUTODISCOVERCLUSTERS`:
Auto discover cluster (Default: ```false```) Auto discover cluster. (Default: ```false```)
`TRAEFIK_PROVIDERS_ECS_CLUSTERS`: `TRAEFIK_PROVIDERS_ECS_CLUSTERS`:
ECS Clusters name (Default: ```default```) ECS Cluster names. (Default: ```default```)
`TRAEFIK_PROVIDERS_ECS_CONSTRAINTS`: `TRAEFIK_PROVIDERS_ECS_CONSTRAINTS`:
Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container. Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container.
@ -574,19 +574,22 @@ Constraints is an expression that Traefik matches against the container's labels
Default rule. (Default: ```Host(`{{ normalize .Name }}`)```) Default rule. (Default: ```Host(`{{ normalize .Name }}`)```)
`TRAEFIK_PROVIDERS_ECS_ECSANYWHERE`: `TRAEFIK_PROVIDERS_ECS_ECSANYWHERE`:
Enable ECS Anywhere support (Default: ```false```) Enable ECS Anywhere support. (Default: ```false```)
`TRAEFIK_PROVIDERS_ECS_EXPOSEDBYDEFAULT`: `TRAEFIK_PROVIDERS_ECS_EXPOSEDBYDEFAULT`:
Expose services by default (Default: ```true```) Expose services by default. (Default: ```true```)
`TRAEFIK_PROVIDERS_ECS_HEALTHYTASKSONLY`:
Determines whether to discover only healthy tasks. (Default: ```false```)
`TRAEFIK_PROVIDERS_ECS_REFRESHSECONDS`: `TRAEFIK_PROVIDERS_ECS_REFRESHSECONDS`:
Polling interval (in seconds) (Default: ```15```) Polling interval (in seconds). (Default: ```15```)
`TRAEFIK_PROVIDERS_ECS_REGION`: `TRAEFIK_PROVIDERS_ECS_REGION`:
The AWS region to use for requests AWS region to use for requests.
`TRAEFIK_PROVIDERS_ECS_SECRETACCESSKEY`: `TRAEFIK_PROVIDERS_ECS_SECRETACCESSKEY`:
The AWS credentials access key to use for making requests AWS credentials access key to use for making requests.
`TRAEFIK_PROVIDERS_ETCD`: `TRAEFIK_PROVIDERS_ETCD`:
Enable Etcd backend with default settings. (Default: ```false```) Enable Etcd backend with default settings. (Default: ```false```)

View file

@ -206,6 +206,7 @@
accessKeyID = "foobar" accessKeyID = "foobar"
secretAccessKey = "foobar" secretAccessKey = "foobar"
ecsAnywhere = true ecsAnywhere = true
healthyTasksOnly = true
[providers.consul] [providers.consul]
rootKey = "foobar" rootKey = "foobar"
endpoints = ["foobar", "foobar"] endpoints = ["foobar", "foobar"]

View file

@ -224,6 +224,7 @@ providers:
accessKeyID: foobar accessKeyID: foobar
secretAccessKey: foobar secretAccessKey: foobar
ecsAnywhere: true ecsAnywhere: true
healthyTasksOnly: true
consul: consul:
rootKey: foobar rootKey: foobar
endpoints: endpoints:

View file

@ -27,17 +27,18 @@ import (
// Provider holds configurations of the provider. // Provider holds configurations of the provider.
type Provider struct { type Provider struct {
Constraints string `description:"Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container." json:"constraints,omitempty" toml:"constraints,omitempty" yaml:"constraints,omitempty" export:"true"` Constraints string `description:"Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container." json:"constraints,omitempty" toml:"constraints,omitempty" yaml:"constraints,omitempty" export:"true"`
ExposedByDefault bool `description:"Expose services by default" json:"exposedByDefault,omitempty" toml:"exposedByDefault,omitempty" yaml:"exposedByDefault,omitempty" export:"true"` ExposedByDefault bool `description:"Expose services by default." json:"exposedByDefault,omitempty" toml:"exposedByDefault,omitempty" yaml:"exposedByDefault,omitempty" export:"true"`
RefreshSeconds int `description:"Polling interval (in seconds)" json:"refreshSeconds,omitempty" toml:"refreshSeconds,omitempty" yaml:"refreshSeconds,omitempty" export:"true"` RefreshSeconds int `description:"Polling interval (in seconds)." json:"refreshSeconds,omitempty" toml:"refreshSeconds,omitempty" yaml:"refreshSeconds,omitempty" export:"true"`
DefaultRule string `description:"Default rule." json:"defaultRule,omitempty" toml:"defaultRule,omitempty" yaml:"defaultRule,omitempty"` DefaultRule string `description:"Default rule." json:"defaultRule,omitempty" toml:"defaultRule,omitempty" yaml:"defaultRule,omitempty"`
// Provider lookup parameters. // Provider lookup parameters.
Clusters []string `description:"ECS Clusters name" json:"clusters,omitempty" toml:"clusters,omitempty" yaml:"clusters,omitempty" export:"true"` Clusters []string `description:"ECS Cluster names." json:"clusters,omitempty" toml:"clusters,omitempty" yaml:"clusters,omitempty" export:"true"`
AutoDiscoverClusters bool `description:"Auto discover cluster" json:"autoDiscoverClusters,omitempty" toml:"autoDiscoverClusters,omitempty" yaml:"autoDiscoverClusters,omitempty" export:"true"` AutoDiscoverClusters bool `description:"Auto discover cluster." json:"autoDiscoverClusters,omitempty" toml:"autoDiscoverClusters,omitempty" yaml:"autoDiscoverClusters,omitempty" export:"true"`
ECSAnywhere bool `description:"Enable ECS Anywhere support" json:"ecsAnywhere,omitempty" toml:"ecsAnywhere,omitempty" yaml:"ecsAnywhere,omitempty" export:"true"` HealthyTasksOnly bool `description:"Determines whether to discover only healthy tasks." json:"healthyTasksOnly,omitempty" toml:"healthyTasksOnly,omitempty" yaml:"healthyTasksOnly,omitempty" export:"true"`
Region string `description:"The AWS region to use for requests" json:"region,omitempty" toml:"region,omitempty" yaml:"region,omitempty" export:"true"` ECSAnywhere bool `description:"Enable ECS Anywhere support." json:"ecsAnywhere,omitempty" toml:"ecsAnywhere,omitempty" yaml:"ecsAnywhere,omitempty" export:"true"`
AccessKeyID string `description:"The AWS credentials access key to use for making requests" json:"accessKeyID,omitempty" toml:"accessKeyID,omitempty" yaml:"accessKeyID,omitempty" loggable:"false"` Region string `description:"AWS region to use for requests." json:"region,omitempty" toml:"region,omitempty" yaml:"region,omitempty" export:"true"`
SecretAccessKey string `description:"The AWS credentials access key to use for making requests" json:"secretAccessKey,omitempty" toml:"secretAccessKey,omitempty" yaml:"secretAccessKey,omitempty" loggable:"false"` AccessKeyID string `description:"AWS credentials access key ID to use for making requests." json:"accessKeyID,omitempty" toml:"accessKeyID,omitempty" yaml:"accessKeyID,omitempty" loggable:"false"`
SecretAccessKey string `description:"AWS credentials access key to use for making requests." json:"secretAccessKey,omitempty" toml:"secretAccessKey,omitempty" yaml:"secretAccessKey,omitempty" loggable:"false"`
defaultRuleTpl *template.Template defaultRuleTpl *template.Template
} }
@ -81,6 +82,7 @@ var (
func (p *Provider) SetDefaults() { func (p *Provider) SetDefaults() {
p.Clusters = []string{"default"} p.Clusters = []string{"default"}
p.AutoDiscoverClusters = false p.AutoDiscoverClusters = false
p.HealthyTasksOnly = false
p.ExposedByDefault = true p.ExposedByDefault = true
p.RefreshSeconds = 15 p.RefreshSeconds = 15
p.DefaultRule = DefaultTemplateRule p.DefaultRule = DefaultTemplateRule
@ -258,9 +260,12 @@ func (p *Provider) listInstances(ctx context.Context, client *awsClient) ([]ecsI
logger.Errorf("Unable to describe tasks for %v", page.TaskArns) logger.Errorf("Unable to describe tasks for %v", page.TaskArns)
} else { } else {
for _, t := range resp.Tasks { for _, t := range resp.Tasks {
if aws.StringValue(t.LastStatus) == ecs.DesiredStatusRunning { if p.HealthyTasksOnly && aws.StringValue(t.HealthStatus) != ecs.HealthStatusHealthy {
tasks[aws.StringValue(t.TaskArn)] = t logger.Debugf("Skipping unhealthy task %s", aws.StringValue(t.TaskArn))
continue
} }
tasks[aws.StringValue(t.TaskArn)] = t
} }
} }
} }