4. Gateway 资源详解:监听器配置、TLS 终止、网关选择器、端口与协议映射
在云原生网关(如 Kubernetes Gateway API)的资源模型中,Gateway 资源是流量入口的声明式定义。它不再像 Ingress 那样将监听行为与路由规则耦合在一起,而是将网络拓扑的底层配置(监听器、TLS、端口)与上层路由策略(HTTPRoute、TLSRoute)进行了解耦。本章将深入剖析 Gateway 资源的四大核心配置块:监听器(Listeners)、TLS 终止、网关选择器(Gateway Selector)以及端口与协议映射。
parentRefs 字段绑定到 Gateway 的监听器上。
4.1 监听器配置:流量的入口点
监听器(Listener)是 Gateway 资源中最核心的配置单元。每个监听器定义了网关在特定端口上监听特定协议的行为。一个 Gateway 可以包含多个监听器,每个监听器必须具有唯一的 名称,并且可以独立配置协议、端口、TLS 以及允许绑定的路由类型。
4.1.1 监听器核心字段
| 字段 | 类型 | 说明 | 是否必填 |
|---|---|---|---|
name |
string | 监听器在 Gateway 内的唯一标识,用于 Route 资源的 sectionName 引用。 |
是 |
port |
int32 | 监听端口号(1-65535)。 | 是 |
protocol |
string | 监听协议,如 HTTP、HTTPS、TLS、TCP、UDP。 |
是 |
hostname |
string | 可选。监听器的主机名过滤。如果设置,只有匹配该 Hostname 的请求才会被接受。 | 否 |
tls |
object | TLS 配置,包括证书、模式(Terminate/Passthrough)等。 | 协议为 HTTPS/TLS 时必填 |
allowedRoutes |
object | 定义哪些命名空间下的哪些 Route 资源可以绑定到此监听器。 | 否 |
4.1.2 监听器配置示例
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
namespace: infra
spec:
gatewayClassName: my-gateway-class
listeners:
- name: http-listener # 监听器名称,唯一
port: 80 # 端口
protocol: HTTP # 协议
allowedRoutes:
namespaces:
from: All # 允许所有命名空间的 Route 绑定
- name: https-listener # 第二个监听器
port: 443
protocol: HTTPS
tls:
mode: Terminate # TLS 终止模式
certificateRefs:
- name: my-tls-secret # 引用 TLS 证书 Secret
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
app: frontend # 仅允许带有该标签的命名空间
4.2 TLS 终止:解密与转发
TLS 终止是网关的核心安全能力。在 Gateway API 中,TLS 配置被显式地定义在监听器级别,支持两种模式:Terminate 和 Passthrough。
4.2.1 TLS 模式对比
| 模式 | 描述 | 证书位置 | 适用场景 |
|---|---|---|---|
| Terminate | 网关解密客户端 TLS 请求,然后将明文 HTTP 请求转发给后端服务。 | 证书存储在网关所在命名空间的 Secret 中。 | 内部服务间使用 HTTP 通信,网关统一管理证书。 |
| Passthrough | 网关不解密 TLS 流量,直接将加密的 TCP 流透传给后端 Pod。 | 证书存储在后端 Pod 中,网关不持有证书。 | 后端服务需要端到端加密,或使用 mTLS 的场景。 |
4.2.2 TLS 终止配置详解
当 mode: Terminate 时,必须通过 certificateRefs 引用一个或多个 Kubernetes Secret。Secret 必须包含 tls.crt 和 tls.key 字段。
tls:
mode: Terminate
certificateRefs:
- name: my-tls-secret # 必须与 Gateway 在同一命名空间
- name: fallback-tls-secret # 可选,提供多个证书用于 SNI 匹配
options: # 可选,传递给网关实现的自定义 TLS 选项
"min-version": "1.2"
"cipher-suites": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
Passthrough 模式时,监听器的协议必须设置为 TLS,且不能配置 certificateRefs。此时,网关仅作为 TCP 代理,路由规则由 TLSRoute 资源定义,基于 SNI 进行转发。
4.3 网关选择器:GatewayClass 与 Gateway 的绑定
网关选择器(Gateway Selector)并非 Gateway 资源自身的字段,而是 GatewayClass 资源用来选择它所管理的 Gateway 实例的机制。它通过标签选择器(Label Selector)实现,是控制平面解耦的关键。
4.3.1 选择器工作原理
每个 Gateway 资源必须指定一个 gatewayClassName。GatewayClass 控制器会监听所有 Gateway 资源,并通过其 spec.parametersRef 或内置逻辑,找到匹配的 Gateway。但更灵活的方式是:GatewayClass 通过 spec.parametersRef 指向一个包含选择器配置的自定义资源。
以下是一个典型的选择器配置流程:
- 定义 GatewayClass: 声明一个名为
my-gateway-class的 GatewayClass。 - 创建 Gateway: 在
spec.gatewayClassName中引用该 GatewayClass。 - 控制器匹配: GatewayClass 的控制器(如 Istio、Contour)根据其实现逻辑,选择所有
gatewayClassName匹配的 Gateway 实例进行配置。
4.3.2 使用标签选择器进行精细化控制
某些网关实现(如基于 Envoy 的 Istio)允许在 GatewayClass 的 parametersRef 中定义更细粒度的选择器,例如只管理带有特定标签的 Gateway。
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: istio-gateway-class
spec:
controllerName: istio.io/gateway-controller
parametersRef:
group: networking.istio.io
kind: IstioGatewayConfig
name: istio-config
---
apiVersion: networking.istio.io/v1beta1
kind: IstioGatewayConfig
metadata:
name: istio-config
spec:
selector:
matchLabels:
istio: ingressgateway # 仅管理带有该标签的 Gateway 资源
4.4 端口与协议映射:从监听器到后端
端口与协议映射定义了监听器如何将入站流量路由到后端服务。在 Gateway API 中,这种映射是通过 Route 资源(如 HTTPRoute、TCPRoute)的 parentRefs 和 backendRefs 间接实现的。Gateway 本身只负责声明“我在 443 端口监听 HTTPS”,而“将 /api 路径转发到 Service A”的逻辑由 Route 资源完成。
4.4.1 映射关系图
下图展示了从客户端请求到后端 Pod 的完整映射链路:
4.4.2 协议映射规则
监听器的协议决定了它可以绑定哪些类型的 Route 资源。错误的协议映射会导致路由规则无法生效。
| 监听器协议 | 可绑定的 Route 类型 | 说明 |
|---|---|---|
HTTP |
HTTPRoute | 标准的 HTTP 代理,支持路径、Header、Query 匹配。 |
HTTPS |
HTTPRoute | TLS 终止后,内部仍使用 HTTP 路由规则。 |
TLS |
TLSRoute | 基于 SNI 的 TCP 代理,支持 Passthrough 或 Terminate。 |
TCP |
TCPRoute | 四层 TCP 代理,不解析应用层协议。 |
UDP |
UDPRoute | 四层 UDP 代理,适用于 DNS、QUIC 等场景。 |
HTTPS 但未配置 tls 块,或者配置了 tls 但 mode: Passthrough 却绑定了 HTTPRoute,网关实现通常会拒绝该配置并报错。
4.5 综合配置示例:一个生产级 Gateway
以下是一个综合了监听器、TLS、选择器和端口映射的生产级 Gateway 配置示例:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: production-gateway
namespace: prod
labels:
app: ingress-gateway
env: production
spec:
gatewayClassName: prod-gateway-class
listeners:
- name: public-http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
expose: public
- name: public-https
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: wildcard-tls
options:
"min-version": "1.3"
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
expose: public
- name: internal-tcp
port: 3306
protocol: TCP
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: public-api
namespace: prod
spec:
parentRefs:
- name: production-gateway
sectionName: public-https # 明确绑定到 HTTPS 监听器
hostnames:
- "api.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /v1/
backendRefs:
- name: api-service
port: 8080
sectionName 字段,Route 可以精确绑定到 Gateway 的某个特定监听器,实现端口级别的路由隔离。这在多协议、多端口网关中非常有用。
4.6 测试验证要点
在测试 Gateway 资源时,应重点关注以下验证点:
- 监听器冲突检测: 验证同一 Gateway 内是否存在端口相同但协议不同的监听器。
- TLS 证书有效性: 验证引用的 Secret 是否存在、格式是否正确(包含
tls.crt和tls.key),以及证书是否过期。 - 路由绑定验证: 验证 Route 资源的
parentRefs是否指向正确的 Gateway 和监听器,以及命名空间选择器是否允许绑定。 - 协议一致性: 验证监听器协议与绑定的 Route 类型是否匹配(如 HTTPS 监听器只能绑定 HTTPRoute)。
- 端口可达性: 通过
curl或nc命令测试 Gateway 的监听端口是否正常响应。
# 测试 HTTPS 监听器是否正常工作
curl -k -H "Host: api.example.com" https://<GATEWAY_IP>/v1/healthz
# 测试 TCP 监听器是否可达
nc -zv <GATEWAY_IP> 3306
-k 或 --insecure 参数,但在生产环境中应使用受信任的 CA 证书。