Skip to content

Traefik Kubernetes Gateway

Traefik 与 Kubernetes 配合使用 Gateway API

当使用 Kubernetes Gateway API provider 时,Traefik 利用 Gateway API 的自定义资源定义(CRD)来获取其路由配置。有关 Gateway API 概念和资源的详细信息,请参阅官方文档

Kubernetes Gateway API provider 支持规范的 v1.5.1 版本。

它完全支持来自 Standard channel 的所有 HTTPRoute 核心功能以及一些扩展功能,如 BackendTLSPolicyGRPCRouteTLSRoute 资源,以及来自 Experimental channelTCPRoute

更多详细信息,请查看一致性 报告

部署 Gateway

Gateway 是 Gateway API 规范中的核心资源,定义了流量进入 Kubernetes 集群的入口点。它与 GatewayClass 相关联,后者指定负责管理和处理流量的控制器,确保流量被定向到适当的 Kubernetes 后端 service。

GatewayClass 是由基础设施 provider 定义的集群范围的资源。以下 GatewayClass 定义了附加到它的 gateway 必须由 Traefik 控制器管理。

GatewayClass

yaml
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: traefik
spec:
  controllerName: traefik.io/gateway-controller

接下来,以下 Gateway manifest 配置正在运行的 Traefik 控制器以处理传入流量。

Listener 端口

请注意,Gateway listener 端口必须与 Traefik 部署配置的 EntryPoint 端口 相匹配。如果它们不匹配,将记录一条 ERROR 消息,并相应地更新资源状态。

Gateway

yaml
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: traefik
  namespace: default
spec:
  gatewayClassName: traefik

  # 仅允许来自同一命名空间的路由。
  listeners:
    - name: http
      protocol: HTTP
      port: 80
      allowedRoutes:
        namespaces:
          from: Same

    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: secret-tls
            namespace: default

      allowedRoutes:
        namespaces:
          from: Same

    - name: tcp
      protocol: TCP
      port: 3000
      allowedRoutes:
        namespaces:
          from: Same

    - name: tls
      protocol: TLS
      port: 3443
      tls:
        mode: Terminate
        certificateRefs:
          - name: secret-tls
            namespace: default

      allowedRoutes:
        namespaces:
          from: Same

Secret

yaml
---
apiVersion: v1
kind: Secret
metadata:
  name: secret-tls
  namespace: default
type: kubernetes.io/tls
data:
  # whoami.localhost 域名的自签名证书。
  tls.crt: |
    ...
  tls.key: |
    ...

多个 TLS 证书

Traefik 支持每个 Gateway listener 的多个 secret certificateRefs。如果其中一个证书无效或无法加载,该 listener 将被视为无效,并且在问题解决之前将无法为流量提供服务。

例如,以下 Gateway listener 引用了两个不同的证书:

yaml
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: multi-cert-gateway
  namespace: default
spec:
  gatewayClassName: traefik
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: example-com-tls
          - name: example-org-tls
      allowedRoutes:
        namespaces:
          from: Same

暴露路由

一旦部署了 Gateway(参见部署 Gateway),就必须部署 HTTPRouteTCPRoute 和/或 TLSRoute 资源,以将一些流量转发到 Kubernetes 后端 services

附加到 Gateway

如下例所示,路由资源必须配置 parentRefs 来引用它应该关联的父 Gateway

HTTP/HTTPS

HTTPRoute 是 Gateway API 规范中的核心资源,旨在定义 HTTP 流量应如何在 Kubernetes 集群内路由。它允许指定将 HTTP 请求定向到适当 Kubernetes 后端 service 的路由规则。

有关资源和概念的更多详细信息,请查看 Kubernetes Gateway API 文档

例如,以下 manifest 配置了 whoami 后端及其对应的 HTTPRoute,可通过已部署的 Gatewayhttp://whoami.localhost 地址访问。

HTTPRoute

yaml
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: whoami-http
  namespace: default
spec:
  parentRefs:
    - name: traefik
      sectionName: http
      kind: Gateway

  hostnames:
    - whoami.localhost

  rules:
     - matches:
        - path:
            type: PathPrefix
            value: /

       backendRefs:
        - name: whoami
          namespace: default
          port: 80

Whoami deployment

yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoami
  namespace: default
spec:
  selector:
    matchLabels:
      app: whoami

  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
        - name: whoami
          image: traefik/whoami

---
apiVersion: v1
kind: Service
metadata:
  name: whoami
  namespace: default
