Traefik 与 Docker¶
Traefik 最出色的功能之一,是将路由配置交由应用层管理。 使用 Docker 时,Traefik 可以利用附加到容器的标签生成路由规则。
标签与敏感数据
我们建议不要使用标签存储敏感数据(证书、凭据等)。 建议将敏感数据存储在更安全的存储介质中(secret、文件等)。
配置示例¶
配置 Docker 并部署/暴露一个服务
启用 Docker 提供者
providers:
docker: {}[providers.docker]--providers.docker=true为容器附加标签(在 Docker compose 文件中)
services:
my-container:
# ...
labels:
- traefik.http.routers.my-container.rule=Host(`example.com`)
为容器指定自定义端口
将发往 http://example.com 的请求转发到 http://<private IP of container>:12345:
services:
my-container:
# ...
labels:
- traefik.http.routers.my-container.rule=Host(`example.com`)
# Tell Traefik to use the port 12345 to connect to `my-container`
- traefik.http.services.my-service.loadbalancer.server.port=12345
Traefik 连接到错误端口:HTTP/502 Gateway Error
默认情况下,Traefik 使用容器暴露的第一个端口。
设置 traefik.http.services.xxx.loadbalancer.server.port 标签
可以覆盖此行为。
为每个容器指定多个路由器和服务
将请求转发到容器上的多个端口时,需要使用路由器上的 service 参数引用服务负载均衡器的端口定义。
在此示例中,发往 http://example-a.com 的请求转发到 http://<private IP of container>:8000,同时发往 http://example-b.com 的请求转发到 http://<private IP of container>:9000:
services:
my-container:
# ...
labels:
- traefik.http.routers.www-router.rule=Host(`example-a.com`)
- traefik.http.routers.www-router.service=www-service
- traefik.http.services.www-service.loadbalancer.server.port=8000
- traefik.http.routers.admin-router.rule=Host(`example-b.com`)
- traefik.http.routers.admin-router.service=admin-service
- traefik.http.services.admin-service.loadbalancer.server.port=9000
配置选项¶
标签
- 标签不区分大小写。
TLS 默认生成证书
要了解如何配置 Traefik 默认生成的证书,请参阅 TLS 证书页面。
通用配置¶
服务会自动为容器的每个实例添加一个服务器,
路由器会自动获得一条由 defaultRule 定义的规则(如果未在标签中为其定义规则)。
服务定义¶
通常,在配置 Traefik 提供者时, 还必须定义分配给一个或多个路由器的服务,路由才能正常工作。
不过,使用基于标签的配置时存在以下例外:
-
如果一个标签定义了路由器(例如通过路由器规则), 另一个标签定义了服务(例如通过负载均衡器的服务器端口值隐式定义), 但路由器没有指定服务, 则该服务会自动分配给这个路由器。
-
如果一个标签定义了路由器(例如通过路由器规则),但没有定义服务, 则会自动创建一个服务并将其分配给该路由器。
正如预期,在上述任一情况下,如果另外为路由器显式指定了服务, 就会使用所指定的服务,无论这个服务是否实际定义,也无论是否定义了其他服务。
只有一个服务时自动分配
在 compose 文件中使用标签
labels:
- "traefik.http.routers.myproxy.rule=Host(`example.net`)"
# service myservice gets automatically assigned to router myproxy
- "traefik.http.services.myservice.loadbalancer.server.port=80"
只有一个路由器时自动创建服务
在 compose 文件中使用标签
labels:
# no service specified or defined and yet one gets automatically created
# and assigned to router myproxy.
- "traefik.http.routers.myproxy.rule=Host(`example.net`)"
显式定义一个服务
在 compose 文件中使用标签
labels:
- traefik.http.routers.www-router.rule=Host(`example-a.com`)
# Explicit link between the router and the service
- traefik.http.routers.www-router.service=www-service
- traefik.http.services.www-service.loadbalancer.server.port=8000
路由器¶
要更新自动关联到容器的路由器配置,
请添加以 traefik.http.routers.<name-of-your-choice>. 开头、后接要修改选项的标签。
例如,要修改规则,可以添加标签 traefik.http.routers.my-container.rule=Host(`example.com`)。
路由器名称 <router_name> 中不允许使用字符 @。
配置选项¶
服务¶
要更新自动关联到容器的服务配置,
请添加以 traefik.http.services.<name-of-your-choice>. 开头、后接要修改选项的标签。
例如,要修改 passHostHeader 的行为,
可以添加标签 traefik.http.services.<name-of-your-choice>.loadbalancer.passhostheader=false。
服务名称 <service_name> 中不允许使用字符 @。
配置选项¶
中间件¶
可以使用以 traefik.http.middlewares.<name-of-your-choice>. 开头、
后接中间件类型/选项的标签声明中间件。
例如,要声明一个名为 my-redirect 的 redirectscheme 中间件,
可以编写 traefik.http.middlewares.my-redirect.redirectscheme.scheme=https。
可用中间件的更多信息见专门的中间件章节。
中间件名称中不允许使用字符 @。
声明并引用中间件
services:
my-container:
# ...
labels:
# Declaring a middleware
- traefik.http.middlewares.my-redirect.redirectscheme.scheme=https
# Referencing a middleware
- traefik.http.routers.my-container.middlewares=my-redirect
声明冲突
如果使用相同名称、不同参数声明多个中间件,该中间件将无法声明。
TCP¶
可以使用标签声明 TCP 路由器和/或服务。
声明 TCP 路由器和一个服务
services:
my-container:
# ...
labels:
- "traefik.tcp.routers.my-router.rule=HostSNI(`example.com`)"
- "traefik.tcp.routers.my-router.tls=true"
- "traefik.tcp.services.my-service.loadbalancer.server.port=4123"
TCP 与 HTTP
如果声明 TCP 路由器/服务,Traefik 就不会再自动创建 HTTP 路由器/服务(未定义 TCP 路由器/服务时,默认会自动创建)。 可以为同一个容器同时声明 TCP 路由器/服务和 HTTP 路由器/服务(但必须手动声明)。
TCP 路由器¶
配置选项¶
| 标签 | 说明 | 值 |
|---|---|---|
traefik.tcp.routers.<router_name>.entrypoints |
更多信息请参阅入口点。 | ep1,ep2 |
traefik.tcp.routers.<router_name>.rule |
更多信息请参阅规则。 | HostSNI(`example.com`) |
traefik.tcp.routers.<router_name>.ruleSyntax |
为每个路由器配置解析规则时所用的规则语法。 RuleSyntax 选项已弃用,将在下一个主版本中移除。 请勿使用此字段,并将路由器规则改写为 v3 语法。 |
v3 |
traefik.tcp.routers.<router_name>.service |
更多信息请参阅服务。 | myservice |
traefik.tcp.routers.<router_name>.tls |
更多信息请参阅 TLS。 | true |
traefik.tcp.routers.<router_name>.tls.certresolver |
更多信息请参阅 certResolver。 | myresolver |
traefik.tcp.routers.<router_name>.tls.domains[n].main |
更多信息请参阅 TLS。 | example.org |
traefik.tcp.routers.<router_name>.tls.domains[n].sans |
更多信息请参阅 TLS。 | test.example.org,dev.example.org |
traefik.tcp.routers.<router_name>.tls.options |
更多信息请参阅 TLS。 | mysoptions |
traefik.tcp.routers.<router_name>.tls.passthrough |
更多信息请参阅透传。 | true |
traefik.tcp.routers.<router_name>.priority |
更多信息请参阅优先级。 | 42 |
TCP 服务¶
配置选项¶
| 标签 | 说明 | 值 |
|---|---|---|
traefik.tcp.services.<service_name>.loadbalancer.server.port |
注册应用程序的一个端口。 | 423 |
traefik.tcp.services.<service_name>.loadbalancer.server.tls |
决定与后端建立连接时是否使用 TLS。 | true |
traefik.tcp.services.<service_name>.loadbalancer.serverstransport |
允许引用使用文件提供者或 Kubernetes CRD 提供者定义的 ServersTransport 资源。 更多信息请参阅 serverstransport。 |
foobar@file |
TCP 中间件¶
可以使用以 traefik.tcp.middlewares.{name-of-your-choice}. 开头、后接中间件类型/选项的标签声明中间件。
例如,要声明一个名为 test-inflightconn 的 InFlightConn 中间件,可以编写 traefik.tcp.middlewares.test-inflightconn.inflightconn.amount=10。
可用中间件的更多信息见专门的中间件章节。
声明并引用中间件
# ...
# Declaring a middleware
traefik.tcp.middlewares.test-inflightconn.inflightconn.amount=10
# Referencing a middleware
traefik.tcp.routers.my-service.middlewares=test-inflightconn
声明冲突
如果使用相同名称、不同参数声明多个中间件,该中间件将无法声明。
UDP¶
可以使用标签声明 UDP 路由器和/或服务。
声明 UDP 路由器和一个服务
services:
my-container:
# ...
labels:
- "traefik.udp.routers.my-router.entrypoints=udp"
- "traefik.udp.services.my-service.loadbalancer.server.port=4123"
UDP 与 HTTP
如果声明 UDP 路由器/服务,Traefik 就不会再自动创建 HTTP 路由器/服务(未定义 UDP 路由器/服务时,默认会自动创建)。 可以为同一个容器同时声明 UDP 路由器/服务和 HTTP 路由器/服务(但必须手动声明)。
UDP 路由器¶
配置选项¶
| 标签 | 说明 | 值 |
|---|---|---|
traefik.udp.routers.<router_name>.entrypoints |
更多信息请参阅入口点。 | ep1,ep2 |
traefik.udp.routers.<router_name>.service |
更多信息请参阅服务。 | myservice |
UDP 服务¶
配置选项¶
| 标签 | 说明 | 值 |
|---|---|---|
traefik.udp.services.<service_name>.loadbalancer.server.port |
注册应用程序的一个端口。 | 423 |
提供者特有选项¶
| 标签 | 说明 | 值 |
|---|---|---|
traefik.enable |
可以通过将 traefik.enable 设置为 true 或 false,指示 Traefik 是否处理该容器。此选项覆盖 exposedByDefault 的值。 |
true |
traefik.docker.allownonrunning |
默认情况下,Traefik 只处理处于 "running" 状态的容器。 此选项控制不处于 "running" 状态(例如已停止、已暂停、已退出)的容器,是否仍可被 Traefik 发现以用于服务发现。 将此标签设置为 true 时,Traefik 将: - 即使容器未运行,也保留路由器和服务配置 - 创建后端服务器列表为空的服务 - 对发往已停止容器的请求返回 503 Service Unavailable(而不是 404 Not Found) - 执行完整的中间件链,允许中间件拦截请求 由于 traefik.docker.allownonrunning 会发现所有声明了此选项的容器,而不考虑其状态,如果多个已停止的容器声明了相同的路由器,但配置不同,这些路由器就会被丢弃。 |
true |
traefik.docker.network |
覆盖连接容器时使用的默认 Docker 网络。 如果容器连接了多个网络,务必设置正确的网络名称(可以使用 docker inspect <container_id> 检查),否则会随机选择一个网络(取决于 Docker 返回这些网络的顺序)。从 compose 文件 stack 部署 stack 时,所定义的网络名称会加上 stack 前缀。 |
mynetwork |