跳到正文
Træfɪk

TraefikService

TraefikService 是建立在 Kubernetes Service 之上的自定义资源,提供在 Kubernetes Service 之间进行加权轮询、最高随机权重负载均衡、流量镜像和故障转移等高级能力。

服务定义如何访问最终处理传入请求的实际端点。在 Traefik 中,目标可以是暴露 Pod 的标准 Kubernetes 服务,也可以是 TraefikService。后者允许组合以下高级负载均衡选项:

加权轮询

WRR 根据权重在多个服务之间分配请求。WRR TraefikService 可以在 Kubernetes Service 和其他 TraefikService 实例(另一个 WRR 服务或镜像服务)之间进行流量负载均衡。

配置示例

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: test-name
  namespace: apps

spec:
  entryPoints:
  - websecure
  routes:
  - match: Host(`example.com`) && PathPrefix(`/foo`)
    kind: Rule
    services:
    # Set a WRR TraefikService
    - name: wrr1
      namespace: apps
      kind: TraefikService
  tls:
    # Add a TLS certificate from a Kubernetes Secret
    secretName: supersecret
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: wrr1
  namespace: apps

spec:
  weighted:
    services:
        # Kubernetes Service
      - name: svc1
        namespace: apps
        port: 80
        weight: 1
        # Second level WRR service
      - name: wrr2
        namespace: apps
        kind: TraefikService
        weight: 1
        # Mirroring service
        # The service is described in the Mirroring example
      - name: mirror1
        namespace: apps
        kind: TraefikService
        weight: 1
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: wrr2
  namespace: apps

spec:
  weighted:
    services:
      # Kubernetes Service
      - name: svc2
        namespace: apps
        port: 80
        weight: 1
      # Kubernetes Service
      - name: svc3
        namespace: apps
        port: 80
        weight: 1
apiVersion: v1
kind: Service
metadata:
  name: svc1
  namespace: apps

spec:
  ports:
  - name: http
      port: 80
  selector:
    app: traefiklabs
    task: app1
---
apiVersion: v1
kind: Service
metadata:
  name: svc2
  namespace: apps

spec:
  ports:
  - name: http
    port: 80
  selector:
    app: traefiklabs
    task: app2
---
apiVersion: v1
kind: Service
metadata:
  name: svc3
  namespace: apps

spec:
  ports:
  - name: http
    port: 80
  selector:
    app: traefiklabs
    task: app3
apiVersion: v1
kind: Secret
metadata:
  name: supersecret
  namespace: apps

data:
  tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
  tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=

配置选项

字段 说明 默认值 必填
services 由 TraefikService 和 Kubernetes 服务任意组合构成的列表。
完整选项见 Service 文档。
否
services[m].weight 服务权重。 "" 否
sticky.
cookie.name
WRR 服务级别用于会话粘性的 Cookie 名称。
启用粘性会话后,初始响应会设置 Set-Cookie 响应头,让客户端知道由哪台服务器处理第一次响应。
后续请求中,客户端应发送带有该值的 Cookie,以保持与同一服务器的会话。
如果 Cookie 指定的服务器不再健康,请求将转发给新服务器,并通过 Cookie 记录新服务器。
更多信息请参阅多层粘性。
sha1 的缩写
(例如 _1d52e)。
否
sticky.
cookie.httpOnly
启用后,阻止 JavaScript 等客户端 API 访问 WRR 服务级别用于会话粘性的 Cookie。
译注:上游此处将 HttpOnly 的作用误写为允许脚本访问;此处依据 RFC 6265 第 4.1.2.6 节修正。
更多信息请参阅多层粘性。
false 否
sticky.
cookie.secure
仅允许通过加密连接(即 HTTPS)传输 WRR 服务级别用于会话粘性的 Cookie。
更多信息请参阅多层粘性。
false 否
sticky.
cookie.sameSite
WRR 服务级别用于会话粘性的 Cookie 的 SameSite 策略。
允许值:
-none
-lax
-strict
-None
-Lax
-Strict
更多信息请参阅多层粘性。
"" 否
sticky.
cookie.maxAge
WRR 服务级别用于会话粘性的 Cookie 过期前的秒数。
负数表示立即过期。
0 表示永不过期。
0 否

多层粘性

链式组合或混合使用负载均衡器时,例如服务器负载均衡器是服务负载均衡器的一个“子级”, 若希望粘性贯穿整个请求路径,就必须在所有需要的层级配置该选项。 这意味着客户端需要在 Cookie 中发送与粘性层级数量相同的键值对。

要让粘性会话在整个路径上生效,必须在每个负载均衡层级指定粘性会话。

例如,下例中两个 whoami 服务之间存在一次加权轮询负载均衡,因此构成第一级; 每个 whoami 服务又是一个 replicaset,会作为服务器负载均衡器处理,因此构成第二级。

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: ingressroutebar
  namespace: apps

