Skip to content

Traefik Kubernetes Services 文档

TraefikService 是一个构建在 Kubernetes Service 之上的自定义资源。它支持高级负载均衡功能,如 Kubernetes Service 之间的 加权轮询(Weighted Round Robin) 负载均衡、最高随机权重(Highest Random Weight) 负载均衡、流量镜像(Mirroring)故障转移(Failover)

Service 用于配置如何访问最终处理传入请求的实际端点。在 Traefik 中,目标 service 可以是标准的 Kubernetes Service(暴露 pod),也可以是 TraefikService。后者允许你组合高级负载均衡选项,例如:

加权轮询(Weighted Round Robin)

WRR 能够根据权重在多个 service 之间对请求进行负载均衡。WRR TraefikService 允许你在 Kubernetes Service 和其它 TraefikService 实例(另一个 WRR service,或镜像 service)之间对流量进行负载均衡。

配置示例

IngressRoute

yaml
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:
    # 设置一个 WRR TraefikService
    - name: wrr1
      namespace: apps
      kind: TraefikService
  tls:
    # 从 Kubernetes Secret 添加 TLS 证书
    secretName: supersecret

TraefikService WRR 第一层

yaml
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: wrr1
  namespace: apps

spec:
  weighted:
    services:
        # Kubernetes Service
      - name: svc1
        namespace: apps
        port: 80
        weight: 1
        # 第二层 WRR service
      - name: wrr2
        namespace: apps
        kind: TraefikService
        weight: 1
        # 镜像 service
        # 该 service 在 Mirroring 示例中描述
      - name: mirror1
        namespace: apps
        kind: TraefikService
        weight: 1

TraefikService WRR 第二层

yaml
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

Kubernetes Services

yaml
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

Secret

yaml
apiVersion: v1
kind: Secret
metadata:
  name: supersecret
  namespace: apps

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

配置选项

字段描述默认值必填
services任何 TraefikService 和 Service 的组合列表。完整的选项列表在 Service 文档中。
services[m].weightService 权重。""
sticky.cookie.name用于 WRR service 级别粘性的 cookie 名称。启用粘性会话时,会在初始响应上设置 Set-Cookie 头以通知客户端哪个服务器处理了第一个响应。在后续请求中,客户端应发送带有设置值的 cookie 以保持与同一服务器的会话。如果 cookie 中指定的服务器变为不健康,请求将被转发到新服务器(cookie 将跟踪新服务器)。有关 WRR 粘性的更多信息。sha1 的缩写(例如:_1d52e)。
sticky.cookie.httpOnly允许用于 WRR service 级别粘性的 cookie 被客户端 API(如 JavaScript)访问。有关 WRR 粘性的更多信息。false
sticky.cookie.secure允许用于 WRR service 级别粘性的 cookie 仅通过加密连接(即 HTTPS)传输。有关 WRR 粘性的更多信息。false
sticky.cookie.sameSite用于 WRR service 级别粘性的 cookie 的 SameSite 策略。允许值:- none - lax - strict - None - Lax - Strict。有关 WRR 粘性的更多信息。""
sticky.cookie.maxAge用于 WRR service 级别粘性的 cookie 过期前的秒数。负数,cookie 立即过期。0,cookie 永不过期。0

多层粘性

当链接或混合负载均衡器时(例如,服务器负载均衡器是 service 负载均衡器的"子项"之一),要使粘性在所有层级都生效,选项需要在所有必需的层级上指定。这意味着客户端需要在 cookie 中发送与粘性层级数一样多的键值对。

例如,在下面的示例中,存在第一层负载均衡,因为有(加权轮询)对两个 whoami service 的负载均衡,还存在第二层,因为每个 whoami service 都是一个 replicaset,因此被作为服务器负载均衡器处理。

IngressRoute

yaml
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

具有 2 层粘性的 TraefikService WRR

yaml
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: wrr1
  namespace: apps

spec:
  weighted:
    services:
    - name: whoami1
      kind: Service
      port: 80
      weight: 1
      # 粘性 level2(Kubernetes service 级别)
      sticky:
        cookie:
        name: lvl2
    - name: whoami2
      kind: Service
      weight: 1
      port: 80
      # 粘性 level2(Kubernetes service 级别)
      sticky:
        cookie:
        name: lvl2
  # 粘性 level2(WRR service 级别)
  sticky:
    cookie:
    name: lvl1

