首页
/ Traefik Kubernetes CRD 指南:使用 ServersTransportTCP 精细控制 Traefik 与 TCP 后端服务的连接

Traefik Kubernetes CRD 指南:使用 ServersTransportTCP 精细控制 Traefik 与 TCP 后端服务的连接

2026-09-07 12:22:15作者:昌雅子Ethen

ServersTransportTCP 是 Traefik 在 Kubernetes 场景下以 CRD(Custom Resource Definition)方式提供的 TCP ServersTransport 实现,用于精细配置 Traefik 与 TCP 后端(backend)之间建立连接时的拨号超时、keep-alive 探测、PROXY Protocol、TLS/mTLS 校验以及连接终止延迟等行为。通过本文你将掌握:如何创建并引用 ServersTransportTCP 资源、如何跨命名空间或跨 Provider 引用它、每个配置字段(含 proxyProtocolterminationDelaytls.rootCAspeerCertSANsspiffe 等)的真实语义与取值范围,以及它从 CRD 到 Traefik 内部动态配置的转换原理。

前置条件:先注册 Traefik CRD

ServersTransportTCP 属于 traefik.io/v1alpha1 API 组。在创建任何 ServersTransportTCP 对象之前,需要先将 Traefik Kubernetes CRDs 应用到你的集群,从而注册 ServersTransportTCP kind 以及 IngressRouteTCPMiddlewareIngressRouteUDP 等 Traefik 专有资源。

官方发行时通过 kubectl apply -f 安装一份聚合的 CRD 清单;在本仓库中可参考同源清单 integration/fixtures/k8s/01-traefik-crd.yml(其中定义了 traefik.io/v1alpha1 下的全部资源,包括 ServersTransportTCP)。CRD 的类型定义本身位于源码 pkg/provider/kubernetes/crd/traefikio/v1alpha1/serverstransporttcp.go,其类型注册见同目录的 register.go

CRD 注册完成后,即可在任意命名空间内创建与 ServersTransportTCP kind 对应的资源对象,随后由运行在集群中的 Traefik 通过 CRD Provider(kubernetescrd)监听并转换为实际路由配置。

注意:ServersTransportTCP 与 HTTP 场景下的 ServersTransport 是两个不同的 CRD。本页描述的是 TCP 场景的版本;其配置字段与 TCP 场景的 ServersTransport 参考文档 一一对应,只是把文件路径/数据形式的证书换成了 Kubernetes Secret/ConfigMap 引用。

未指定时的默认行为:default@internal

如果某个 TCP 服务没有显式指定 serversTransport,Traefik 会使用名为 default@internal 的内置默认 transport。default@internal 是在安装配置(install configuration,旧称静态配置 static configuration)中构建出来的。

源码中的对应注释也印证了这一语义(serverstransporttcp.go):If no tcpServersTransport is specified, a default one named default@internal will be used. 换句话说,默认 TCP transport 的各项超时与 TLS 参数由 Traefik 进程自身的安装配置决定,而不是由某个 CRD 对象决定。

命名空间与 Provider 引用规则

ServersTransportTCP 是一种可被引用的资源,引用它的通常是 IngressRouteTCP 中某个 service 的 serversTransport 字段。默认情况下存在三条约束:

  • 同命名空间引用ServersTransportTCP CRD 必须与被引用的 TCP 服务定义在同一个 Kubernetes 命名空间中,引用时直接写资源名(如 mytransport)。
  • 跨命名空间引用:若需要引用其他命名空间的 ServersTransportTCP,值必须写成 namespace-name@kubernetescrd 形式(例如 cross-ns@kubernetescrd),并且必须在 CRD Provider 上启用 allowCrossNamespace 选项,否则该引用会被拒绝。
  • 跨 Provider 引用:如果 ServersTransportTCP 是由其他 Provider 提供的(例如文件 Provider、Consul 等),则应使用跨 Provider 的 name@provider 形式。

