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
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: traefik
spec:
controllerName: traefik.io/gateway-controller接下来,以下 Gateway manifest 配置正在运行的 Traefik 控制器以处理传入流量。
Listener 端口
请注意,
Gatewaylistener 端口必须与 Traefik 部署配置的 EntryPoint 端口 相匹配。如果它们不匹配,将记录一条ERROR消息,并相应地更新资源状态。
Gateway
---
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: SameSecret
---
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 引用了两个不同的证书:
---
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
---
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: 80Whoami deployment
---
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)
---
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: httpsHTTPRoute (HTTPS)
---
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 请求应返回以下响应:
响应
$ 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 中间件用作
ExtensionReffilter,必须在静态配置中启用 Kubernetes IngressRoute provider,详见文档。
例如,以下 manifest 配置了使用 Traefik AddPrefix 中间件的 HTTPRoute,可通过已部署的 Gateway 在 http://whoami.localhost 地址访问:
HTTPRoute
---
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-prefixAddPrefix middleware
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: add-prefix
namespace: default
spec:
addPrefix:
prefix: /prefixWhoami deployment
---
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 请求应返回以下响应:
响应
$ 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
---
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
---
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-prefixAddPrefix Middleware
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: add-prefix
namespace: default
spec:
addPrefix:
prefix: /apiGRPC
GRPCRoute 是 Gateway API 规范中的扩展资源,旨在定义 GRPC 流量应如何在 Kubernetes 集群内路由。它允许指定将 GRPC 请求定向到适当 Kubernetes 后端 service 的路由规则。
有关资源和概念的更多详细信息,请查看 Kubernetes Gateway API 文档。
例如,以下 manifest 配置了 echo 后端及其对应的 GRPCRoute,可通过已部署的 Gateway 在 echo.localhost:80 地址访问。
GRPCRoute
---
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: 3000Echo deployment
---
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 请求应返回以下响应:
响应
$ 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
---
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: 3000Whoami deployment
---
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 命令应返回以下响应:
响应
$ 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:7d21TLS
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
---
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: 3000Whoami deployment
---
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 命令应返回以下响应:
响应
$ 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 选项覆盖默认值。
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 网关功能既快速又无缝。无需进行替换,所有配置都保持不变。可以通过这个短视频查看实际效果。