Traefik 与 Docker Swarm¶
Traefik 最出色的功能之一,是将路由配置交由应用层管理。 使用 Docker Swarm 时,Traefik 可以利用附加到服务的标签生成路由规则。
标签与敏感数据
我们建议不要使用标签存储敏感数据(证书、凭据等)。 建议将敏感数据存储在更安全的存储介质中(secret、文件等)。
配置示例¶
配置 Docker Swarm 并部署/暴露一个服务
启用 Docker 提供者(Swarm 模式)
providers:
swarm:
# swarm classic (1.12-)
# endpoint: "tcp://127.0.0.1:2375"
# docker swarm mode (1.12+)
endpoint: "tcp://127.0.0.1:2377"[providers.swarm]
# swarm classic (1.12-)
# endpoint = "tcp://127.0.0.1:2375"
# docker swarm mode (1.12+)
endpoint = "tcp://127.0.0.1:2377"# swarm classic (1.12-)
# --providers.swarm.endpoint=tcp://127.0.0.1:2375
# docker swarm mode (1.12+)
--providers.swarm.endpoint=tcp://127.0.0.1:2377在 Swarm 模式下,为服务(而非容器)附加标签(在 Docker compose 文件中)。 当只有一个服务,且路由器没有指定服务时, 该服务会自动分配给路由器。
services:
my-container:
deploy:
labels:
- traefik.http.routers.my-container.rule=Host(`example.com`)
- traefik.http.services.my-container-service.loadbalancer.server.port=8080
Docker Swarm 模式中的标签
在 Swarm 模式下,Traefik 使用服务上的标签,而不是各个容器上的标签。
因此,如果使用 Swarm 模式下的 compose 文件,标签应定义在服务的 deploy 部分。
此行为仅在 docker-compose 版本 3+ 中启用(Compose 文件参考)。
为容器指定自定义端口
将发往 http://example.com 的请求转发到 http://<private IP of container>:12345:
services:
my-container:
# ...
deploy:
labels:
- traefik.http.routers.my-container.rule=Host(`example.com`)
- traefik.http.routers.my-container.service=my-service"
# 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 使用容器暴露的最小端口,详细说明见 Swarm 提供者的端口检测章节。
设置 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:
# ...
deploy:
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=8080"
通过标签自动创建并分配服务
在 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`)"
路由器¶
要更新自动关联到容器的路由器配置,
请添加以 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:
# ...
deploy:
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:
# ...
deploy:
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:
# ...
deploy:
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.swarm.network |
覆盖连接容器时使用的默认 Docker 网络。 如果容器连接了多个网络,务必设置正确的网络名称(可以使用 docker inspect <container_id> 检查),否则会随机选择一个网络(取决于 Docker 返回这些网络的顺序)。从 compose 文件 stack 部署 stack 时,所定义的网络名称会加上 stack 前缀。 |
mynetwork |
traefik.swarm.lbswarm |
启用 Swarm 内置的负载均衡器(仅适用于 Swarm 模式)。 如果启用此选项,Traefik 会使用 Docker Swarm 提供的虚拟 IP,而不是容器 IP。 这意味着 Traefik 不会执行任何负载均衡,而是将此任务交给 Swarm。 |
true |