spec:
  entryPoints:
  - web
  routes:
  - match: Host(`example.com`) && PathPrefix(`/foo`)
    kind: Rule
    services:
    - name: wrr1
      namespace: apps
      kind: TraefikService
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: wrr1
  namespace: apps

spec:
  weighted:
    services:
    - name: whoami1
      kind: Service
      port: 80
      weight: 1
      # Stickiness level2 (on the Kubernetes service)
      sticky:
        cookie:
        name: lvl2
    - name: whoami2
      kind: Service
      weight: 1
      port: 80
      # Stickiness level2 (on the Kubernetes service)
      sticky:
        cookie:
        name: lvl2
  # Stickiness level2 (on the WRR service)
  sticky:
    cookie:
    name: lvl1

上例中,客户端为了始终与同一服务器保持会话,需要在每次请求的 Cookie 中指定两个层级,例如使用 curl:

# Assuming `10.42.0.6` is the IP address of one of the replicas (a pod then) of the `whoami1` service.
curl -H Host:example.com -b "lvl1=default-whoami1-80; lvl2=http://10.42.0.6:80" http://localhost:8000/foo

最高随机权重

HRW(最高随机权重)负载均衡器通过一致性哈希,确保来自同一客户端 IP 的请求始终路由到同一服务。与按权重分配请求的加权轮询不同,HRW 根据客户端的远端地址提供一致的路由结果。

这特别适合不依赖粘性 Cookie 的会话亲和性,因为同一客户端会根据其 IP 地址持续访问同一个后端服务。

配置示例

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: test-hrw
  namespace: apps

spec:
  entryPoints:
  - websecure
  routes:
  - match: Host(`example.com`) && PathPrefix(`/app`)
    kind: Rule
    services:
    # Set an HRW TraefikService
    - name: hrw1
      namespace: apps
      kind: TraefikService
  tls:
    secretName: supersecret
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: hrw1
  namespace: apps

spec:
  highestRandomWeight:
    services:
      # Kubernetes Service with weight 10
      - name: svc1
        namespace: apps
        port: 80
        weight: 10
      # Kubernetes Service with weight 20
      - name: svc2
        namespace: apps
        port: 80
        weight: 20
      # Another TraefikService
      - name: wrr1
        namespace: apps
        kind: TraefikService
        weight: 15
apiVersion: v1
kind: Service
metadata:
  name: svc1
  namespace: apps

spec:
  ports:
  - name: http
    port: 80
  selector:
    app: traefiklabs
    task: app1
---
apiVersion: v1
kind: Service
metadata:
  name: svc2
  namespace: apps

spec:
  ports:
  - name: http
    port: 80
  selector:
    app: traefiklabs
    task: app2

配置选项

