首页
/ 如何使用 IngressRouteTCP 在 Kubernetes 集群中把 TCP 连接路由到后端服务

如何使用 IngressRouteTCP 在 Kubernetes 集群中把 TCP 连接路由到后端服务

2026-09-08 17:25:39作者:裴麒琰

在 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.ymlkubernetes-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 流量定义入口

IngressRouteTCPspec.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].nameservices[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 的先后顺序决定胜负。

验证路由是否生效

  1. 确认资源已被接受:

    kubectl get ingressroutetcps -o name
    
  2. Traefik 的 API 会列出当前所有 TCP 路由(见 API & Dashboard 文档):

    # 通过 dashboard/入口所在主机访问,路径前缀为 /api
    curl http://dashboard.localhost/api/tcp/routers
    

    返回列表中应出现名为 whoamitcp-route 的路由(名字格式以文档示例为准)。也可以在 Traefik Dashboard 的 TCP Routers 一栏查看。

  3. 直接连一下 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.certResolvertls.domains 用于证书解析场景。
  • 后端 TLSservices[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 文档

一个完整字段的配置样例(含 ingressClassNamepriority、middlewares、serversTransportnativeLBnodePortLB 和完整 tls 块)可以直接参考 ingressroutetcp.md 中的 Configuration Example;仓库集成测试里的实际用例见 05-ingressroutetcp.yml,它同时使用了 tls.optionstls.store

下一步

  • 需要限制可访问后端的来源 IP 时,给路由挂一个 ipallowlist 类型的 MiddlewareTCP
  • 需要调整 Traefik 到后端的传输行为(超时、连接池等)时,配置 ServersTransportTCP 并通过 services[n].serversTransport 引用;
  • 同一套机制还有 UDP 版本的 IngressRouteUDP,字段结构与 TCP 版本相近,可在 Kubernetes Custom Resources 文档 的自定义资源表中对照查看。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
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