在上面的示例中,要保持与同一服务器的会话,客户端需要在每个请求的 cookie 中为每个级别指定相应的值,例如使用 curl:

bash
# 假设 `10.42.0.6` 是 `whoami1` service 的某个副本(即 pod)的 IP 地址。
curl -H Host:example.com -b "lvl1=default-whoami1-80; lvl2=http://10.42.0.6:80" http://localhost:8000/foo

最高随机权重(Highest Random Weight)

HRW(最高随机权重)负载均衡器使用一致性哈希来确保来自同一客户端 IP 的请求始终被路由到同一 service。与基于权重分配请求的加权轮询不同,HRW 基于客户端的远程地址提供一致的路由。

这对于在没有粘性 cookie 的情况下维护会话亲和性特别有用,因为客户端将根据其 IP 地址一致地到达同一后端 service。

配置示例

IngressRoute

yaml
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:
    # 设置一个 HRW TraefikService
    - name: hrw1
      namespace: apps
      kind: TraefikService
  tls:
    secretName: supersecret

TraefikService HRW

yaml
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: hrw1
  namespace: apps

spec:
  highestRandomWeight:
    services:
      # 权重为 10 的 Kubernetes Service
      - name: svc1
        namespace: apps
        port: 80
        weight: 10
      # 权重为 20 的 Kubernetes Service
      - name: svc2
        namespace: apps
        port: 80
        weight: 20
      # 另一个 TraefikService
      - name: wrr1
        namespace: apps
        kind: TraefikService
        weight: 15

Kubernetes Services

yaml
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 和 Service 的组合列表。每个 service 必须分配权重。
services[m].kind目标 service 的种类。允许两个值:- Service: Kubernetes Service - TraefikService: Traefik Service。""
services[m].nameService 名称。字符 @ 不允许。""
services[m].namespaceService 命名空间。""
services[m].portService 端口(数字或端口名称)。仅在 kind 是 Service 时评估。""
services[m].weight在 HRW 算法中使用的 service 权重。较高的权重会增加给定客户端 IP 被选中的概率。1
services[m].responseForwarding.flushInterval复制响应 body 时两次刷新之间的间隔(毫秒)。100ms
services[m].scheme用于向上游 Kubernetes Service 发起请求的协议。"http""https" 当端口为 443 或包含字符串 https
services[m].serversTransport用于配置 Traefik 与服务器之间传输的 ServersTransport 资源名称。""
services[m].passHostHeader将客户端 Host 头转发到服务器。true
services[m].healthCheck.*各种健康检查选项。仅对类型为 ExternalName 的 Service 评估。
services[m].sticky.cookie.name用于粘性的 cookie 名称。仅在 kind 是 Service 时评估。sha1 的缩写
services[m].sticky.cookie.httpOnly允许 cookie 被客户端 API(如 JavaScript)访问。false
services[m].sticky.cookie.secure允许 cookie 仅通过加密连接(即 HTTPS)传输。false
services[m].sticky.cookie.sameSiteSameSite 策略。允许值(不区分大小写):- none - lax - strict。""
services[m].sticky.cookie.maxAgecookie 过期前的秒数。0
services[m].strategy服务器之间的负载均衡策略。RoundRobin 是目前唯一支持的值。"RoundRobin"
services[m].nativeLB允许使用 Kubernetes Service 在 pod 之间进行负载均衡。false
services[m].nodePortLB当 service 类型为 NodePort 时使用 nodePort IP 地址。false

HRW 的工作原理

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

  1. 一致性哈希:对于每个传入的请求,对客户端的远程地址进行哈希以确保一致的路由。
  2. 加权选择:每个 service 都根据客户端 IP 的哈希值和 service 的权重分配一个随机值。
  3. 最高选择:计算出最高值的 service 接收请求。

这种方法提供了几个好处:

  • 会话亲和性:客户端一致地到达同一后端 service
  • 加权分布:权重较高的 service 更有可能被选中
  • 无需状态:与粘性 cookie 不同,不需要客户端或服务器端状态
  • 容错:如果某个 service 不可用,请求会在剩余 service 之间一致地重新分配

