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
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: supersecretTraefikService WRR 第一层
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: 1TraefikService WRR 第二层
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: 1Kubernetes Services
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: app3Secret
apiVersion: v1
kind: Secret
metadata:
name: supersecret
namespace: apps
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=配置选项
| 字段 | 描述 | 默认值 | 必填 |
|---|---|---|---|
services | 任何 TraefikService 和 Service 的组合列表。完整的选项列表在 Service 文档中。 | 否 | |
services[m].weight | Service 权重。 | "" | 否 |
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
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
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:
# 假设 `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
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: supersecretTraefikService HRW
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: 15Kubernetes Services
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].name | Service 名称。字符 @ 不允许。 | "" | 是 |
services[m].namespace | Service 命名空间。 | "" | 否 |
services[m].port | Service 端口(数字或端口名称)。仅在 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.sameSite | SameSite 策略。允许值(不区分大小写):- none - lax - strict。 | "" | 否 |
services[m].sticky.cookie.maxAge | cookie 过期前的秒数。 | 0 | 否 |
services[m].strategy | 服务器之间的负载均衡策略。RoundRobin 是目前唯一支持的值。 | "RoundRobin" | 否 |
services[m].nativeLB | 允许使用 Kubernetes Service 在 pod 之间进行负载均衡。 | false | 否 |
services[m].nodePortLB | 当 service 类型为 NodePort 时使用 nodePort IP 地址。 | false | 否 |
HRW 的工作原理
最高随机权重算法将一致性哈希与加权负载均衡相结合:
- 一致性哈希:对于每个传入的请求,对客户端的远程地址进行哈希以确保一致的路由。
- 加权选择:每个 service 都根据客户端 IP 的哈希值和 service 的权重分配一个随机值。
- 最高选择:计算出最高值的 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
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 进行镜像
# 从 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) 进行镜像
# 从 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: 10Kubernetes Services
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
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 进行故障转移
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) 进行故障转移
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 的故障转移
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: 1048576Kubernetes Services
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 的商业支持。