跳到正文
Træfɪk

Service

Service 是 Traefik HTTP 服务的实现。

Service 没有专用 CRD,而是以下资源的一部分:

请注意,创建 IngressRoute 或 TraefikService 对象前,需要将 Traefik Kubernetes CRD 应用到 Kubernetes 集群。

这会注册 Traefik 专用资源。

配置示例

可以按以下方式将 Service 声明为 IngressRoute 或 TraefikService 的一部分:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: test-name
  namespace: apps
spec:
  entryPoints:
    - web
  routes:
  - kind: Rule
    # Rule on the Host
    match: Host(`test.example.com`)
    services:
    # Target a Kubernetes Service
    - kind: Service
      name: foo
      namespace: apps
      # Customize the connection between Traefik and the backend
      passHostHeader: true
      port: 80
      responseForwarding:
        flushInterval: 1ms
      scheme: https
      sticky:
        cookie:
          httpOnly: true
          name: cookie
          secure: true
      strategy: wrr
      # Attach middlewares to this service
      middlewares:
        - name: my-middleware
          namespace: apps
apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: wrr1
  namespace: apps

spec:
  weighted:
    services:
    # Target a Kubernetes Service
    - kind: Service
      name: foo
      namespace: apps
      # Customize the connection between Traefik and the backend
      passHostHeader: true
      port: 80
      responseForwarding:
        flushInterval: 1ms
      scheme: https
      sticky:
        cookie:
          httpOnly: true
          name: cookie
          secure: true
      strategy: wrr

配置选项

字段 说明 默认值 必填
kind 目标服务类型。
允许两个值:
- Service:Kubernetes Service
TraefikService:Traefik 服务。
详见 ExternalName 服务。
"Service" 否
name 服务名称。
不允许使用字符 @。
详见中间件。
是
namespace 服务命名空间。
服务与 IngressRoute 位于同一命名空间时可以留空。
详见 ExternalName 服务。
否
port 服务端口,可以是端口号或端口名称。
仅当类型为 Service 时生效。
否
responseForwarding.
flushInterval
复制响应体时,向客户端刷新数据的间隔,单位为毫秒。
负值表示每次写入客户端后立即刷新。
流式响应会忽略此配置,所有写入都会立即刷新到客户端。
仅当类型为 Service 时生效。
100ms 否
scheme 向上游 Kubernetes Service 发起请求时使用的协议。
仅当类型为 Service 时生效。
"http"
如果 port 为 443 或包含字符串 https,则为 "https"。
否
serversTransport 用于配置 Traefik 与服务器之间传输行为的 ServersTransport 资源名称。
仅当类型为 Service 时生效。
"" 否
passHostHeader 将客户端 Host 请求头转发给服务器。
仅当类型为 Service 时生效。
true 否
healthCheck.scheme 健康检查端点的服务器 URL 协议。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
"" 否
healthCheck.mode 健康检查模式。
设置为 grpc 时,使用 gRPC 健康检查协议探测服务器。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
"http" 否
healthCheck.path 健康检查端点的服务器 URL 路径。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
"" 否
healthCheck.interval 对健康目标执行健康检查的频率。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
"30s" 否
healthCheck.unhealthyInterval 对不健康目标执行健康检查的频率。
未定义时,使用 interval 的值。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
"30s" 否
healthCheck.method 健康检查端点使用的 HTTP 方法。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
"GET" 否
healthCheck.status 健康检查响应的预期 HTTP 状态码。
仅适用于 ExternalName 类型的 Kubernetes 服务。
未设置时,预期状态码为 200 到 399。
仅当类型为 Service 时生效。
否
healthCheck.port 健康检查端点的 URL 端口。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
否
healthCheck.timeout 判定服务器不健康之前允许等待的最长时间。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
"5s" 否
healthCheck.hostname 健康检查请求的 Host 请求头值。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
"" 否
healthCheck.
followRedirect
健康检查是否跟随重定向。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
true 否
healthCheck.headers 发送到健康检查端点的请求头映射。
仅当类型为 Service 时生效。
仅适用于 ExternalName 类型的 Kubernetes 服务。
否
sticky.
cookie.name
用于会话粘性的 Cookie 名称。
启用粘性会话后,初始响应会设置 Set-Cookie 响应头,让客户端知道由哪台服务器处理第一次响应。
后续请求中,客户端应发送带有该值的 Cookie,以便保持与同一服务器的会话。
如果 Cookie 指定的服务器不再健康,请求将转发给新服务器,并通过 Cookie 记录新服务器。
仅当类型为 Service 时生效。
"" 否
sticky.
cookie.httpOnly
禁止 JavaScript 等客户端 API 访问该 Cookie。
仅当类型为 Service 时生效。
false 否
sticky.
cookie.secure
仅允许通过加密连接(即 HTTPS)传输该 Cookie。
仅当类型为 Service 时生效。
false 否
sticky.
cookie.sameSite
SameSite 策略。
允许值:
-none
-lax
strict
仅当类型为 Service 时生效。
"" 否
sticky.
cookie.maxAge
Cookie 过期前的秒数。
负数表示立即过期。
0 表示永不过期。
仅当类型为 Service 时生效。
0 否
sticky.
cookie.path
浏览器发送 Cookie 请求头时,请求 URL 必须包含的路径。
未设置时,对该域的每个请求都会发送 Cookie。
仅当类型为 Service 时生效。
"/" 否
sticky.
cookie.domain
发送 Cookie 的目标主机。
仅当类型为 Service 时生效。
"" 否
strategy 定义服务器之间的负载均衡策略。
支持 wrr(加权轮询)、p2c(双随机选择)、hrw(最高随机权重)和 leasttime(最短时间)。
仅当类型为 Service 时生效。
"wrr" 否
nativeLB 允许使用 Kubernetes Service 提供的 Pod 间负载均衡,而不是 Traefik 自身的负载均衡。
仅当类型为 Service 时生效。
false 否
nodePortLB 服务类型为 NodePort 时使用 nodePort IP 地址。
这样,当 Traefik 运行在 Kubernetes 集群外部、但与节点位于同一网络时,仍能访问服务。
仅当类型为 Service 时生效。
false 否
middlewares 应用到服务的 Middleware 资源引用列表。
这些中间件对该服务处理的所有请求生效,与转发请求的路由器无关。
仅当类型为 Service 时生效。
详见中间件。
否
middlewares[n].name 中间件名称。
不允许使用字符 @。
是
middlewares[n].namespace 中间件命名空间。
中间件与 IngressRoute 位于同一命名空间时可以留空。
否

