traefik 的内部架构图如下:
- 传入请求在endpoints结束,顾名思义,它们是Traefik的网络入口点(侦听端口,SSL,流量重定向......)。
- 然后将流量转发到匹配的frontends。前端定义了从入口点到后端的路由。使用请求字段(主机,路径,标头...)创建路由,并且可以匹配或不匹配请求。然后,frontend将请求发送到后端。
- 后端可以由一个或多个server组成,也可以由负载平衡策略组成。最后,server将请求转发到专用网络中的相应微服务。
Entrypoints
entrypoint 是trafik 的网络入口。可以通过端口,SSL,重定向来定义
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[[entryPoints.https.tls.certificates]]
certFile = "tests/traefik.crt"
keyFile = "tests/traefik.key"
如上例子,定义了两个entrypoint ,一个http , 一个https。他们的端口分别是80和443。通过给定证书和key文件来启用ssl,并rewrite所有的http entrypoint的请求到https
frontends
一个frontend 定义了一组规则来决定如何转发到后端的入口。
规则分为两种:Modifiers 和 Matchers
Modifiers
Modifier规则只修改请求,它们对正在做出的路由决策没有任何影响,下列是已经存在的modifier规则:
AddPrefix: /products:为请求URL路径添加前缀
ReplacePath: /serverless-path:替换path,并把老的path添加到X-Replaced-Path头
ReplacePathRegex: ^/api/v2/(.*) /api/$1:
Matchers
Matchers 用来定义是否将特定的请求转发到后端
用,分割的两个规则表示或, 满足之一即可
使用;分割的规则表示与,需要全部满足
Headers: Content-Type, application/json: 通过 Headers 可以添加一个匹配规则来匹配请求头部包含的值。它接受要匹配的键/值对序列。
HeadersRegexp: Content-Type, application/(text|json): 也可以在 Headers 中使用正则表达式。它接受要匹配的键/值对序列,序列内容解析是通过正则匹配的
Host: traefik.io, www.traefik.io: 匹配请求 Host 必需在给定域名列表内。
HostRegexp: traefik.io, {subdomain:[a-z]+}.traefik.io: 添加匹配请求 Host 的正则表达式。 它接受一个以{}包括起来的为空或更多url变量的模版。变量的值可以以一个可选的正则表达式来匹配。
Method: GET, POST, PUT: Method 可以添加一个HTTP请求方法的匹配。它接受要匹配的一个或多个请求方法序列。
Path: /products/, /articles/{category}/{id:[0-9]+}: Path 可以添加一个URL路径的匹配。它接受一个以{}包括起来的为空或更多url变量的模版。
PathStrip: /products/ 和 Path 相同,但从请求的URL路径中去掉的给定的前缀。
PathStripRegex: /articles/{category}/{id:[0-9]+} 匹配精确的路径,并在转发到后端前剥离路径,接受一组文字和正则路径
PathPrefix: /products/, /articles/{category}/{id:[0-9]+} PathPrefix 可以添加一个URL路径前缀的匹配。它匹配给定模版中的完整URL路径前缀。
PathPrefixStrip: /products/ 和 PathPrefix 相同,但从请求的URL路径中去掉的给定的前缀。
PathPrefixStripRegex: /articles/{category}/{id:[0-9]+} 匹配路径前缀,并在转发到后端前剥离路径,接受一组文字和正则路径,从trafik 1.3开始,剥离的路径将会传递到X-Forwarded-Prefix 头。
Query: foo=bar, bar=baz 匹配查询对象,接受k=v的格式
使用Host 和Path Matchers时,你必须声明一个任意命名的变量,后跟冒号分隔的正则表达式,例如:/posts/{id:[0-9]+}
例子中的id 并没有实际含义, 但你必须定义。
你可以启用passHostHeader变量来转发客户端的Host头到backend,您还可以选择配置passTLSClientCert选项,以将客户端证书到特定header中传递给后端。
PATH MATCHER USAGE GUIDELINES
- 如果您的后端仅侦听确切的路径,请使用Path。例如,Path:/products将匹配/products,但不匹配/products/shoes。
- 使用Prefix matcher,如果你的backend监听特定的基础路径但也在子路径处理请求。例如,PathPrefix: /products 将匹配/products 也匹配/products/shoes and /products/shirts。由于是按照原路径转发。因此,后端需要监听/products
- 如果backend 监听的根路径(/),但也需要路由特定的前缀。 请使用Strip,例如PathPrefixStrip: /products, 将匹配/products、/products/shoes、/products/shirts,由于路径被剥离,因此backend 需要在/监听
如果后端是静态资源服务。它必须返回正确构造的相对URL。
继续这个例子,后端应该返回/products/shoes/image.png(而不是/images.png,Traefik可能无法与同一个后端关联)。可以通过查询请求中的X-Forwarded-Prefix 头来动态构造url规则顺序
当Modifier 和 Matcher 组合使用时,Matcher 规则将始终在Modifier 规则前生效。
下面的规则即是Matcher 也是Modifier,因此Matcher 应用在前,Modifier 应用在后
- PathStrip
- PathStripRegex
- PathPrefixStrip
- PathPrefixStripRegex
无论规则配置部分的顺序如何, 修改器将以预定顺序应用
- PathStrip
- PathPrefixStrip
- PathStripRegex
- PathPrefixStripRegex
- AddPrefix
- ReplacePath
优先级
默认情况下,将使用规则长度(以避免路径重叠)对路由进行排序(以降序排序): - PathPrefix:/ foo;主机:foo.com(length == 28)将在PathPrefixStrip之前匹配:/ foobar(length == 23)将在PathPrefix:/ foo,/ bar(length == 20)之前匹配。
优先级值0将被忽略,因此将计算默认值(规则长度)。
可以在frontend 中自定义优先级,自定义的优先级将覆盖规则长度的计算结果
例如:
[frontends]
[frontends.frontend1]
backend = "backend1"
priority = 20
passHostHeader = true
[frontends.frontend1.routes.test_1]
rule = "PathPrefix:/to"
[frontends.frontend2]
backend = "backend2"
passHostHeader = true
[frontends.frontend2.routes.test_1]
rule = "PathPrefix:/toto"
frontend1 将首先匹配(20>16)
自定义 headers
可以通过前端配置自定义header,以将header添加到与前端规则匹配的请求或响应中。
这允许将诸如X-Script-Name之类的header添加到请求中,或者将自定义header添加到响应中。
如果自定义header名称与请求或响应的一个header名称相同,则将替换它
例子1:路径/cheese的所有匹配都会将X-Script-Name标头添加到代理请求中,并将X-Custom-Response-Header标头添加到响应中。
[frontends]
[frontends.frontend1]
backend = "backend1"
[frontends.frontend1.headers.customresponseheaders]
X-Custom-Response-Header = "True"
[frontends.frontend1.headers.customrequestheaders]
X-Script-Name = "test"
[frontends.frontend1.routes.test_1]
rule = "PathPrefixStrip:/cheese"
Backends
backend负责将来自一个或多个前端的流量负载平衡到一组http服务器。
Servers
只使用url定义server,你也可以通过自定义weight给每一个server
Load-balancing
支持两种负载均衡算法:
- wrr:加权轮训
- drr:动态轮训,增加weight 当server 的表现比其他好。也可以回到原来的weight ,当server 发生变化。
Circuit breakers
可以在backend 上应用断路器来避免故障服务器上的高负载。初始状态是Standby(待机)。断路器观察统计数据,但是不修改请求。当满足某个条件,断路器进入Tripped(跳闸)状态。它用预定义的代码响应或重定向到另一个frontend (?),一旦Tripped计时器到期,断路器进入恢复状态并重启所有状态,如果条件不匹配并且恢复计时器到期,断路器将进入Standby状态。
可以通过以下方式配置:
Methods:LatencyAtQuantileMS, NetworkErrorRatio, ResponseCodeRatio
Operators: AND, OR, EQ, NEQ, LT, LE, GT, GE - NetworkErrorRatio() > 0.5: 监控网络故障率大于0.5超过10秒后,为这个前端平滑切换,断路条件匹配
- LatencyAtQuantileMS(50.0) > 50: 监控延迟超过50ms时断路条件匹配
- ResponseCodeRatio(500, 600, 0, 600) > 0.5: 监控返回 HTTP状态码在[500-600]之间的数量/HTTP状态码在[0-600]之间的数量 的比例大于0.5时,断路条件匹配
Maximum connections
为了主动防止后端因高负载而不堪重负,最大连接限制也可以应用于每个后端。
可以通过为maxconn.amount和maxconn.extractorfunc指定一个整数值来配置最大连接数,这是一种策略,用于确定如何对请求进行分类以评估最大连接数。
例子:
[backends]
[backends.backend1]
[backends.backend1.maxconn]
amount = 10
extractorfunc = "request.host"
backend1 将会返回HTTP CODE 429 Too Many Requests 如果同一主机头的请求已经有10个在处理。
extractorfunc的另一个可能值是client.ip,它将根据客户端源ip对请求进行分类。
最后,extractorfunc可以获取request.header.ANY_HEADER的值,该值将根据您提供的ANY_HEADER对请求进行分类。
Sticky sessions
两种负载均衡都支持粘性会话。
启用粘性会话时,会在初始请求上设置cookie。默认cookie名称是sha1的缩写,在后续请求中,如果客户端仍然健康,则会将客户端定向到存储在cookie中的后端。如果没有,将分配新的后端。
health check
可以设置健康检查以便从LB的轮训中剔除不健康的后端。如过后端持续返回非2XX 或者 3XX 的状态码。traefik 定期执行Get 请求
通过一个后端的path 和检查周期(执定多久进行一次,默认30s)来定义一个healthcheck。每个backend必须在5秒内响应健康检查。
默认情况下,使用后端服务器的端口,但是,可以覆盖此端口。
一个恢复的后端返回2XX 和3XX的响应将会被再次添加进Lb 的轮询池
原文地址:https://www.cnblogs.com/itanony/p/11037512.html