如何使用 IngressRouteTCP 在 Kubernetes 集群中把 TCP 连接路由到后端服务
在 Kubernetes 里,IngressRoute 只能路由 HTTP 流量,而 PostgreSQL、MySQL、gRPC、MQTT 这类直接基于 TCP 的后端需要 Traefik 的 TCP 路由能力。本文的任务很具体:在已运行 Traefik 的 Kubernetes 集群中,创建一个 IngressRouteTCP 资源,让到达指定入口(entrypoint)的原始 TCP 连接被转发到某个 Kubernetes Service 的端口上,并验证连接确实走通了。前提条件是集群中已部署 Traefik,且 kubernetesCRD provider 处于启用状态(使用 Helm chart 安装时默认启用)。
准备工作:确认 CRD 与 provider 就绪
IngressRouteTCP 是 Traefik 的 CRD 实现,在创建对象之前,集群里必须已注册 Traefik 的资源定义。用 Helm chart 安装 Traefik 时这一步已经自动完成。如果没有用 Helm chart 安装(或升级时资源定义过期),需要应用 CRD 定义和对应的 RBAC 文件。仓库中对应的文件是 kubernetes-crd-definition-v1.yml 和 kubernetes-crd-rbac.yml,用 kubectl apply -f <文件> 分别应用即可,其中前者注册 IngressRouteTCP 等 Traefik 自定义资源,后者授予 Traefik 读取这些资源的权限。
确认 provider 已启用:静态配置中为 providers.kubernetesCRD: {},或 CLI 参数 --providers.kubernetescrd=true。参考 Kubernetes Custom Resources 中的说明。
第一步:准备一个后端 TCP 服务
以 Traefik 官方的 whoami 示例应用作为后端(它返回请求的详细信息,方便验证)。创建 Deployment 和 Service:
# whoamitcp.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoamitcp
spec:
replicas: 2
selector:
matchLabels:
app: whoamitcp
template:
metadata:
labels:
app: whoamitcp
spec:
containers:
- name: whoamitcp
image: traefik/whoami
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: whoamitcp
spec:
ports:
- port: 8080
selector:
app: whoamitcp
kubectl apply -f whoamitcp.yaml
Service 名 whoamitcp、端口 8080 是本文后续配置中引用到的值。Traefik 的集成测试也使用同名的服务做 TCP 路由测试,可见其 Service 定义(端口 8080、选择 whoamitcp 标签的 Pod)参考 02-services.yml。
第二步:为 TCP 流量定义入口
IngressRouteTCP 的 spec.entryPoints 指定连接从哪个入口进来。Helm chart 默认只创建 web(80)、websecure(443)、traefik(8080)和 metrics(9100)这几个入口,如果不想占用 80 端口(避免和 HTTP 路由混用),可以新增一个专用入口,例如 footcp 监听 8080。在 Helm values 文件中追加(格式见 EntryPoints 文档 的 Helm Chart Values 示例):
ports:
footcp:
port: :8080
入口的底层配置等价于静态配置中的 entryPoints.footcp.address: ":8080"。如果本地用 k3d 建集群做验证,记得在创建集群时把 8080 映射出来(快速开始指南中的做法是 --port 8080:8080@loadbalancer,见 Kubernetes Quick Start)。
一个需要知道的边界:如果 TCP 路由器和 HTTP 路由器挂在同一个入口上,TCP 路由会先于 HTTP 路由生效;只有当 TCP 路由没有匹配到任何规则时,HTTP 路由才会接管。所以给 TCP 服务用独立入口可以避免抢占 80 端口上的 HTTP 流量。
第三步:创建 IngressRouteTCP
最小可用的非 TLS 配置如下,把 footcp 入口上的所有连接转发到 whoamitcp:8080:
# ingressroutetcp.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRouteTCP
metadata:
name: whoamitcp-route
namespace: default
spec:
entryPoints:
- footcp
routes:
- match: HostSNI(`*`)
services:
- name: whoamitcp
namespace: default
port: 8080
kubectl apply -f ingressroutetcp.yaml
字段要求(完整字段表见 IngressRouteTCP 参考文档):
spec.routes必填,其中每条路由的match(匹配规则)必填;services[n].name和services[n].port必填,引用的是 Kubernetes Service 及其端口(端口也可以写命名端口);spec.entryPoints可选,不写则使用该入口的默认列表;- 同一入口上有多条规则可能同时匹配时,用
routes[n].priority消除歧义。
第四步:理解 match 规则
match 是连接匹配器,TCP 路由支持的匹配器只有四个(见 TCP Routers Rules & Priority):
| 规则 | 作用 |
|---|---|
HostSNI(domain) |
连接携带的 TLS Server Name Indication 等于 domain,支持单层通配 *.example.com(只匹配直接子域) |
HostSNIRegexp(regexp) |
SNI 匹配 Go 风格正则 |
ClientIP(ip) |
按客户端 IP 匹配,支持 IPv4、IPv6 和 CIDR |
ALPN(protocol) |
按 ALPN 协议匹配(不允许匹配 ACME-TLS/1,否则 Traefik 报错) |
几个写规则时的硬性约定:
- 规则值必须用反引号
`或转义双引号,单引号不被接受; - 支持
&&、||、!和括号组合,例如HostSNI(example.com) || (HostSNI(example.org) && !ALPN(h2)); HostSNI依赖 TLS 协议扩展,因此只有 TLS 路由才能按域名匹配。非 TLS 路由要匹配所有连接时,使用专门的HostSNI(*)写法——这就是第三步示例中的用法;HostSNI不支持非 ASCII 字符,IDN 域名要用 punycode 编码值。
优先级方面:不写 priority 时,默认优先级等于规则字符串长度(越长越优先);显式写 priority: 0 表示忽略、回落到默认的长度排序;负值也支持。来自不同 provider 且优先级相同的规则,按 providers.precedence 中 provider 的先后顺序决定胜负。
验证路由是否生效
-
确认资源已被接受:
kubectl get ingressroutetcps -o name -
Traefik 的 API 会列出当前所有 TCP 路由(见 API & Dashboard 文档):
# 通过 dashboard/入口所在主机访问,路径前缀为 /api curl http://dashboard.localhost/api/tcp/routers返回列表中应出现名为
whoamitcp-route的路由(名字格式以文档示例为准)。也可以在 Traefik Dashboard 的 TCP Routers 一栏查看。 -
直接连一下 TCP 入口,确认连接被转发到后端。由于 whoami 应用本身返回 HTTP 响应,可以用
curl验证:curl http://127.0.0.1:8080预期得到类似下面的输出(以下为文档示例,实际 Pod 名和 IP 会不同,每次连接还可能落在不同副本上):
Hostname: whoami-76c9859cfc-6v8hh IP: 127.0.0.1 IP: ::1 RemoteAddr: 10.42.0.9:38280 GET / HTTP/1.1 Host: whoami.localhost输出中出现
whoami副本的 Hostname,说明 TCP 连接已经穿过 Traefik 到达后端 Service。
如果第 2 步看不到路由,先核对三件事:kubernetesCRD provider 是否启用、entryPoints 里写的入口名是否真实存在(/api/entrypoints 可查)、spec.routes[n].services 引用的 Service 名和端口是否准确。
常用可选项与边界
以下字段都来自 IngressRouteTCP 参考文档,按需添加:
- TLS 终结与透传:
tls.secretName指定存放证书的 Secret(与IngressRouteTCP同命名空间);tls.passthrough: true时 TLS 终结委托给后端,Traefik 只做透传;tls.options可引用一个TLSOption定制 TLS 连接参数;tls.certResolver和tls.domains用于证书解析场景。 - 后端 TLS:
services[n].tls控制 Traefik 拨号到后端时是否走 TLS,默认false。 - 负载均衡方式:默认情况下 Traefik 直接以 Pod IP 作为负载均衡子节点;
nativeLB: true改为使用 Service 的clusterIP作为唯一子节点,把负载交还给 Kubernetes 自己做;nodePortLB: true则适用于 Traefik 部署在集群外但与节点同网络的情形,子节点为节点内部 IP 加 nodePort。 - 多后端加权:一条路由可以挂多个
services,用services[n].weight(默认 1)控制负载分配。 - ExternalName Service:Traefik 按「域名 + 端口」连接后端,而 Kubernetes 的 ExternalName Service 可以不带端口。端口要么只在
IngressRouteTCP的 service 里定义,要么两边都定义——两边都定义时如果不一致会有警告,且以IngressRouteTCP侧的端口为准。 - 中间件:
routes[n].middlewares引用MiddlewareTCP(同 CRD 命名空间下),用于在转发前处理 TCP 流,比如 IP 白名单,参考 MiddlewareTCP 文档。
一个完整字段的配置样例(含 ingressClassName、priority、middlewares、serversTransport、nativeLB、nodePortLB 和完整 tls 块)可以直接参考 ingressroutetcp.md 中的 Configuration Example;仓库集成测试里的实际用例见 05-ingressroutetcp.yml,它同时使用了 tls.options 和 tls.store。
下一步
- 需要限制可访问后端的来源 IP 时,给路由挂一个
ipallowlist类型的 MiddlewareTCP; - 需要调整 Traefik 到后端的传输行为(超时、连接池等)时,配置
ServersTransportTCP并通过services[n].serversTransport引用; - 同一套机制还有 UDP 版本的
IngressRouteUDP,字段结构与 TCP 版本相近,可在 Kubernetes Custom Resources 文档 的自定义资源表中对照查看。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00