流量镜像(Mirroring)

镜像能够将发送到一个 service 的请求镜像到其它 service。

镜像 service 允许你将流量一起发送到多个 service:

  • service 接收 100% 的流量
  • 镜像 service 接收一定百分比的流量

例如,要升级应用程序的版本。你可以将目标当前版本的 service 设置为 service,将新版本的 service 设置为镜像 service。这样,你就可以开始测试新版本的行为,同时保持当前版本可访问。

镜像 TraefikService 允许你引用 Kubernetes Service 和其它 TraefikService 实例(另一个 WRR service,或镜像 service)。

请注意,默认情况下,在镜像过程中整个请求会被缓存在内存中。有关如何修改此行为,请参阅下面的 maxBodySize 选项。

配置示例

IngressRoute

yaml
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

从 Kubernetes Service 进行镜像

yaml
# 从 k8s Service 镜像
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: mirror1
  namespace: default

spec:
  mirroring:
    name: svc1                      # svc1 接收 100% 的流量
    port: 80
    mirrorBody: true                # 默认为 false
    maxBodySize: 1M
    mirrors:
      - name: svc2                  # svc2 接收此流量的 20% 副本
        port: 80
        percent: 20
      - name: svc3                  # svc3 接收此流量的 15% 副本
        kind: TraefikService
        percent: 15

从 TraefikService (WRR) 进行镜像

yaml
# 从 Traefik Service 镜像
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: mirror1
  namespace: default

spec:
  mirroring:
    name: wrr1                      # wrr1 接收 100% 的流量
    kind: TraefikService
    mirrors:
      - name: svc2                  # svc2 接收此流量的 20% 副本
        port: 80
        percent: 20
      - name: svc3                  # svc3 接收此流量的 10% 副本
        kind: TraefikService
        percent: 10

Kubernetes Services

yaml
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 的属性作为选项根级别设置。

主 service 提供与 Service 相同的选项。完整的 service 选项列表在 Service 文档中描述。镜像主 service 的专用选项如下所述。

字段描述默认值必填
mirrorBody定义是否应镜像请求体。true
maxBodySize请求体允许的最大大小。如果 body 更大,则不镜像请求。-1 表示无限制大小。-1
mirrors要镜像的 service 列表。可以是 TraefikService 和 Service 的任何组合。

镜像 Service 选项

被镜像 service 的属性在 mirrors 列表中设置。

被镜像的 service 提供与 Service 相同的选项。

字段描述默认值必填
mirrors[m].percent路由到该 service 的流量百分比。0

故障转移(Failover)

故障转移 service 在主 service 以 errors 配置中定义的特定 HTTP 状态码响应时,将所有请求转发到回退 service。

Failover 上的 HealthCheck

目前只能使用 File provider 在 Failover service 上定义 HealthCheck。

配置示例

IngressRoute

yaml
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:
    # 设置一个 Failover TraefikService
    - name: failover1
      namespace: apps
      kind: TraefikService

从 Kubernetes Services 进行故障转移

yaml
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"

从 TraefikService (WRR) 进行故障转移

yaml
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"

带 maxRequestBodyBytes 的故障转移

yaml
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

Kubernetes Services

yaml
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 选项

servicefallback 字段各自使用与 Service 相同的选项定义目标 service。完整的 service 选项列表在 Service 文档中描述。

Failover 专用选项

字段描述默认值必填
service用于转发请求的主 service。提供与 Service 相同的选项。
fallback当主 service 返回匹配的错误状态码时使用的回退 service。提供与 Service 相同的选项。
errors.status应使用回退 service 的 HTTP 状态码范围列表。每个条目可以是单个代码(例如 "429")或范围(例如 "500-503")。
errors.maxRequestBodyBytes请求体允许的最大大小。如果 body 更大,则不会重放到回退 service。-1 表示无限制大小。-1

在生产环境使用 Traefik OSS?

如果你在工作中使用 Traefik,可以考虑为其添加企业级 API 网关能力或获取 Traefik OSS 的商业支持。

基于 MIT 协议发布