spec:
  selector:
    app: whoami

  ports:
    - port: 80

要使用 HTTPS 保护连接并将非安全请求重定向到安全端点,我们将更新上面的 HTTPRoute manifest,添加一个 RequestRedirect filter,并添加一个新的 HTTPRoute,它绑定到 https Listener 并将流量转发到 whoami 后端。

HTTPRoute (HTTP)

yaml
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: whoami-http
  namespace: default
spec:
  parentRefs:
    - name: traefik
      sectionName: http
      kind: Gateway

  hostnames:
    - whoami.localhost

  rules:
    - filters:
        - type: RequestRedirect
          requestRedirect:
            scheme: https

HTTPRoute (HTTPS)

yaml
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: whoami-https
  namespace: default
spec:
  parentRefs:
    - name: traefik
      sectionName: https
      kind: Gateway

  hostnames:
    - whoami.localhost

  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /

      backendRefs:
        - name: whoami
          namespace: default
          port: 80

一旦部署了所有内容,向 HTTP 和 HTTPS 端点发送 GET 请求应返回以下响应:

响应

bash
$ curl -I http://whoami.localhost

HTTP/1.1 302 Found
Location: https://whoami.localhost/
Date: Thu, 11 Jul 2024 15:11:31 GMT
Content-Length: 5

$ curl -k https://whoami.localhost

Hostname: whoami-697f8c6cbc-2krl7
IP: 127.0.0.1
IP: ::1
IP: 10.42.1.5
IP: fe80::60ed:22ff:fe10:3ced
RemoteAddr: 10.42.2.4:44682
GET / HTTP/1.1
Host: whoami.localhost
User-Agent: curl/7.87.1-DEV
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.42.1.0
X-Forwarded-Host: whoami.localhost
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Forwarded-Server: traefik-6b66d45748-ns8mt
X-Real-Ip: 10.42.1.0

将 Traefik 中间件用作 HTTPRoute filter

HTTP filterHTTPRoute 的一个组件,它能够在请求和响应通过路由基础设施时修改它们。

有三种类型的 filter:

  • Core:每个 Gateway 控制器都必须实现的强制 filter,如 RequestHeaderModifierRequestRedirect
  • Extended:Gateway 控制器的可选 filter,如 ResponseHeaderModifierRequestMirror
  • ExtensionRef:由 Gateway 控制器提供的额外 filter。在 Traefik 中,这些是通过 Middleware CRD 支持的 HTTP middlewares

ExtensionRef Filters

要将 Traefik 中间件用作 ExtensionRef filter,必须在静态配置中启用 Kubernetes IngressRoute provider,详见文档

例如,以下 manifest 配置了使用 Traefik AddPrefix 中间件的 HTTPRoute,可通过已部署的 Gatewayhttp://whoami.localhost 地址访问:

HTTPRoute

yaml
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: whoami-http
  namespace: default
spec:
  parentRefs:
    - name: traefik
      sectionName: http
      kind: Gateway

  hostnames:
    - whoami.localhost

  rules:
    - backendRefs:
        - name: whoami
          namespace: default
          port: 80

      filters:
        - type: ExtensionRef
          extensionRef:
            group: traefik.io
            kind: Middleware
            name: add-prefix

AddPrefix middleware

yaml
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: add-prefix
  namespace: default
spec:
  addPrefix:
    prefix: /prefix

Whoami deployment

yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoami
  namespace: default
spec:
  selector:
    matchLabels:
      app: whoami

  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
        - name: whoami
          image: traefik/whoami

---
apiVersion: v1
kind: Service
metadata:
  name: whoami
  namespace: default
spec:
  selector:
    app: whoami
  ports:
    - port: 80

一旦部署了所有内容,发送 GET 请求应返回以下响应:

响应

bash
$ curl http://whoami.localhost

Hostname: whoami-697f8c6cbc-kw954
IP: 127.0.0.1
IP: ::1
IP: 10.42.2.6
IP: fe80::a460:ecff:feb6:3a56
RemoteAddr: 10.42.2.4:54758
GET /prefix/ HTTP/1.1
Host: whoami.localhost
User-Agent: curl/7.87.1-DEV
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.42.2.1
X-Forwarded-Host: whoami.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: traefik-6b66d45748-ns8mt
X-Real-Ip: 10.42.2.1

后端级别 Filters

除了路由级别 filter 之外,Gateway API 还支持通过 backendRefs[].filters 字段将 filter 直接应用于各个后端。这允许对特定后端应用请求修改,从而启用 HTTPRouteBackendRequestHeaderModification 扩展功能。

