Skip to content

Kubernetes Service

ServiceTraefik HTTP service 的实现。

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

请注意,在创建 IngressRouteTraefikService 对象之前,你需要将 Traefik Kubernetes CRDs 应用到你的 Kubernetes 集群。

这会注册 Traefik 专属资源。

配置示例

你可以按如下方式在 IngressRouteTraefikService 中声明 Service

IngressRoute

yaml
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: apps

TraefikService

yaml
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"
nameService 名称。字符 @ 不允许。
namespaceService 命名空间。如果 service 与 IngressRoute 位于同一命名空间,可留空。
portService 端口(数字或端口名称)。仅在 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.sameSiteSameSite 策略。允许值:- none - lax - strict。仅在 kind 是 Service 时评估。""
sticky.cookie.maxAgecookie 过期前的秒数。负数,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 支持通过两种方式定义端口:

  • 仅在 IngressRoute service 上
  • 两侧都定义,如果端口不匹配会发出警告,使用 IngressRoute service 端口

因此,如果两侧都定义了端口,Traefik 期望端口匹配。

在资源上定义端口

IngressRoute

yaml
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

Service ExternalName

yaml
apiVersion: v1
kind: Service
metadata:
  name: external-svc
  namespace: apps

spec:
  externalName: external.domain
  type: ExternalName

在 Service 上定义端口

IngressRoute

yaml
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

Service ExternalName

yaml
apiVersion: v1
kind: Service
metadata:
  name: external-svc
  namespace: apps

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

两侧都定义端口

IngressRoute

yaml
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

Service ExternalName

yaml
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 service 上
  • 两侧都定义,如果端口不匹配会发出警告,使用 IngressRoute service 端口

因此,如果两侧都定义了端口,Traefik 期望端口匹配。

示例

IngressRoute

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

ExternalName Service

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

两侧都定义

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

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: svc1
      namespace: default
    - name: svc2
      namespace: default

K8s Service

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

Kubernetes Service 原生负载均衡

要避免使用 pod IP 创建服务器负载均衡器,而直接使用 Kubernetes Service clusterIP,应将 service 的 NativeLB 选项设置为 true

请注意,默认情况下,Traefik 会重用与后端建立的连接以提升性能。当设置该选项时,这可能会阻止副本之间的请求负载均衡按预期工作。默认情况下,NativeLBfalse

示例

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

yaml
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

Middleware

yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: add-header
  namespace: default
spec:
  headers:
    customRequestHeaders:
      X-Custom-Header: "service-middleware"

Whoami Service

yaml
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 的商业支持。

基于 MIT 协议发布