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

service 和 fallback 字段各自使用与 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 协议发布