ExternalName 服务

Traefik 创建后端时必须指定端口,但 Kubernetes 的 ExternalName Service 可以不定义端口。因此,Traefik 支持以下两种端口定义方式:

  • 仅在 IngressRoute 的服务中定义
  • 在两端都定义;如果端口不匹配,会发出警告,并使用 IngressRoute 服务中的端口

因此,在两端都定义端口时,Traefik 期望它们相互匹配。

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: 80
apiVersion: v1
kind: Service
metadata:
  name: external-svc
  namespace: apps

spec:
  externalName: external.domain
  type: ExternalName
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
apiVersion: v1
kind: Service
metadata:
  name: external-svc
  namespace: apps

spec:
  externalName: external.domain
  type: ExternalName
  ports:
    - port: 80
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: 80
apiVersion: v1
kind: Service
metadata:
  name: external-svc
  namespace: apps

spec:
  externalName: external.domain
  type: ExternalName
  ports:
    - port: 80

端口定义

Traefik 创建后端时必须指定端口,但 Kubernetes 的 ExternalName Service 可以不定义端口。因此,Traefik 支持以下两种端口定义方式:

  • 仅在 IngressRoute 的服务中定义
  • 在两端都定义;如果端口不匹配,会发出警告,并使用 IngressRoute 服务中的端口

因此,在两端都定义端口时,Traefik 期望它们相互匹配。

示例
---
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
---
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 负载均衡:

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: default
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

Kubernetes Service 原生负载均衡

如果希望直接使用 Kubernetes Service 的 clusterIP,而不是根据 Pod IP 创建服务器负载均衡器, 应将服务的 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
      # Here, nativeLB instructs to build the server load-balancer with the Kubernetes Service clusterIP only.
      nativeLB: true

---
apiVersion: v1
kind: Service
metadata:
  name: svc
  namespace: default
spec:
  type: ClusterIP
  ...

中间件

可以为每个服务附加一组中间件。 这些中间件对该服务处理的所有请求生效,与转发请求的路由器无关。

有关服务级中间件的更多信息,请参阅服务中间件。

为服务附加中间件
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: default
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: add-header
  namespace: default
spec:
  headers:
    customRequestHeaders:
      X-Custom-Header: "service-middleware"
apiVersion: v1
kind: Service
metadata:
  name: whoami
  namespace: default
spec:
  ports:
    - port: 80
  selector:
    app: whoami

配置后端协议

可以通过以下三种方式配置 Traefik 与 Pod 通信使用的后端协议:

  • 显式设置协议(http/https/h2c)
  • 将 Kubernetes 服务端口的名称设置为以 https 开头(https)
  • 将 Kubernetes 服务端口设置为 443(https)

如果没有上述配置,Traefik 将使用 http 连接。


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

文档由 HeadFile Studio 翻译。

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