上述解析逻辑在源码中有完整实现:kubernetes_tcp.go 中的 makeTCPServersTransportKey 会检查引用名是否包含命名空间分隔符 @:当存在跨命名空间引用但 AllowCrossNamespace 未开启时返回错误 namespace-name@kubernetescrd format is not allowed when crossnamespace is disallowed;合法情况下则把 namespace/name 规范化成 Traefik 内部的 key。

仓库中的 fixture 也覆盖了这三种引用形态(tcp/with_servers_transport.ymltcp/with_servers_transport_cross_namespace.yml),例如跨命名空间示例使用 serversTransport: cross-ns-st-cross-ns@kubernetescrd 引用位于 cross-ns 命名空间的资源。

配置示例

下面是一个最小的可运行示例:它创建一个名为 mytransportServersTransportTCP,启用 PROXY Protocol 版本 2、把连接终止延迟设为 100ms,并在与后端建连做 TLS 握手时使用 SNI example.org 且跳过证书校验。

apiVersion: traefik.io/v1alpha1
kind: ServersTransportTCP
metadata:
  name: mytransport
  namespace: default

spec:
  proxyProtocol:
    version: 2
  terminationDelay: 100ms
  tls:
    serverName: example.org
    insecureSkipVerify: true

把上面内容保存为 servers-transport.yaml 后执行:

kubectl apply -f servers-transport.yaml

如何把 ServersTransportTCP 绑定到 TCP 服务

ServersTransportTCP 本身并不直接承载路由,它必须由 IngressRouteTCP 中的服务引用才生效。引用的字段是 TCP 服务的 serversTransport,在 ingressroutetcp.go 中定义为 ServersTransport string,注释明确说明它指向 ServersTransportTCP 资源名:

apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
  name: my-tcp-route
  namespace: default

spec:
  entryPoints:
    - tcpservice
  routes:
    - match: HostSNI(`tcp.example.org`)
      services:
        - name: my-backend
          port: 9000
          serversTransport: mytransport

绑定后,Traefik 在转发到 my-backend:9000 时会依据 mytransportspec 建立连接。关于 IngressRouteTCPterminationDelayproxyProtocol 字段,ingressroutetcp.go 中的注释指出它们已被标记为 Deprecated,未来 API 版本将不再支持,官方建议统一改用 ServersTransport 来配置 TerminationDelayProxyProtocol —— 这正是使用 ServersTransportTCP 的价值所在。

配置选项总表

以下是 ServersTransportTCP 支持的完整字段说明,与官方参考文档一致:

Field Description Default Required
dialTimeout 等待与后端服务器建立连接的时间上限;如果为零,表示不存在超时。 30s No
dialKeepAlive 活跃网络连接的 keep-alive 探测间隔。设为 0 时使用默认值(当前为 15 秒,前提是协议与操作系统支持);不支持 keep-alive 的协议/操作系统会忽略该字段;设为负数则关闭 keep-alive 探测。 15s No
proxyProtocol 定义 PROXY Protocol 配置。空的 proxyProtocol 段即启用 PROXY Protocol 版本 2 No
proxyProtocol.version Traefik 在 TCP 服务上支持 PROXY Protocol 版本 1 与 2。 No
terminationDelay 在某一端对等方关闭其写能力(发送 FIN)后,代理等待多久才完全终止连接。 100ms No
tls.serverName 用于连接服务器的 ServerName(SNI)。 "" No
tls.insecureSkipVerify 是否校验服务器的证书链与主机名。 false No
tls.peerCertSANs 对端证书校验时用于匹配的 SANs(Subject Alternative Names)列表。 [] No
tls.peerCertSANs[].type SAN 类型,取值为 URIDNSName "" No
tls.peerCertSANs[].value 用于匹配对端证书 SAN 的值。 "" No
tls.rootCAs 用于校验服务器证书的 CA 证书 Secret 或 ConfigMap 列表。每一项可通过 secretconfigMap 按名称引用;被引用资源必须在 tls.caca.crt key 下包含证书。 No
tls.rootCAsSecrets 已废弃:请改用 tls.rootCAs 用于校验服务器证书的根 CA 集合;CA Secret 必须在 tls.caca.crt key 下包含 base64 编码的证书。 "" No
tls.certificatesSecrets 用于 mTLS 向服务器出示的客户端证书。 "" No
spiffe 配置 SPIFFE 相关选项。 "" No
spiffe.ids 允许的 SPIFFE ID 列表,优先级高于 SPIFFE trustDomain "" No
spiffe.trustDomain 允许的 SPIFFE trust domain。 "" No

