常见问题¶
为什么 Traefik 返回 XXX HTTP 响应状态码?¶
Traefik 是动态反向代理。 虽然文档经常通过配置文件示例来演示配置选项, 但 Traefik 的核心能力是动态配置, 它会直接响应提供者随时间发生的变化。
具体来说,安装配置是静态的, 可以在启动时通过文件提供;而各种提供者, 例如文件提供者, 会在 Traefik 实例的整个生命周期中,持续动态地更新其路由配置。
此外,配置还包含 EntryPoint 等概念,它可以看作传输层(TCP)的监听器; 而 Router 则更关注表示层(TLS)和应用层(HTTP)。 对于一个 EntryPoint,可以按需配置任意数量的路由器。
换句话说,对于某个 Entrypoint, 任意时刻观察到的流量并不一定只涉及一种协议。 它可以是 HTTP,也可以是其他协议;可以经过 TLS,也可以不经过。 更不用说,动态配置变更可能导致流量类型随时间变化。
因此,在这样的动态环境中,
某个 entryPoint 的静态配置完全无法说明经过该 entryPoint 的流量会如何路由。
甚至无法说明流量是否会被路由,
也就是是否存在与经过此入口的流量类型匹配的 Router。
404 Not found¶
Traefik 在以下情况下返回 404 响应码:
- 请求到达的 EntryPoint 未配置任何 Router
- HTTP 请求到达的 EntryPoint 未配置 HTTP Router
- HTTPS 请求到达的 EntryPoint 未配置 HTTPS Router
- 请求到达的 EntryPoint 配置了 HTTP/HTTPS Router,但无法匹配这些路由器
从 Traefik 的角度看,
每当请求无法匹配路由器时,正确的响应码都是 404 Not found。
在这种情况下,响应码不会是 503 Service Unavailable,
因为 Traefik 无法确认请求缺少匹配路由器的情况只是暂时的。
Traefik 的路由配置是动态的,由不同提供者的配置聚合而成,
因此无法在任意时刻假定某条路由应该被处理或不被处理。
此行为符合 rfc7231
The server is currently unable to handle the request due to a
temporary overloading or maintenance of the server. The implication
is that this is a temporary condition which will be alleviated after
some delay. If known, the length of the delay MAY be indicated in a
Retry-After header. If no Retry-After is given, the client SHOULD
handle the response as it would for a 500 response.
Note: The existence of the 503 status code does not imply that a
server must use it when becoming overloaded. Some servers may wish
to simply refuse the connection.
502 Bad Gateway¶
Traefik 在联系上游服务时发生错误,就会返回 502 响应码。
503 Service Unavailable¶
当请求已匹配某个 Router,
但没有就绪服务器能够处理该请求时,Traefik 返回 503 响应码。
当服务被显式配置为不包含服务器, 或者服务启用了健康检查且所有服务器均不健康时,就会出现此情况。
用 XXX 代替 404¶
有时,404 响应码与其他参与方或服务(例如 CDN)配合得不够好。
在这种情况下,您可能希望 Traefik 始终返回 503 响应码,
而不是 404 响应码。
为实现此行为,可以配置一个兜底路由器, 将其优先级设为尽可能低,并路由到不包含服务器的服务, 从而在没有匹配其他路由器时处理所有请求。
下面是仅使用文件提供者的配置示例(yaml):
# traefik.yml
entryPoints:
web:
address: :80
providers:
file:
filename: dynamic.yaml# dynamic.yaml
http:
routers:
catchall:
# attached only to web entryPoint
entryPoints:
- "web"
# catchall rule
rule: "PathPrefix(`/`)"
service: unavailable
# lowest possible priority
# evaluated when no other router is matched
priority: 1
services:
# Service that will always answer a 503 Service Unavailable response
unavailable:
loadBalancer:
servers: {}专用服务
如果需要返回 503 以外的响应码,或者自定义消息,
上述示例的原理(兜底路由器)仍然适用,
但应调整 unavailable 服务以满足此类需求。
为什么 TLS 证书内容变化后没有重新加载?¶
使用文件提供者时, 只有被监视的配置文件发生修改,才会触发配置更新。
因此,如果通过路径定义证书, 而实际变更的是该证书的内容, 就_不会_触发配置更新。
要使新证书内容生效,必须强制更新动态配置。
一种方法是触发文件通知,
例如对配置文件执行 touch 命令。
代理 HTTP 请求时会添加哪些转发头?¶
默认情况下,代理请求时会自动添加以下请求头:
| 属性 | HTTP 请求头 |
|---|---|
| 客户端 IP | X-Forwarded-For, X-Real-Ip |
| 主机 | X-Forwarded-Host |
| 端口 | X-Forwarded-Port |
| 协议 | X-Forwarded-Proto |
| 代理服务器的主机名 | X-Forwarded-Server |
更多详情, 请查阅转发头文档。
Traefik 如何存储和提供 TLS 证书?¶
存储 TLS 证书¶
TLS 证书可以直接由路由配置提供, 也可以由证书解析器提供。
对于每个 TLS 证书,Traefik 都会生成一个标识符,用作存储该证书的键。
该标识符由 TLS 证书 SAN 中的 DNSNames 和 IPAddresses 按字母顺序排列并拼接而成。
示例:¶
| X509v3 主题备用名称 | TLS 证书标识符 |
|---|---|
DNS:example.com, IP Address:127.0.0.1 |
127.0.0.1,example.com |
DNS:example.com, DNS:*.example.com |
*.example.com,example.com |
此标识符用于存储 TLS 证书,以便随后用于处理 TLS 连接。 每次配置发生变化时,都会执行此操作。
如果提供了多个具有相同 SAN 定义(相同标识符)的 TLS 证书,只会保留第一个处理的证书。 由于动态配置是从所有提供者聚合而来, 在处理配置、收集 TLS 证书时, 无法保证处理顺序。 因此,随着配置的应用,某个标识符最终保留的 TLS 证书可能会发生变化。
提供 TLS 证书¶
对于每个传入连接,Traefik 会为其提供的服务器名称选用“最匹配”的 TLS 证书。
TLS 证书选择流程先筛出与服务器名称匹配的证书列表, 然后按标识符的字母顺序排序,选择列表中的最后一个 TLS 证书。
示例:¶
| 选中的 TLS 证书标识符 | 排序后的 TLS 证书标识符 | 提供的证书标识符 |
|---|---|---|
127.0.0.1,example.com,*.example.com,example.com |
*.example.com,example.com,127.0.0.1,example.com |
127.0.0.1,example.com |
*.example.com,example.com,example.com |
*.example.com,example.com,example.com |
example.com |
缓存 TLS 证书¶
Traefik 为每个传入连接提供最匹配的 TLS 证书, 同时通过缓存机制避免每次连接都承担证书选择的开销。
一旦某个 TLS 证书被选为服务器名称的“最匹配”证书, 就会缓存一小时,使后续连接无需再次执行选择流程。
不过,每当应用新配置时,缓存都会重置。
“field not found”错误是什么意思?¶
error: field not found, node: -badField-
当动态或静态配置中出现未知属性时,就会发生“field not found”错误。
检查配置文件格式是否正确的一种方法是使用以下 Schema 进行校验:
为什么某些资源(路由器、中间件、服务等)没有创建或应用?¶
一个通用建议是:如果 Traefik 在求值动态配置后丢弃或未创建某个资源, 应在日志中查找错误。
如果找到了错误,就说明创建资源时出现了问题, 错误消息通常有助于定位配置中的错误及其修复方式。
使用文件提供者时, 可以使用动态配置 JSON Schema 进行校验,以检查动态配置格式是否正确。
为什么使用 DNS 质询续订或生成 Let's Encrypt 通配符证书会失败?¶
如果您尝试通过 DNS 质询续订通配符证书, 并且遇到如下错误:
msg="Error renewing certificate from LE: {example.com [*.example.com]}"
providerName=letsencrypt.acme error="error: one or more domains had a problem:
[example.com] acme: error presenting token: gandiv5: unexpected authZone example.com. for fqdn example.com."
那么原因可能与 CNAME 支持有关。
此时,应确保基础设施已正确配置,能够进行
DNS 质询,而且该质询不依赖 CNAME,并尝试通过以下方式禁用 CNAME 支持:
LEGO_DISABLE_CNAME_SUPPORT=true
在生产环境使用 Traefik OSS?
如果你在工作中使用 Traefik,可以考虑为 Traefik OSS 增加企业级 API 网关能力或商业支持。
为 Traefik OSS 增加 API 网关能力快捷且平滑,无需推倒重来,现有配置也会完整保留。请通过这个简短视频了解实际效果。