Traefik 与 AWS ECS¶
配置示例¶
可以按以下方式启用 ECS 提供者:
providers:
ecs: {}[providers.ecs]--providers.ecs=true配置选项¶
| 字段 | 说明 | 默认值 | 必填 |
|---|---|---|---|
providers.providersThrottleDuration |
配置重新加载后,在接受新的配置刷新事件之前至少等待的时间。 如果在此期间发生多个事件,只处理最新的事件,其余事件全部丢弃。 此选项无法为每个提供者单独设置,但节流算法会独立作用于各个提供者。 |
2s | 否 |
providers.ecs.autoDiscoverClusters |
在集群列表中搜索服务。如果设置为 true,会为所有集群启用服务发现。 |
false | 否 |
providers.ecs.ecsAnywhere |
启用 ECS Anywhere 支持。 | false | 否 |
providers.ecs.clusters |
在集群列表中搜索服务。如果 autoDiscoverClusters 设置为 true,则忽略此选项。 |
["default"] |
否 |
providers.ecs.exposedByDefault |
默认通过 Traefik 暴露 ECS 服务。如果设置为 false,生成的路由配置将忽略没有 traefik.enable=true 标签的容器。有关更多信息,请参阅此处。 |
true | 否 |
providers.ecs.constraints |
定义一个表达式,Traefik 将其与容器标签进行匹配,以决定是否为该容器创建路由。有关更多信息,请参阅此处。 | "" |
否 |
providers.ecs.healthyTasksOnly |
定义 Traefik 是否仅发现健康任务(healthStatus 为 HEALTHY)。 |
false | 否 |
providers.ecs.defaultRule |
所有服务的默认 Host 规则。有关更多信息,请参阅此处。 | "Host(`{{ normalize .Name }}`)" |
否 |
providers.ecs.refreshSeconds |
定义轮询间隔(以秒为单位)。 | 15 | 否 |
providers.ecs.region |
定义 ECS 实例所在的区域。有关更多信息,请参阅此处。 | "" | 否 |
providers.ecs.accessKeyID |
定义 ECS 实例的 Access Key ID。有关更多信息,请参阅此处。 | "" | 否 |
providers.ecs.secretAccessKey |
定义 ECS 实例的 Secret Access Key。有关更多信息,请参阅此处。 | "" | 否 |
constraints¶
constraints 选项可以设置为一个表达式。Traefik 将容器(任务)标签与该表达式进行匹配,
以决定是否为该容器创建路由。
如果容器的标签均不匹配此表达式,就不会为该容器创建路由。
如果表达式为空,则包含所有发现的容器。
表达式语法基于 Label("key", "value") 和 LabelRegex("key", "value") 函数,
并支持常规的布尔逻辑,如以下示例所示。
约束键的限制
请注意,traefik.* 是保留用于配置的标签命名空间,不能用作自定义约束的键。
约束表达式示例
# Includes only containers having a label with key `a.label.name` and value `foo`
constraints = "Label(`a.label.name`, `foo`)"
# Excludes containers having any label with key `a.label.name` and value `foo`
constraints = "!Label(`a.label.name`, `value`)"
# With logical AND.
constraints = "Label(`a.label.name`, `valueA`) && Label(`another.label.name`, `valueB`)"
# With logical OR.
constraints = "Label(`a.label.name`, `valueA`) || Label(`another.label.name`, `valueB`)"
# With logical AND and OR, with precedence set by parentheses.
constraints = "Label(`a.label.name`, `valueA`) && (Label(`another.label.name`, `valueB`) || Label(`yet.another.label.name`, `valueC`))"
# Includes only containers having a label with key `a.label.name` and a value matching the `a.+` regular expression.
constraints = "LabelRegex(`a.label.name`, `a.+`)"
providers:
ecs:
constraints: "Label(`a.label.name`,`foo`)"
# ...[providers.ecs]
constraints = "Label(`a.label.name`,`foo`)"
# ...--providers.ecs.constraints="Label(`a.label.name`,`foo`)"
# ...有关更多信息,请参阅限制服务发现的范围。
defaultRule¶
defaultRule 选项定义当标签没有指定规则时,应对容器应用的路由规则。
它必须是有效的 Go 模板,并且可以使用
sprig 模板函数。
可以通过 Name 标识符访问容器的服务名,
模板还可以访问此容器上定义的全部标签。
providers:
ecs:
defaultRule: "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)"
# ...[providers.ecs]
defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)"
# ...--providers.ecs.defaultRule='Host(`{{ .Name }}.{{ index .Labels "customLabel"}}`)'
# ...默认规则与 Traefik 服务
暴露 Traefik 容器时,如果同时使用默认规则机制, 可能会创建一个以自身为目标的路由器,形成循环。 遇到这种情况时,为避免无限循环, Traefik 会添加一个内部中间件,拒绝来自同一路由器的请求。
凭据¶
此处定义 ECS 实例的凭据。
如果没有提供 region,对于 EC2 任务,会从 EC2 元数据端点解析它。
在 FARGATE 环境中,则从 AWS_REGION 环境变量解析它。
如果没有提供 accessKeyID 和 secretAccessKey,则按以下顺序解析凭据:
- 使用环境变量
AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY和AWS_SESSION_TOKEN。 - 使用共享凭据,由
AWS_PROFILE和AWS_SHARED_CREDENTIALS_FILE指定,默认值分别为default和~/.aws/credentials。 - 使用 EC2 实例角色或 ECS 任务角色。
providers:
ecs:
region: us-east-1
accessKeyID: "abc"
secretAccessKey: "123"
# ...[providers.ecs]
region = "us-east-1"
accessKeyID = "abc"
secretAccessKey = "123"--providers.ecs.region="us-east-1"
--providers.ecs.accessKeyID="abc"
--providers.ecs.secretAccessKey="123"
# ...策略¶
Traefik 需要以下策略才能读取 ECS 信息:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "TraefikECSReadAccess",
"Effect": "Allow",
"Action": [
"ecs:ListClusters",
"ecs:DescribeClusters",
"ecs:ListTasks",
"ecs:DescribeTasks",
"ecs:DescribeContainerInstances",
"ecs:DescribeTaskDefinition",
"ec2:DescribeInstances",
"ssm:DescribeInstanceInformation"
],
"Resource": [
"*"
]
}
]
}
ECS Anywhere
请注意,发现 ECS Anywhere 实例需要 ssm:DescribeInstanceInformation 操作。