字段 说明 默认值 必填
services 由 TraefikService 和 Kubernetes 服务任意组合构成的列表。每个服务必须分配权重。 是
services[m].
kind
目标服务类型。
允许两个值:
- Service:Kubernetes Service
- TraefikService:Traefik 服务。
"" 否
services[m].
name
服务名称。
不允许使用字符 @。
"" 是
services[m].
namespace
服务命名空间。 "" 否
services[m].
port
服务端口,可以是端口号或端口名称。
仅当类型为 Service 时生效。
"" 否
services[m].
weight
HRW 算法使用的服务权重。对同一个客户端 IP,权重越高的服务被选中的概率越大。 1 否
services[m].
responseForwarding.
flushInterval
复制响应体时,向客户端刷新数据的间隔,单位为毫秒。
负值表示每次写入客户端后立即刷新。
流式响应会忽略此配置,所有写入都会立即刷新到客户端。
仅当类型为 Service 时生效。
100ms 否
services[m].
scheme
向上游 Kubernetes Service 发起请求时使用的协议。
仅当类型为 Service 时生效。
"http"
如果 port 为 443 或包含字符串 https,则为 "https"。
否
services[m].
serversTransport
用于配置 Traefik 与服务器之间传输行为的 ServersTransport 资源名称。
仅当类型为 Service 时生效。
"" 否
services[m].
passHostHeader
将客户端 Host 请求头转发给服务器。
仅当类型为 Service 时生效。
true 否
services[m].
healthCheck.scheme
健康检查端点的服务器 URL 协议。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
"" 否
services[m].
healthCheck.mode
健康检查模式。
设置为 grpc 时,使用 gRPC 健康检查协议探测服务器。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
"http" 否
services[m].
healthCheck.path
健康检查端点的服务器 URL 路径。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
"" 否
services[m].
healthCheck.interval
对健康目标执行健康检查的频率。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
"30s" 否
services[m].
healthCheck.unhealthyInterval
对不健康目标执行健康检查的频率。
未定义时,使用 interval 的值。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
"30s" 否
services[m].
healthCheck.method
健康检查端点使用的 HTTP 方法。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
"GET" 否
services[m].
healthCheck.status
健康检查响应的预期 HTTP 状态码。
仅适用于 ExternalName 类型的 Kubernetes 服务。
未设置时,预期状态码为 200 到 399。
仅当类型为 Service 时生效。
否
services[m].
healthCheck.port
健康检查端点的 URL 端口。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
否
services[m].
healthCheck.timeout
判定服务器不健康之前允许等待的最长时间。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
"5s" 否
services[m].
healthCheck.hostname
健康检查请求的 Host 请求头值。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
"" 否
services[m].
healthCheck.
followRedirect
健康检查是否跟随重定向。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
true 否
services[m].
healthCheck.headers
发送到健康检查端点的请求头映射。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
否
services[m].
sticky.
cookie.name
用于会话粘性的 Cookie 名称。
仅当类型为 Service 时生效。
sha1 的缩写
(例如 _1d52e)。
否
services[m].
sticky.
cookie.httpOnly
启用后,阻止 JavaScript 等客户端 API 访问该 Cookie。
译注:上游此处将 HttpOnly 的作用误写为允许脚本访问;此处依据 RFC 6265 第 4.1.2.6 节修正。
仅当类型为 Service 时生效。
false 否
services[m].
sticky.
cookie.secure
仅允许通过加密连接(即 HTTPS)传输该 Cookie。
仅当类型为 Service 时生效。
false 否
services[m].
sticky.
cookie.sameSite
SameSite 策略。
允许值不区分大小写:
-none
-lax
-strict
-None
-Lax
-Strict
仅当类型为 Service 时生效。
"" 否
services[m].
sticky.
cookie.maxAge
Cookie 过期前的秒数。
负数表示立即过期。
0 表示永不过期。
仅当类型为 Service 时生效。
0 否
services[m].
strategy
服务器之间的负载均衡策略。
支持值:wrr、p2c、hrw、leasttime。
仅当类型为 Service 时生效。
"wrr" 否
services[m].
nativeLB
允许使用 Kubernetes Service 提供的 Pod 间负载均衡,而不是 Traefik 自身的负载均衡。
具体而言,将 nativeLB 设为 true 会让 Traefik 将流量路由到 Kubernetes Service,使用 kube-proxy、Cilium、Calico 等集群网络机制,并由 Kubernetes 自身执行负载均衡。
设为 false 时,Traefik 直接将流量路由到 Pod,并在内部作出负载均衡决策。
无论 nativeLB 如何配置,Traefik 默认都会为了性能复用已建立的后端连接。但连接复用与 nativeLB: true 结合时可能造成负载不均;如果无法接受,可以将 maxIdleConnsPerHost 设为 -1 以禁用连接复用。
仅当类型为 Service 时生效。
false 否
services[m].
nodePortLB
服务类型为 NodePort 时使用 nodePort IP 地址。
这样,当 Traefik 运行在 Kubernetes 集群外部、但与节点位于同一网络时,仍能访问服务。
仅当类型为 Service 时生效。
false 否

HRW 的工作原理

最高随机权重算法将一致性哈希与加权负载均衡结合:

  1. 一致性哈希:对每个传入请求的客户端远端地址进行哈希,确保路由一致性。
  2. 加权选择:根据客户端 IP 的哈希值与服务权重,为每个服务计算一个随机值。
  3. 选择最大值:将请求发送给计算结果最大的服务。

这种方式具有以下优点:

  • 会话亲和性:客户端持续访问同一个后端服务
  • 加权分配:权重更高的服务更容易被选中
  • 无需状态:与粘性 Cookie 不同,无需客户端或服务端维护状态
  • 容错:某个服务不可用时,请求会以一致的方式重新分配给其余服务

流量镜像

流量镜像可以将发往某个服务的请求复制到其他服务。

镜像服务允许同时将流量发送给多个服务:

  • 主服务接收 100% 的流量,
  • 镜像服务接收指定百分比的流量。

例如升级应用版本时,可以将当前版本对应的服务设为主服务,将新版本对应的服务设为镜像服务。 这样就能在保持当前版本可访问的同时,开始测试新版本的行为。

镜像 TraefikService 可以引用 Kubernetes Service 和其他 TraefikService 实例,例如另一个 WRR 服务或镜像服务。

请注意,默认情况下,镜像操作会将整个请求缓存在内存中。 如何修改此行为,请参阅下例中的 maxBodySize 选项。

配置示例

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: ingressroutebar
  namespace: default

spec:
  entryPoints:
    - web
  routes:
  - match: Host(`example.com`) && PathPrefix(`/foo`)
    kind: Rule
    services:
    - name: mirror1
      namespace: default
      kind: TraefikService