支持的 filter 类型

后端级别 filter 支持与路由级别 filter 相同的 filter 类型:

  • RequestHeaderModifier:在转发到后端之前添加、设置或删除 HTTP 请求头。
  • ResponseHeaderModifier:添加、设置或删除 HTTP 响应头。
  • RequestRedirect:将请求重定向到不同的 URL。
  • URLRewrite:重写请求 URL 路径和/或主机名。
  • ExtensionRef:引用 Traefik Middleware 资源。

中间件执行顺序

当同时配置了路由级别和后端级别 filter 时,首先应用路由级别 filter,然后应用后端级别 filter。

有关 service 级别中间件的更多信息,请参阅 service middlewares

在后端上使用 RequestHeaderModifier

HTTPRoute

yaml
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: whoami-http
  namespace: default
spec:
  parentRefs:
    - name: traefik
      sectionName: http
      kind: Gateway

  hostnames:
    - whoami.localhost

  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /

      backendRefs:
        - name: whoami
          namespace: default
          port: 80
          filters:
            - type: RequestHeaderModifier
              requestHeaderModifier:
                set:
                  - name: X-Backend-Header
                    value: "backend-filter"

在后端上使用 ExtensionRef(Traefik 中间件)

HTTPRoute

yaml
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: whoami-http
  namespace: default
spec:
  parentRefs:
    - name: traefik
      sectionName: http
      kind: Gateway

  hostnames:
    - whoami.localhost

  rules:
    - backendRefs:
        - name: whoami
          namespace: default
          port: 80
          filters:
        - type: ExtensionRef
          extensionRef:
            group: traefik.io
            kind: Middleware
            name: add-prefix

AddPrefix Middleware

yaml
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: add-prefix
  namespace: default
spec:
  addPrefix:
    prefix: /api

GRPC

GRPCRoute 是 Gateway API 规范中的扩展资源,旨在定义 GRPC 流量应如何在 Kubernetes 集群内路由。它允许指定将 GRPC 请求定向到适当 Kubernetes 后端 service 的路由规则。

有关资源和概念的更多详细信息,请查看 Kubernetes Gateway API 文档

例如,以下 manifest 配置了 echo 后端及其对应的 GRPCRoute,可通过已部署的 Gatewayecho.localhost:80 地址访问。

GRPCRoute

yaml
---
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: echo
  namespace: default
spec:
  parentRefs:
    - name: traefik
      sectionName: http
      kind: Gateway

  hostnames:
    - echo.localhost

  rules:
    - matches:
        - method:
            type: Exact
            service: grpc.reflection.v1alpha.ServerReflection

        - method:
            type: Exact
            service: gateway_api_conformance.echo_basic.grpcecho.GrpcEcho
            method: Echo

      backendRefs:
        - name: echo
          namespace: default
          port: 3000

Echo deployment

yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo
  namespace: default
spec:
  selector:
    matchLabels:
      app: echo

  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
        - name: echo-basic
          image: gcr.io/k8s-staging-gateway-api/echo-basic
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: GRPC_ECHO_SERVER
              value: "1"

---
apiVersion: v1
kind: Service
metadata:
  name: echo
  namespace: default
spec:
  selector:
    app: echo

  ports:
    - port: 3000

一旦部署了所有内容,向 HTTP 端点发送 GRPC 请求应返回以下响应:

响应

bash
$ grpcurl -plaintext echo.localhost:80 gateway_api_conformance.echo_basic.grpcecho.GrpcEcho/Echo

{
  "assertions": {
    "fullyQualifiedMethod": "/gateway_api_conformance.echo_basic.grpcecho.GrpcEcho/Echo",
    "headers": [
      {
        "key": "x-real-ip",
        "value": "10.42.2.0"
      },
      ...
    ],
    "authority": "echo.localhost:80",
    "context": {
      "namespace": "default",
      "pod": "echo-78f76675cf-9k7rf"
    }
  }
}

TCP

Experimental Channel

下面描述的 TCPRoute 资源目前仅在 Gateway API 规范的 Experimental channel 中可用。要使用此资源,必须在 Traefik 部署中启用 experimentalChannel 配置选项。

TCPRoute 是 Gateway API 规范中的资源,旨在定义 TCP 流量应如何在 Kubernetes 集群内路由。

有关资源和概念的更多详细信息,请查看 Kubernetes Gateway API 文档

