Kubernetes Service
Service 是 Traefik HTTP service 的实现。
没有专用的 CRD,Service 是以下资源的一部分:
请注意,在创建 IngressRoute 或 TraefikService 对象之前,你需要将 Traefik Kubernetes CRDs 应用到你的 Kubernetes 集群。
这会注册 Traefik 专属资源。
配置示例
你可以按如下方式在 IngressRoute 或 TraefikService 中声明 Service:
IngressRoute
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test-name
namespace: apps
spec:
entryPoints:
- web
routes:
- kind: Rule
# 基于 Host 的规则
match: Host(`test.example.com`)
services:
# 目标 Kubernetes Service
- kind: Service
name: foo
namespace: apps
# 自定义 Traefik 与后端之间的连接
passHostHeader: true
port: 80
responseForwarding:
flushInterval: 1ms
scheme: https
sticky:
cookie:
httpOnly: true
name: cookie
secure: true
strategy: wrr
# 将中间件附加到此 service
middlewares:
- name: my-middleware
namespace: appsTraefikService
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
name: wrr1
namespace: apps
spec:
weighted:
services:
# 目标 Kubernetes Service
- kind: Service
name: foo
namespace: apps
# 自定义 Traefik 与后端之间的连接
passHostHeader: true
port: 80
responseForwarding:
flushInterval: 1ms
scheme: https
sticky:
cookie:
httpOnly: true
name: cookie
secure: true
strategy: wrr配置选项
| 字段 | 描述 | 默认值 | 必填 |
|---|---|---|---|
kind | 目标 service 的种类。允许两个值:- Service: Kubernetes Service - TraefikService: Traefik Service。更多信息见下文。 | "Service" | 否 |
name | Service 名称。字符 @ 不允许。 | 是 | |
namespace | Service 命名空间。如果 service 与 IngressRoute 位于同一命名空间,可留空。 | 否 | |
port | Service 端口(数字或端口名称)。仅在 kind 是 Service 时评估。 | 否 | |
responseForwarding.flushInterval | 复制响应 body 时两次刷新之间的间隔(毫秒)。负值表示每次写入客户端后立即刷新。当响应是流式响应时,此配置被忽略。仅在 kind 是 Service 时评估。 | 100ms | 否 |
scheme | 用于向上游 Kubernetes Service 发起请求的协议。仅在 kind 是 Service 时评估。 | "http","https" 当端口为 443 或包含字符串 https | 否 |
serversTransport | 用于配置 Traefik 与服务器之间传输的 ServersTransport 资源名称。仅在 kind 是 Service 时评估。 | "" | 否 |
passHostHeader | 将客户端 Host 头转发到服务器。仅在 kind 是 Service 时评估。 | true | 否 |
healthCheck.scheme | 健康检查端点的服务器 URL 协议。仅对类型为 ExternalName 的 Service 评估。仅在 kind 是 Service 时评估。 | "" | 否 |
healthCheck.mode | 健康检查模式。如果定义为 grpc,将使用 gRPC 健康检查协议探测服务器。仅对类型为 ExternalName 的 Service 评估。仅在 kind 是 Service 时评估。 | "http" | 否 |
healthCheck.path | 健康检查端点的服务器 URL 路径。仅对类型为 ExternalName 的 Service 评估。仅在 kind 是 Service 时评估。 | "" | 否 |
healthCheck.interval | 对健康目标的健康检查调用频率。仅对类型为 ExternalName 的 Service 评估。仅在 kind 是 Service 时评估。 | "100ms" | 否 |
healthCheck.unhealthyInterval | 对不健康目标的健康检查调用频率。未定义时,默认为 interval 值。仅对类型为 ExternalName 的 Service 评估。仅在 kind 是 Service 时评估。 | "100ms" | 否 |
healthCheck.method | 健康检查端点的 HTTP 方法。仅对类型为 ExternalName 的 Service 评估。仅在 kind 是 Service 时评估。 | "GET" | 否 |
healthCheck.status | 健康检查请求响应的预期 HTTP 状态码。仅对类型为 ExternalName 的 Service 评估。如果未设置,期望 200 到 399 之间的状态。仅在 kind 是 Service 时评估。 | 否 | |
healthCheck.port | 健康检查端点的 URL 端口。仅对类型为 ExternalName 的 Service 评估。仅在 kind 是 Service 时评估。 | 否 | |
healthCheck.timeout | 在将服务器视为不健康之前等待的最长时间。仅对类型为 ExternalName 的 Service 评估。仅在 kind 是 Service 时评估。 | "5s" | 否 |
healthCheck.hostname | 健康检查请求的 Host 头的值。仅对类型为 ExternalName 的 Service 评估。仅在 kind 是 Service 时评估。 | "" | 否 |
healthCheck.followRedirect | 在健康检查期间跟随重定向。仅对类型为 ExternalName 的 Service 评估。仅在 kind 是 Service 时评估。 | true | 否 |
healthCheck.headers | 发送到健康检查端点的 header 映射。仅对类型为 ExternalName 的 Service 评估。仅在 kind 是 Service 时评估。 | 否 | |
sticky.cookie.name | 用于粘性的 cookie 名称。启用粘性会话时,会在初始响应上设置 Set-Cookie 头以通知客户端哪个服务器处理了第一个响应。在后续请求中,为了保持与同一服务器的会话,客户端应发送带有设置值的 cookie。如果 cookie 中指定的服务器变为不健康,请求将被转发到新服务器(cookie 将跟踪新服务器)。仅在 kind 是 Service 时评估。 | "" | 否 |
sticky.cookie.httpOnly | 允许 cookie 被客户端 API(如 JavaScript)访问。仅在 kind 是 Service 时评估。 | false | 否 |
sticky.cookie.secure | 允许 cookie 仅通过加密连接(即 HTTPS)传输。仅在 kind 是 Service 时评估。 | false | 否 |
sticky.cookie.sameSite | SameSite 策略。允许值:- none - lax - strict。仅在 kind 是 Service 时评估。 | "" | 否 |
sticky.cookie.maxAge | cookie 过期前的秒数。负数,cookie 立即过期。0,cookie 永不过期。仅在 kind 是 Service 时评估。 | 0 | 否 |
strategy | 定义服务器之间的负载均衡策略。支持的值有:wrr(加权轮询)、p2c(两次选择中取最优)、hrw(最高随机权重)和 leasttime(最少时间)。仅在 kind 是 Service 时评估。 | "RoundRobin" | 否 |
nativeLB | 允许使用 Kubernetes Service 在 pod 之间进行负载均衡,而不是使用 Traefik 提供的负载均衡。仅在 kind 是 Service 时评估。 | false | 否 |
nodePortLB | 当 service 类型为 NodePort 时使用 nodePort IP 地址。它允许在 Traefik 在 Kubernetes 集群外部但在节点同一网络内运行时,service 仍可访问。仅在 kind 是 Service 时评估。 | false | 否 |
middlewares | 要应用于 service 的中间件资源引用列表。中间件将对 service 处理的所有请求生效,无论哪个路由器转发该请求。仅在 kind 是 Service 时评估。更多信息见下文。 | 否 | |
middlewares[n].name | 中间件名称。字符 @ 不允许。 | 是 | |
middlewares[n].namespace | 中间件命名空间。如果中间件与 IngressRoute 位于同一命名空间,可留空。 | 否 |
ExternalName Service
Traefik 后端的创建需要设置一个端口,但 Kubernetes ExternalName Service 可以在没有任何端口的情况下定义。因此,Traefik 支持通过两种方式定义端口:
- 仅在
IngressRouteservice 上 - 两侧都定义,如果端口不匹配会发出警告,使用
IngressRouteservice 端口
因此,如果两侧都定义了端口,Traefik 期望端口匹配。
在资源上定义端口
IngressRoute
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: apps
spec:
entryPoints:
- foo
routes:
- match: Host(`example.net`)
kind: Rule
services:
- name: external-svc
port: 80Service ExternalName
apiVersion: v1
kind: Service
metadata:
name: external-svc
namespace: apps
spec:
externalName: external.domain
type: ExternalName在 Service 上定义端口
IngressRoute
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: apps
spec:
entryPoints:
- foo
routes:
- match: Host(`example.net`)
kind: Rule
services:
- name: external-svcService ExternalName
apiVersion: v1
kind: Service
metadata:
name: external-svc
namespace: apps
spec:
externalName: external.domain
type: ExternalName
ports:
- port: 80两侧都定义端口
IngressRoute
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: apps
spec:
entryPoints:
- foo
routes:
- match: Host(`example.net`)
kind: Rule
services:
- name: external-svc
port: 80Service ExternalName
apiVersion: v1
kind: Service
metadata:
name: external-svc
namespace: apps
spec:
externalName: external.domain
type: ExternalName
ports:
- port: 80端口定义
Traefik 后端的创建需要设置一个端口,但 Kubernetes ExternalName Service 可以在没有任何端口的情况下定义。因此,Traefik 支持通过两种方式定义端口:
- 仅在
IngressRouteservice 上 - 两侧都定义,如果端口不匹配会发出警告,使用
IngressRouteservice 端口
因此,如果两侧都定义了端口,Traefik 期望端口匹配。
示例
IngressRoute
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- foo
routes:
- match: Host(`example.net`)
kind: Rule
services:
- name: external-svc
port: 80
---
apiVersion: v1
kind: Service
metadata:
name: external-svc
namespace: default
spec:
externalName: external.domain
type: ExternalNameExternalName Service
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- foo
routes:
- match: Host(`example.net`)
kind: Rule
services:
- name: external-svc
---
apiVersion: v1
kind: Service
metadata:
name: external-svc
namespace: default
spec:
externalName: external.domain
type: ExternalName
ports:
- port: 80两侧都定义
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- foo
routes:
- match: Host(`example.net`)
kind: Rule
services:
- name: external-svc
port: 80
---
apiVersion: v1
kind: Service
metadata:
name: external-svc
namespace: default
spec:
externalName: external.domain
type: ExternalName
ports:
- port: 80负载均衡
你可以按如下方式声明和使用 Kubernetes Service 负载均衡:
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: svc1
namespace: default
- name: svc2
namespace: defaultK8s Service
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: app2Kubernetes Service 原生负载均衡
要避免使用 pod IP 创建服务器负载均衡器,而直接使用 Kubernetes Service clusterIP,应将 service 的 NativeLB 选项设置为 true。
请注意,默认情况下,Traefik 会重用与后端建立的连接以提升性能。当设置该选项时,这可能会阻止副本之间的请求负载均衡按预期工作。默认情况下,NativeLB 为 false。
示例
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test.route
namespace: default
spec:
entryPoints:
- foo
routes:
- match: Host(`example.net`)
kind: Rule
services:
- name: svc
port: 80
# 此处,nativeLB 指示仅使用 Kubernetes Service clusterIP 构建服务器负载均衡器。
nativeLB: true
---
apiVersion: v1
kind: Service
metadata:
name: svc
namespace: default
spec:
type: ClusterIP
...Middlewares
你可以将 middlewares 列表附加到每个 service。中间件将对 service 处理的所有请求生效,无论哪个路由器转发该请求。
有关 service 级别中间件的更多信息,请参阅 service middlewares。
将中间件附加到 Service
IngressRoute
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: test-name
namespace: default
spec:
entryPoints:
- web
routes:
- kind: Rule
match: Host(`example.com`)
services:
- kind: Service
name: whoami
port: 80
middlewares:
- name: add-header
namespace: defaultMiddleware
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: add-header
namespace: default
spec:
headers:
customRequestHeaders:
X-Custom-Header: "service-middleware"Whoami Service
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: default
spec:
ports:
- port: 80
selector:
app: whoami配置后端协议
有 3 种方式可以配置 Traefik 与 pod 之间的后端通信协议:
- 显式设置协议(http/https/h2c)
- 将 kubernetes service 端口名称配置为以 https 开头(https)
- 将 kubernetes service 端口设置为 443(https)
如果不进行以上配置,Traefik 将假定为 http 连接。
在生产环境使用 Traefik OSS?
如果你在工作中使用 Traefik,可以考虑为其添加企业级 API 网关能力或获取 Traefik OSS 的商业支持。