# Mirroring from a k8s Service
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: mirror1
  namespace: default

spec:
  mirroring:
    name: svc1                      # svc1 receives 100% of the traffic
    port: 80
    mirrorBody: true                # Default: true
    maxBodySize: 1048576
    mirrors:
      - name: svc2                  # svc2 receives a copy of 20% of this traffic
        port: 80
        percent: 20
      - name: svc3                  # svc3 receives a copy of 15% of this traffic
        kind: TraefikService
        percent: 15
# Mirroring from a Traefik Service
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: mirror1
  namespace: default

spec:
  mirroring:
    name: wrr1                      # wrr1 receives 100% of the traffic
    kind: TraefikService
    mirrors:
      - name: svc2                  # svc2 receives a copy of 20% of this traffic
        port: 80
        percent: 20
      - name: svc3                  # svc3 receives a copy of 10% of this traffic
        kind: TraefikService
        percent: 10
apiVersion: v1
kind: Service
metadata:
  name: svc1
  namespace: default

spec:
  ports:
    - name: http
      port: 80
  selector:
    app: traefiklabs
    task: app1
---
apiVersion: v1
kind: Service
metadata:
  name: svc2
  namespace: default

spec:
  ports:
    - name: http
      port: 80
  selector:
    app: traefiklabs
    task: app2

配置选项

主服务选项

主服务属性直接设置在选项的根层级。

主服务提供与 Service 相同的选项。

完整的服务选项见 Service 文档。 镜像主服务的专用选项如下。

字段 说明 默认值 必填
mirrorBody 定义是否镜像请求体。 true 否
maxBodySize 请求体允许的最大大小。
超过此大小时,不会镜像该请求。
-1 表示大小不受限制。
-1 否
mirrors 目标镜像服务列表。
可以由 TraefikService 和 Kubernetes 服务任意组合构成。
完整选项见 Service 文档。
是

镜像服务选项

镜像服务属性设置在 mirrors 列表中。

镜像服务提供与 Service 相同的选项。

完整的服务选项见 Service 文档。 镜像服务的专用选项如下。

字段 说明 默认值 必填
mirrors[m].percent 路由到该服务的流量百分比。 0 否

故障转移

主服务返回 errors 配置中指定的 HTTP 状态码时,故障转移服务会将所有请求转发到备用服务。

基于健康检查状态的故障转移

目前只能通过 File 提供者为故障转移服务定义 HealthCheck。

配置示例

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: test-name
  namespace: apps

spec:
  entryPoints:
  - websecure
  routes:
  - match: Host(`example.com`) && PathPrefix(`/foo`)
    kind: Rule
    services:
    # Set a Failover TraefikService
    - name: failover1
      namespace: apps
      kind: TraefikService
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: failover1
  namespace: apps

spec:
  failover:
    service:
      name: svc1
      port: 80
    fallback:
      name: svc2
      port: 80
    errors:
      status:
        - "500-503"
        - "429"
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: failover1
  namespace: apps

spec:
  failover:
    service:
      name: wrr1
      kind: TraefikService
    fallback:
      name: wrr2
      kind: TraefikService
    errors:
      status:
        - "500-503"
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: failover1
  namespace: apps

spec:
  failover:
    service:
      name: svc1
      port: 80
    fallback:
      name: svc2
      port: 80
    errors:
      status:
        - "500-503"
        - "429"
      maxRequestBodyBytes: 1048576
apiVersion: v1
kind: Service
metadata:
  name: svc1
  namespace: apps

spec:
  ports:
  - name: http
    port: 80
  selector:
    app: traefiklabs
    task: app1
---
apiVersion: v1
kind: Service
metadata:
  name: svc2
  namespace: apps

spec:
  ports:
  - name: http
    port: 80
  selector:
    app: traefiklabs
    task: app2

配置选项

主服务与备用服务选项

service 和 fallback 字段分别使用与 Service 相同的选项定义目标服务。

完整的服务选项见 Service 文档。

故障转移专用选项

字段 说明 默认值 必填
service 接收转发请求的主服务,提供与 Service 相同的选项。 是
fallback 主服务返回匹配的错误状态码时使用的备用服务,提供与 Service 相同的选项。 是
errors.status 应当切换到备用服务的 HTTP 状态码范围列表。
每项可以是单个状态码,例如 "429",也可以是一个范围,例如 "500-503"。
否
errors.
maxRequestBodyBytes
请求体允许的最大大小。
超过此大小时,不会向备用服务重放请求。
-1 表示大小不受限制。
-1 否

版权所有 © 头文件软件工作室

文档由 HeadFile Studio 翻译。

Traefik v3.7 中文快照 · 原文版权归 Traefik Labs 及贡献者所有 · MIT 许可证