4. Gateway 资源详解:监听器配置、TLS 终止、网关选择器、端口与协议映射

在云原生网关(如 Kubernetes Gateway API)的资源模型中,Gateway 资源是流量入口的声明式定义。它不再像 Ingress 那样将监听行为与路由规则耦合在一起,而是将网络拓扑的底层配置(监听器、TLS、端口)与上层路由策略(HTTPRoute、TLSRoute)进行了解耦。本章将深入剖析 Gateway 资源的四大核心配置块:监听器(Listeners)、TLS 终止、网关选择器(Gateway Selector)以及端口与协议映射。

核心认知: Gateway 资源本身不定义路由规则,它只定义“如何暴露”和“暴露什么”。路由规则由 Route 资源(如 HTTPRoute)通过 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        # 仅允许带有该标签的命名空间
关键约束: 同一个 Gateway 内的监听器,如果端口相同,则协议必须相同。例如,不能同时存在两个监听器都监听 80 端口,一个用 HTTP,一个用 TCP。

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 指向一个包含选择器配置的自定义资源。

以下是一个典型的选择器配置流程:

  1. 定义 GatewayClass: 声明一个名为 my-gateway-class 的 GatewayClass。
  2. 创建 Gateway: 在 spec.gatewayClassName 中引用该 GatewayClass。
  3. 控制器匹配: 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 资源
最佳实践: 建议为不同用途的 Gateway(如内网、外网、测试)打上不同的标签,并通过 GatewayClass 的选择器进行隔离管理,避免配置冲突。

4.4 端口与协议映射:从监听器到后端

端口与协议映射定义了监听器如何将入站流量路由到后端服务。在 Gateway API 中,这种映射是通过 Route 资源(如 HTTPRoute、TCPRoute)的 parentRefs 和 backendRefs 间接实现的。Gateway 本身只负责声明“我在 443 端口监听 HTTPS”,而“将 /api 路径转发到 Service A”的逻辑由 Route 资源完成。

4.4.1 映射关系图

下图展示了从客户端请求到后端 Pod 的完整映射链路:

端口与协议映射链路 端口与协议映射链路 客户端 Gateway 监听器 端口: 443, 协议: HTTPS HTTPRoute 匹配: /api, 后端: svc-a Service A 端口: 8080, 协议: HTTP 映射说明 1. 客户端通过 HTTPS 访问 Gateway 的 443 端口。 2. Gateway 根据监听器配置终止 TLS,并将请求交给 HTTPRoute。 3. HTTPRoute 匹配路径后,将请求转发到后端 Service 的 8080 端口。

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
注意: 在测试 TLS 终止时,务必验证证书链是否完整。如果使用自签名证书,客户端需要添加 -k 或 --insecure 参数,但在生产环境中应使用受信任的 CA 证书。