例如,以下 manifest 配置了 whoami 后端及其对应的 TCPRoute,可通过已部署的 Gatewaylocalhost:3000 地址访问。

TCPRoute

yaml
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
  name: whoami-tcp
  namespace: default
spec:
  parentRefs:
    - name: traefik
      sectionName: tcp
      kind: Gateway

  rules:
     - backendRefs:
        - name: whoamitcp
          namespace: default
          port: 3000

Whoami deployment

yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoamitcp
  namespace: default
spec:
  selector:
    matchLabels:
      app: whoamitcp

  template:
    metadata:
      labels:
        app: whoamitcp
    spec:
      containers:
        - name: whoami
          image: traefik/whoamitcp
          args:
            - --port=:3000

---
apiVersion: v1
kind: Service
metadata:
  name: whoamitcp
  namespace: default
spec:
  selector:
    app: whoamitcp
  ports:
    - port: 3000

一旦部署了所有内容,发送 WHO 命令应返回以下响应:

响应

bash
$ nc localhost 3000

WHO
Hostname: whoamitcp-85d644bfc-ktzv4
IP: 127.0.0.1
IP: ::1
IP: 10.42.1.4
IP: fe80::b89e:85ff:fec2:7d21

TLS

Experimental Channel

下面描述的 TLSRoute 资源目前仅在 Gateway API 的 Experimental channel 中可用。因此,要使用此资源,必须启用 experimentalChannel 选项。

TLSRoute 是 Gateway API 规范中的资源,旨在定义 TLS(传输层安全)流量应如何在 Kubernetes 集群内路由。它根据传入连接的 SNI(Server Name Indication)指定 TLS 连接的路由规则,将其定向到适当的后端 service。

有关资源和概念的更多详细信息,请查看 Kubernetes Gateway API 文档

例如,以下 manifest 配置了 whoami 后端及其对应的 TLSRoute,可通过已部署的 Gatewaylocalhost:3443 地址通过与 whoami.localhost SNI 的安全连接进行访问。

TLSRoute

yaml
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
  name: whoami-tls
  namespace: default
spec:
  parentRefs:
    - name: traefik
      sectionName: tls
      kind: Gateway

  hostnames:
    - whoami.localhost

  rules:
    - backendRefs:
        - name: whoamitcp
          namespace: default
          port: 3000

Whoami deployment

yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoamitcp
  namespace: default
spec:
  selector:
    matchLabels:
      app: whoamitcp

  template:
    metadata:
      labels:
        app: whoamitcp
    spec:
      containers:
        - name: whoami
          image: traefik/whoamitcp
          args:
            - --port=:3000

---
apiVersion: v1
kind: Service
metadata:
  name: whoamitcp
  namespace: default
spec:
  selector:
    app: whoamitcp
  ports:
    - port: 3000

一旦部署了所有内容,发送 WHO 命令应返回以下响应:

响应

bash
$ openssl s_client -quiet -connect localhost:3443 -servername whoami.localhost
Connecting to ::1
depth=0 C=FR, L=Lyon, O=Traefik Labs, CN=Whoami
verify error:num=18:self-signed certificate
verify return:1
depth=0 C=FR, L=Lyon, O=Traefik Labs, CN=Whoami
verify return:1

WHO
Hostname: whoamitcp-85d644bfc-hnmdz
IP: 127.0.0.1
IP: ::1
IP: 10.42.2.4
IP: fe80::d873:20ff:fef5:be86

原生负载均衡

默认情况下,Traefik 直接将流量发送到 pod IP,并重用与后端建立的连接以提升性能。

可以覆盖此行为,配置 Traefik 将流量发送到 service IP。Kubernetes service 本身负责对 pod 进行负载均衡。可以通过在后端 Service 上使用注解 traefik.io/service.nativelb 来实现。

默认情况下,NativeLB 为 false

默认值

注意,可以通过 provider 级别的 nativeLBByDefault 选项覆盖默认值。

yaml
apiVersion: v1
kind: Service
metadata:
  name: myservice
  namespace: default
  annotations:
    traefik.io/service.nativelb: "true"
spec:
  ports:
    - name: web
      port: 80

在生产环境使用 Traefik OSS?

如果你在工作中使用 Traefik,可以考虑为其添加企业级 API 网关能力或获取 Traefik OSS 的商业支持。

向 Traefik OSS 添加 API 网关功能既快速又无缝。无需进行替换,所有配置都保持不变。可以通过这个短视频查看实际效果。

基于 MIT 协议发布