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 核心功能以及一些扩展功能,如 BackendTLSPolicy、GRPCRoute 和 TLSRoute 资源,以及来自 Experimental channel 的 TCPRoute。

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

部署 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),就必须部署 HTTPRoute、TCPRoute 和/或 TLSRoute 资源,以将一些流量转发到 Kubernetes 后端 services。

附加到 Gateway

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

HTTP/HTTPS ​

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

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

例如,以下 manifest 配置了 whoami 后端及其对应的 HTTPRoute,可通过已部署的 Gateway 在 http://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 filter 是 HTTPRoute 的一个组件,它能够在请求和响应通过路由基础设施时修改它们。

有三种类型的 filter:

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

ExtensionRef Filters

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

例如,以下 manifest 配置了使用 Traefik AddPrefix 中间件的 HTTPRoute,可通过已部署的 Gateway 在 http://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,可通过已部署的 Gateway 在 echo.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,可通过已部署的 Gateway 在 localhost: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,可通过已部署的 Gateway 在 localhost: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 协议发布