时间:26-04-24
日常维护 Kubernetes 集群,用 Ingress 处理 HTTP/HTTPS 流量早已是家常便饭。但最近团队上线了新的游戏后端和 Redis 集群,这就引出了一个新问题:那些非 HTTP 的流量,比如数据库连接、游戏数据包,该怎么管?
免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
Envoy Gateway 进入了我们的视野。它基于 Kubernetes API 原生设计,内核又是久经沙场的 Envoy,看起来是个不错的新选择。今天,我们就来拆解一下,如何用它来清晰、高效地配置 TCP 和 UDP 路由。
Envoy Gateway
在遵循 Gateway API 标准的 Envoy Gateway 架构里,流量管理是分门别类的。HTTP 流量自然交给 HTTPRoute,那么非 HTTP 流量呢?答案就是 TCPRoute 和 UDPRoute。
简单来说:
这里有个关键点:无论是 TCPRoute 还是 UDPRoute,都需要“挂靠”到一个 Gateway 资源上,并且这个 Gateway 必须已经监听了对应的协议(TCP 或 UDP)。
理论清楚了,动手试试看。假设我们已经有一个处理 HTTP 的 Gateway(名为 simple-gw),现在想让它同时处理 TCP 流量。
首先,给现有的 Gateway 打个“补丁”,增加一个 TCP 类型的监听器。比如,我们想在 2084 端口监听 TCP 流量。
$ kubectl patch gateway simple-gw --type=json --patch '[
{
"op": "add",
"path": "/spec/listeners/-",
"value": {
"name": "tcp-2084",
"port": 2084,
"protocol": "TCP"
}
}
]'
gateway.gateway.networking.k8s.io/simple-gw patched
配置提交了,但生效了吗?最好深入容器内部确认一下。找到 Envoy 容器的进程 ID,然后检查端口监听状态,这是最踏实的方法。
$ sudo crictl ps | grep simple-gw
a9aa1fb792260 a1ea73ec74e58 24 minutes ago Running shutdown-manager 0 e3c0b55bc1a1a
52d6f9253a884 c36c3dd237ac4 24 minutes ago Running envoy 0 e3c0b55bc1a1a
$ sudo crictl inspect 52d6f9253a884 | grep pid
"pid": 17169,
"pid": 1
"type": "pid"
# 端口已监听即可
$ sudo nsenter -t 17169 -n netstat -lntup | grep 2084
tcp 0 0 0.0.0.0:2084 0.0.0.0:* LISTEN 17169/envoy
看到 2084 端口处于 LISTEN 状态,心里就稳了。
监听器准备好了,接下来就是定义路由规则:把到达这个端口的流量,转发到后端的哪个服务。这里我们创建一个 TCPRoute 资源。
$ cat <
这个配置的意思是:所有到达 simple-gw 网关 tcp-2084 监听器的 TCP 流量,统统转发到名为 `simple` 的 Service 的 80 端口。
在云环境下,Gateway 通常会配 LoadBalancer。但在自建集群里,我们更常看到的是 NodePort。查看一下服务暴露的端口号。
$ kubectl -n envoy-gateway-system get svc -l gateway.envoyproxy.io/owning-gateway-name=simple-gw -ojsonpath='{.items[].spec.ports}' | jq .
[
{
"name": "http-80",
"nodePort": 30874,
"port": 80,
"protocol": "TCP",
"targetPort": 10080
},
{
"name": "tcp-2084",
"nodePort": 31486,
"port": 2084,
"protocol": "TCP",
"targetPort": 2084
}
]
看,除了原来的 HTTP 端口,现在多了一个 `tcp-2084` 对应的 NodePort (31486)。注意:在非公有云且未安装 MetalLB 等负载均衡器的环境下,访问就需要通过这个 NodePort 端口。
是骡子是马,拉出来遛遛。用 curl 访问对应的 NodePort 地址和端口,看看流量是否真的被正确路由到了后端的应用。
$ curl 172.139.20.19:31486/who/hostname
simple-97bcd47bd-4vpcx
成功返回了后端 Pod 的主机名,证明 TCP 路由配置完全正确。
搞定了 TCP,再来看看 UDP。这次我们用一个更经典的场景:通过 Envoy Gateway 暴露集群内的 CoreDNS 服务。首先,得确保目标命名空间(这里是 kube-system)下有可用的 Gateway 资源。
如果还没有,就先创建一个。注意,这次 listener 的协议是 UDP,端口我们设为 5300。
cat <<'EOF' | kubectl apply -f -
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: simple-gw
namespace: kube-system
spec:
# Gateway关联上述创建的gatewayClass
gatewayClassName: envoy-proxy-gwc
# 配置Envoy监听端口
listeners:
- name: udp-5300
protocol: UDP
port: 5300
EOF
接着,创建 UDPRoute 资源,将 UDP 5300 端口的流量指向 kube-system 命名空间下的 kube-dns 服务(CoreDNS 的 Service)。
cat <
同样,查看一下这个 UDP 服务对外暴露的 NodePort 是多少。
$ kubectl -n envoy-gateway-system get svc envoy-kube-system-simple-gw-da10de49 -ojsonpath='{.spec.ports}' | jq .
[
{
"name": "udp-5300",
"nodePort": 32709,
"port": 5300,
"protocol": "UDP",
"targetPort": 5300
}
]
UDP 端口 32709 已经就绪。
是时候验证 DNS 查询了。使用 `dig` 命令,指定我们刚刚暴露的地址和端口,查询一个集群内服务域名。
$ dig @172.139.20.19 -p 32709 kubernetes.default.svc.cluster.local
; <<>> DiG 9.18.39-0ubuntu0.24.04.2-Ubuntu <<>> @172.139.20.19 -p 32709 kubernetes.default.svc.cluster.local
; (1 server found)
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10409
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not a vailable
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232; COOKIE: 0a5df5c8afe7d534 (echoed)
;; QUESTION SECTION:
;kubernetes.default.svc.cluster.local. IN A
;; ANSWER SECTION:
kubernetes.default.svc.cluster.local. 30 IN A 10.96.0.1
;; Query time: 3 msec
;; SERVER: 172.139.20.19#32709(172.139.20.19) (UDP)
;; WHEN: Tue Feb 24 17:14:23 CST 2026
;; MSG SIZE rcvd: 129
查询成功,返回了正确的集群内 IP 地址。这说明 UDP 路由也完美工作了。
走完这一套流程,你会发现,用 Envoy Gateway 管理 TCP/UDP 流量,逻辑其实非常清晰:配置监听器、定义路由规则、关联后端服务。对于运维团队而言,掌握这套方法的价值在于,它能将集群南北向的流量管理统一起来。无论是上层的 HTTP 微服务,还是底层的数据库、游戏服务,都可以纳入同一套控制平面,大大提升了管理的一致性和可观测性。希望今天的实操示例,能为你后续的生产环境落地提供一个清晰的参考。