关键字段深入解析

terminationDelay:半开连接防护

作为客户端与服务器之间的代理,可能出现某一侧(例如客户端侧)主动关闭自身写能力(即发出 FIN 包)的情况。此时代理需要把这一意图传播给另一侧,于是也会在与另一侧(后端侧)的连接上执行同样的 FIN。

但如果另一侧出于实现缺陷或恶意目的始终不照做,连接就会长期停留在**半开(half-open)**状态,白白占用资源。为此,代理一旦进入该终止序列,就会对两侧连接的完全终止设置一个 deadline——terminationDelay 控制的正是这个 deadline。默认值为 100ms

需要注意其取值的边界语义:

  • 设置为负数表示无限 deadline(即代理本身永远不会主动彻底终止该连接);
  • 对比参考文档可知,TCP ServersTransport 允许为终止序列设置无期限的等待,这在某些对优雅关闭有严格要求的场景中是有意为之。

proxyProtocol.version:保留客户端真实来源

Traefik 在 TCP 服务上支持 PROXY Protocol 版本 1 与版本 2,通过 serversTransport 上的 proxyProtocol.version 指定使用的协议版本(取值只能是 1 或 2)。设置 PROXY Protocol 后,Traefik 向后端发起连接时会携带原始客户端地址信息,方便后端程序在没有标准转发头(TCP 层没有 HTTP 头)的情况下还原客户端真实 IP。

serverstransporttcp.go 可见,该字段的类型直接复用 dynamic.ProxyProtocol;而空白的 proxyProtocol 段即等价于启用 PROXY Protocol 版本 2,这也与总表中的默认说明一致。

tls.rootCAs 与证书密钥约定

当后端使用自签名或私有 CA 签发证书时,需要通过 tls.rootCAs 告诉 Traefik 信任哪些 CA。该字段的每一项有两种写法,二选一

spec:
  tls:
    rootCAs:
      - secret: my-ca-secret            # 引用 Secret
      - configMap: my-ca-configmap      # 引用 ConfigMap

被引用的 Secret 或 ConfigMap 中必须包含证书内容,支持的 key 为 tls.caca.crt。从仓库测试 fixture tcp/with_servers_transport.yml 可以确认:当同一 Secret 同时包含 ca.crttls.ca 两个 key 时,tls.ca 会被优先使用(fixture 中明确标注 “This should be the preferred one”)。

同时注意:

  • 旧字段 tls.rootCAsSecrets 只接受 Secret 引用,已被标记废弃,请迁移到 tls.rootCAs
  • tls.certificatesSecrets 用于 mTLS 场景,即 Traefik 需要向后端出示客户端证书。Secret 需要包含 tls.crttls.key 两个 key(见 fixture 中的 mtls1/mtls2 示例)。

tls.peerCertSANs:按 SAN 精确校验对端证书

在某些安全要求较高的场景(如 SPIFFE/mTLS)中,仅信任某个 CA 还不够,还需要校验对端证书里的 Subject Alternative Name。tls.peerCertSANs 的每个条目包含两个字段:

spec:
  tls:
    peerCertSANs:
      - type: DNSName
        value: foo.com
      - type: URI
        value: spiffe://example.org/peer
  • type 取值为 URIDNSName
  • value 为要匹配的 SAN 值。

其类型在源码中复用 pkg/tls 包中定义的 SAN 结构(见 serverstransporttcp.go)。早期版本提供过一个单独的 tls.peerCertURI 字符串字段(只能匹配单个 URI),该字段同样已被标记废弃,官方建议改用 peerCertSANs

spiffe:基于 SPIFFE ID 的鉴权

