K3s环境下如何通过Traefik在LoadBalancer上直接暴露自定义TCP/UDP端口
Traefik暴露自定义TCP/UDP端口解决方案
问题根因
标准Ingress资源仅设计用于处理HTTP/HTTPS七层流量,本身不支持TCP/UDP四层端口的直接暴露,无论使用Traefik还是Nginx Ingress都无法通过你编写的这类Ingress配置实现自定义端口暴露。你之前了解到的Nginx Ingress的TCP/UDP暴露能力,同样不是通过标准Ingress资源配置实现的,需要额外维护ConfigMap映射规则,同时修改Nginx Ingress的Service开放对应端口,逻辑和Traefik完全一致。你遇到的LoadBalancer仅开放80/443的问题,是因为K3s内置的Traefik默认仅配置了这两个端口的入口。
Traefik版本支持情况
- Traefik v1:支持TCP/UDP服务暴露,但配置方式不依赖标准Ingress,需要先给Traefik新增启动参数
--entrypoints定义自定义端口入口,再通过自定义配置或者前端规则映射到后端服务,配置流程相对繁琐。 - Traefik v2:原生支持TCP/UDP四层路由,官方提供了专门的
IngressRouteTCP、IngressRouteUDP自定义资源(CRD),配置流程规范,无需修改Traefik静态配置即可自定义路由规则,但前提是需要先在Traefik的LoadBalancer类型Service中追加要暴露的端口,让LoadBalancer层面先开放对应端口。
实现步骤(无需切换到Nginx Ingress)
步骤1:修改Traefik的LoadBalancer Service配置
编辑K3s kube-system命名空间下的traefik service,追加你需要暴露的端口:
ports: # 原有80、443端口配置保留 - name: tomcat-8080 port: 8080 targetPort: 8080 protocol: TCP - name: udp-1700 port: 1700 targetPort: 1700 protocol: UDP - name: tcp-1795 port: 1795 targetPort: 1795 protocol: TCP
修改后Traefik的LoadBalancer就会同步开放这三个端口。
步骤2:配置四层路由规则
以Traefik v2为例,分别为TCP、UDP服务创建对应的IngressRoute资源,示例如下:
Tomcat 8080 TCP路由配置
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRouteTCP metadata: name: tomcat-8080 namespace: default spec: entryPoints: - tomcat-8080 # 与步骤1中定义的端口name保持一致 routes: - match: HostSNI(`*`) services: - name: tomcat-tcp-service port: 8080
1700 UDP路由配置
apiVersion: traefik.containo.us/v1alpha1 kind: IngressRouteUDP metadata: name: udp-1700 namespace: default spec: entryPoints: - udp-1700 # 与步骤1中定义的端口name保持一致 routes: - services: - name: the-udp-service port: 1700
1795 TCP端口的配置逻辑和8080一致,替换对应名称和端口即可。
方案选型建议
- 如果你的服务数量较少,不想修改Traefik的默认配置,直接部署MetalLB,给需要暴露端口的Service直接设置LoadBalancer类型,独立分配IP暴露端口,不需要走Ingress链路,是最简单的实现方案。
- 如果你已经用Traefik作为集群统一入口,需要统一管理所有暴露端口,直接使用上述Traefik四层路由方案即可,不需要切换到Nginx Ingress,两者的四层暴露能力完全对等,迁移没有额外收益。
- 不推荐使用NodePort方式直接暴露服务,可维护性和安全性都较差。
内容的提问来源于stack exchange,提问作者Ravish
相关产品推荐
相关产品推荐