当后端启用 SPIFFE 工作负载身份时,可用 spiffe 段限制 Traefik 只能与持有特定身份的服务器建连:

spec:
  tls:
    spiffe:
      ids:
        - spiffe://example.org/id1
        - spiffe://example.org/id2
      trustDomain: example.org
  • spiffe.ids 定义允许的 SPIFFE ID,优先级高于 trustDomain
  • spiffe.trustDomain 定义允许的 trust domain。

需要特别强调的是:SPIFFE 必须先在 安装配置的 TLS 部分(旧称静态配置)中启用,才能用于保护 Traefik 与后端之间的连接。单纯在 CRD 上声明 spiffe 段而安装配置未开启时不会生效。

源码级原理:CRD 如何转换为内部配置

理解 ServersTransportTCP 的完整链路,有助于排查“配置了但没生效”的问题。整条转换发生在 CRD Provider 的配置加载函数中(kubernetes.go),大致过程如下:

  1. Provider 通过 informer 获取集群中全部 ServersTransportTCP 对象(client.GetServersTransportTCPs());
  2. 对每个对象,先构造内部的 TCPServersTransport,并按字段依次赋值:
    • dialTimeoutdialKeepAliveterminationDelay 三个时间字段在 CRD 中声明为 *intstr.IntOrString(同时带 +kubebuilder:validation:Pattern="^([0-9]+(ns|us|µs|ms|s|m|h)?)+$"+kubebuilder:validation:XIntOrString 注解,见 serverstransporttcp.go),因此在 YAML 中既可以写 42 这样的整数,也可以写 100ms/30s 这样的 Go duration 字符串;
    • proxyProtocol 直接整体赋值给内部对象;
    • tls 段中,从 rootCAsSecrets / rootCAs 引用的 Secret/ConfigMap 会被读取出 PEM 证书内容(分别通过 loadCASecretloadCAConfigMap 加载),从 certificatesSecrets 读取客户端证书/私钥;
  3. 最终用 provider.Normalize(makeID(namespace, name)) 生成规范化 key(例如 default-mytransport@kubernetescrd)存入动态配置,供 IngressRouteTCP 引用。

可见,ServersTransportTCP 里声明的 Secret/ConfigMap 名称都是在该 CRD 自身的命名空间内解析的,这从侧面解释了为什么跨命名空间引用需要显式开启 allowCrossNamespace

如何验证你的配置

仓库为 CRD Provider 提供了覆盖上述全部字段的测试资产,可直接作为“教科书级”示例研读:

  • tcp/with_servers_transport.yml:覆盖 serverNameinsecureSkipVerifypeerCertURIrootCAsSecrets(多个 Secret、同时含 tls.caca.crt 的 Secret)、rootCAs(Secret 与 ConfigMap、同一项同时引用两者应失败的边界)、certificatesSecretsspiffe、三个整数形式的时间字段,以及同命名空间引用的 IngressRouteTCP
  • tcp/with_servers_transport_cross_namespace.yml:覆盖 namespace-name@kubernetescrd 形式的跨命名空间引用,以及 dialKeepAlive: 0 这一“关闭 keep-alive 自定义、退回默认探测”的写法;
  • 对应的 Provider 单元测试位于 pkg/provider/kubernetes/crd/kubernetes_test.go

小结

ServersTransportTCP 把原本位于安装配置/文件配置中的 TCP transport 参数(拨号超时、keep-alive、PROXY Protocol、TLS 与 mTLS 校验、SPIFFE、连接终止延迟)下沉为 Kubernetes 原生 CRD,使集群使用者可以在不触碰 Traefik 安装配置的前提下,按服务精细化控制反向代理与 TCP 后端的连接行为。使用时只需记住三点:先安装 CRD、在 IngressRouteTCP 服务上通过 serversTransport 字段引用、跨命名空间引用需开启 allowCrossNamespace 并采用 name@kubernetescrd 命名。更完整的字段定义与动态配置(YAML/TOML/标签形式)对照可继续查阅 TCP ServersTransport 参考CRD 类型源码

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391