一文读懂 K8s Gateway API:下一代 Kubernetes 网关标准的深度解析
Kubernetes 已经成为容器编排的事实标准,而如何将外部流量可靠、安全、高效地引入 Kubernetes 集群内部的服务,一直是困扰用户的重要课题。长期以来,Ingress API 承担了这一职责,但随着 Kubernetes 生态的发展和用户需求的日益复杂,Ingress 的局限性也逐渐显现。为了解决这些问题,Kubernetes 社区推出了全新的 Gateway API,旨在成为下一代标准的流量入口规范。
本文将带你深入了解 Gateway API,包括它为什么出现、解决了什么问题、核心概念是什么、如何工作以及它的优势和未来。
1. Ingress API 的困境:为什么我们需要新的标准?
在我们深入 Gateway API 之前,理解其前身 Ingress API 的不足之处是必要的。Ingress API 于 2015 年引入,其核心思想是提供一种声明式的方式来定义如何从外部访问集群内部的服务。一个 Ingress 资源通常包含主机名、路径以及后端服务的映射关系。
然而,Ingress 在实际使用中暴露出许多局限性:
- 表达能力有限 (Limited Expressiveness): Ingress API 规范本身相对简单,只能表示基本的基于主机名和路径的路由。像请求头匹配、方法匹配、权重分流、流量镜像、请求/响应体修改等高级路由功能,都需要依赖特定的 Ingress Controller(如 Nginx Ingress, HAProxy Ingress, Traefik 等)通过注解 (Annotations) 来实现。
- 标准化缺失 (Lack of Standardization): 由于高级功能依赖注解,而注解本身是特定于具体实现的(Vendor-Specific),这意味着不同的 Ingress Controller 使用不同的注解来表达相同的功能。这导致用户在切换 Ingress Controller 时需要大量修改 Ingress 资源,形成厂商锁定,并增加了学习成本。
- 角色分离不足 (Insufficient Role Separation): Ingress 资源通常由应用开发者或运维人员创建和管理。然而,配置 Ingress Controller 本身(例如负载均衡器的类型、TLS 证书管理方式、全局限速策略等)往往是由更底层的平台工程师或基础设施团队负责。Ingress API 没有很好地将这些不同角色的职责区分开来,导致协作困难和权限管理复杂。一个 Ingress 资源的修改可能会意外影响到其他应用,因为底层的共享 Ingress Controller 是一个单点。
- 复杂性管理 (Complexity Management): 随着集群规模扩大和应用增多,Ingress 规则会变得非常庞大和复杂。管理数百甚至上千个 Ingress 资源及其各种注解成为一项挑战。
- 缺乏可扩展性 (Poor Extensibility): 除了注解,Ingress API 本身没有提供一个标准的、结构化的方式来扩展其功能或定义自定义策略。
正是为了解决 Ingress API 的这些痛点,Kubernetes 社区 SIG Network(Special Interest Group on Networking)着手设计了 Gateway API,旨在提供一个更通用、更灵活、更标准化的网络入口接口。
2. Gateway API 的核心理念:以角色为中心
Gateway API 的设计核心理念是以角色为中心 (Role-Oriented)。它明确区分了使用 Kubernetes 网关涉及到的不同角色,并为每个角色定义了相应的 API 资源,从而实现职责分离和更好的管理:
- 基础设施提供者 (Infrastructure Provider): 这个角色负责运行实际的网络基础设施,如云提供商的负载均衡器、硬件负载均衡器、或者复杂的代理软件(如 Istio, Contour, Nginx, HAProxy)。他们定义了网关类 (GatewayClass)。
- 集群操作员 (Cluster Operator): 这个角色负责管理集群内的共享网络基础设施实例,例如配置和部署具体的负载均衡器实例。他们创建网关 (Gateway) 资源。
- 应用开发者 (Application Developer): 这个角色负责定义应用的网络需求,例如哪些主机名和路径应该路由到他们的服务。他们创建路由 (Route) 资源(如
HTTPRoute
,TLSRoute
)。
通过这种方式, Gateway API 将网关能力的定义、网关实例的配置以及具体路由规则的设置分离开来,大大提升了灵活性、安全性和可管理性。
3. Gateway API 的核心资源详解
Gateway API 引入了几个新的 Kubernetes API 资源,它们共同协作来管理流量入口。最核心的三个资源是:GatewayClass
、Gateway
和 Route
(以 HTTPRoute
为例)。
3.1 GatewayClass (网关类)
- 作用:
GatewayClass
是一个集群范围 (Cluster-Scoped) 的资源,它定义了一类网关的能力和模板。它不是一个网关实例,而是网关实例的蓝图或规范。GatewayClass
由基础设施提供者创建,并通常引用一个特定的控制器 (Controller) 来实现其定义的功能。 - 谁管理: 通常由基础设施提供者或集群管理员管理。
- 关键字段:
spec.controllerName
: 必需。指定哪个 Gateway Controller 会实现这个GatewayClass
。这是一个字符串标识符,不同的 Gateway Controller 会注册自己支持的controllerName
。spec.parametersRef
: 可选。引用一个额外的参数资源,用于提供特定于控制器或实现的配置。例如,可能引用一个ConfigMap
或一个自定义资源来配置底层的负载均衡器类型、共享的 TLS 配置等。这个参数资源的类型和内容完全取决于具体的 Gateway Controller 实现。spec.description
: 可选。描述这个GatewayClass
的用途或特性。
- 状态:
GatewayClass
的status
字段会指示这个类是否是“有效的” (Valid
) 以及它是否已经“接受” (Accepted
)。 - 重要性:
GatewayClass
是 Gateway API 的起点。没有GatewayClass
,就无法创建Gateway
实例。它将网关的实现细节(由哪个控制器提供)与网关的配置分离开来。
示例 (YAML):
yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: example-nginx-class
spec:
controllerName: nginx.org/gateway-controller # 指定实现此类的控制器
description: "A GatewayClass implemented by the NGINX Gateway Controller"
# parametersRef 可以引用一个 ConfigMap 或其他资源提供更多配置
# parametersRef:
# group: core
# kind: ConfigMap
# name: nginx-gateway-params
3.2 Gateway (网关)
- 作用:
Gateway
是一个命名空间范围 (Namespace-Scoped) 的资源,它代表了网关的一个具体实例。它请求了网络资源(如 IP 地址、端口)并引用一个GatewayClass
来指定其能力和行为。Gateway
是路由规则(如HTTPRoute
)的父级 (Parent) 资源,路由规则通过引用Gateway
来表明它们希望通过哪个网关实例暴露服务。 - 谁管理: 通常由集群操作员管理。
- 关键字段:
spec.gatewayClassName
: 必需。引用要使用哪个GatewayClass
的名称。这个字段将Gateway
实例与一个特定的网关能力模板关联起来。spec.listeners
: 必需。定义网关监听的网络地址、端口和协议。每个监听器可以指定:port
: 监听的端口号。protocol
: 协议 (如HTTP
,HTTPS
,TLS
,TCP
,UDP
)。hostname
: 可选。指定监听哪个主机名,用于基于主机名的路由或 TLS SNI 匹配。tls
: 可选。配置 TLS 终止,引用 Kubernetes Secret 中的证书。allowedRoutes
: 可选。定义哪些命名空间的路由可以附加到此监听器。这是实现跨命名空间引用路由和增强安全性的关键。
- 状态:
Gateway
的status
字段非常重要,它会显示:- 分配给网关的 IP 地址或主机名。
- 监听器的状态,包括是否成功监听以及哪些路由已成功附加。
Gateway
实例是否已准备就绪 (Ready
)。
- 重要性:
Gateway
是网络流量的入口点。它将抽象的GatewayClass
变为一个具体的、有 IP 地址和端口的网络端点。它也是连接GatewayClass
和各种Route
资源的桥梁。
示例 (YAML):
yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: example-gateway
namespace: default # 网关资源在命名空间下
spec:
gatewayClassName: example-nginx-class # 引用上面定义的 GatewayClass
listeners:
- name: http # 监听器名称
port: 80
protocol: HTTP
# hostname: example.com # 可选,只监听 example.com 的 HTTP 流量
allowedRoutes: # 允许哪些命名空间的路由附加到此监听器
namespaces:
from: Same # 只允许与 Gateway 在同一个命名空间 (default) 的路由
- name: https
port: 443
protocol: HTTPS
hostname: example.com # 明确指定监听 example.com 的 HTTPS 流量
tls:
mode: Terminate # TLS 终止在网关
certificateRefs: # 引用 TLS 证书 Secret
- kind: Secret
name: example-tls-cert
namespace: default # Secret 所在的命名空间
allowedRoutes:
namespaces:
from: Selector # 允许特定命名空间的路由
selector:
matchLabels:
app: my-app # 带有 label app=my-app 的命名空间
3.3 Route (路由)
- 作用:
Route
资源定义了如何将请求匹配并路由到 Kubernetes Services。Gateway API 定义了多种类型的Route
资源来处理不同的协议流量,例如HTTPRoute
,TLSRoute
,TCPRoute
,UDPRoute
。其中HTTPRoute
是最常用和最强大的,用于处理 HTTP/HTTPS 流量。Route
资源通过parentRefs
字段引用它们希望附加到的Gateway
资源。 - 谁管理: 通常由应用开发者管理。
- 核心 Route 类型:
HTTPRoute
: 用于 HTTP/HTTPS 流量。支持基于主机名、路径、方法、头部、查询参数等多种匹配规则,以及将流量转发到 Service、重定向、镜像、重写等多种动作。TLSRoute
: 用于 TLS 流量,通常用于 SNI 匹配和直接转发 TLS 流量(非终止)。TCPRoute
: 用于 TCP 流量的端口转发。UDPRoute
: 用于 UDP 流量的端口转发。GRPCRoute
(试验中): 用于 gRPC 流量。
HTTPRoute
关键字段:spec.parentRefs
: 必需。一个列表,引用此路由希望附加到的一个或多个Gateway
资源。每个引用包含group
,kind
,name
以及可选的namespace
和sectionName
(指向 Gateway 监听器的名称)。这实现了路由与网关的关联。spec.hostnames
: 可选。指定此路由匹配的主机名列表。如果未指定,则匹配其父 Gateway Listener 上指定的主机名(如果存在)。spec.rules
: 必需。一个列表,定义路由规则。每个规则包含:matches
: 必需。一个列表,定义请求匹配条件。可以组合多种匹配条件 (如路径、头部、方法、查询参数)。path
: 路径匹配 (精确匹配Exact
, 前缀匹配PathPrefix
, 正则匹配RegularExpression
)。headers
: 头部匹配 (精确匹配Exact
, 正则匹配RegularExpression
, 存在匹配Present
)。method
: 方法匹配 (GET, POST, PUT 等)。queryParams
: 查询参数匹配 (精确匹配Exact
, 正则匹配RegularExpression
, 存在匹配Present
)。
filters
: 可选。在请求被转发到后端之前或之后执行的操作,例如请求/响应头修改、URL 重写、请求镜像。backendRefs
: 必需。一个列表,定义匹配条件的请求应该转发到哪些后端服务。可以指定多个后端服务并分配权重,实现流量分流。每个引用包含group
,kind
(通常是Service
),name
,port
以及可选的weight
。
- 状态:
Route
的status
字段会显示此路由是否已成功附加到其引用的 Gateway,以及 Gateway 控制器是否已为此路由配置底层基础设施。 - 重要性:
Route
资源是应用开发者与网关交互的主要方式。它们提供了比 Ingress 强大得多的路由匹配和流量控制能力,并且这些能力是标准化的 API 字段,而不是特定注解。
示例 (HTTPRoute
YAML):
yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: example-app-route
namespace: default # 路由通常在应用的命名空间下
spec:
parentRefs: # 引用父 Gateway 资源
- name: example-gateway # 父 Gateway 的名称
namespace: default # 父 Gateway 所在的命名空间 (如果不在同一命名空间需要指定)
sectionName: http # 引用 Gateway 中名称为 'http' 的监听器
hostnames:
- "example.com" # 只匹配 example.com 的请求
rules:
- matches: # 第一个匹配规则
- path:
type: PathPrefix # 路径前缀匹配
value: /app
- headers: # 同时匹配请求头
- name: Version
value: v1 # 请求头 Version 精确匹配 v1
backendRefs: # 转发到 example-app-v1 服务
- name: example-app-v1
port: 80
- matches: # 第二个匹配规则
- path:
type: PathPrefix
value: /app
- headers:
- name: Version
value: v2 # 请求头 Version 精确匹配 v2
backendRefs: # 转发到 example-app-v2 服务
- name: example-app-v2
port: 80
- matches: # 第三个匹配规则 (默认规则,如果没有 Version 头或不匹配 v1/v2)
- path:
type: PathPrefix
value: /app # 依然是 /app 前缀
backendRefs: # 将 90% 流量转发到 v1,10% 流量转发到 v2 (金丝雀发布示例)
- name: example-app-v1
port: 80
weight: 90
- name: example-app-v2
port: 80
weight: 10
- matches: # 第四个匹配规则 (精确匹配 /status 路径)
- path:
type: Exact # 精确匹配
value: /status
backendRefs:
- name: status-service # 转发到 status-service
port: 80
- matches: # 第五个匹配规则 (匹配所有其他路径 /)
- path:
type: PathPrefix
value: /
backendRefs:
- name: default-service # 转发到默认服务
port: 80
filters: # 在转发到 default-service 之前执行过滤操作
- type: URLRewrite # URL 重写
urlRewrite:
path:
type: PrefixMatch # 将匹配到的前缀 / 替换为 /index
value: /index
3.4 Policy (策略)
- 作用:
Policy
资源(目前在实验或开发阶段,如ReferencePolicy
,HealthCheckPolicy
等概念)旨在提供一种标准化的方式,将特定的配置或策略(如认证、授权、限速、熔断、健康检查等)附加到GatewayClass
,Gateway
,Route
或甚至Service
资源上。这提供了比注解更结构化和可管理的方式来扩展网关功能。 - 重要性:
Policy
机制是 Gateway API 扩展性的关键。不同的 Gateway Controller 可以定义和实现自己的策略资源,并通过标准的Policy
附加机制将其应用到网关资源的各个层级。这进一步增强了灵活性和解耦性。
4. Gateway API 的工作流程概述
Gateway API 的工作流程可以概括为以下几个步骤:
- 定义能力 (GatewayClass): 基础设施提供者或集群管理员部署 Gateway Controller,并创建或确保存在一个或多个
GatewayClass
资源。每个GatewayClass
定义了某种类型的网关能力的蓝图,并指定了由哪个控制器来负责实现。 - 创建实例 (Gateway): 集群操作员创建
Gateway
资源,引用一个已有的GatewayClass
。这个Gateway
资源请求具体的网络资源(如在云中创建负载均衡器),并配置监听器(指定 IP/端口/协议/TLS)。Gateway Controller 会监听Gateway
资源,并根据其配置和引用的GatewayClass
,创建和配置底层的网络基础设施。Gateway
资源的status
字段会更新,显示分配的 IP 地址和监听器状态。 - 定义路由 (Route): 应用开发者创建
Route
资源(如HTTPRoute
),在其parentRefs
字段中引用一个或多个他们希望使用的Gateway
资源(通常是特定命名空间下的特定 Gateway 实例)。Route
资源定义了具体的流量匹配规则和后端转发规则。 - 关联与配置 (Controller Action): Gateway Controller 会监听
Route
资源,并检查其parentRefs
是否指向它正在管理的Gateway
实例。如果引用关系合法且被 Gateway 允许(通过allowedRoutes
策略),Controller 就会将Route
中定义的规则应用到它管理的底层网络基础设施上。Route
资源的status
字段会更新,指示其是否成功附加到 Gateway 并生效。 - 流量转发: 外部流量到达 Gateway 暴露的 IP 地址和端口后,底层的网络基础设施会根据 Gateway 和所有附加到该 Gateway 上的
Route
资源定义的规则,进行流量匹配、处理(如重写、过滤)和转发到相应的后端 Kubernetes Services。
这个流程清晰地划分了不同角色的职责,使得基础设施管理、网关实例配置和应用路由规则定义可以并行进行,互不干扰(在权限允许的范围内)。
5. Gateway API 的核心优势总结
Gateway API 相较于 Ingress API 带来了显著的提升:
- 强大的表达能力: 通过结构化的 API 字段,原生支持复杂的路由匹配规则(头部、方法、查询参数等)和流量控制操作(权重分流、镜像、重写、重定向),无需依赖特定注解。
- 标准的 API 规范: 核心功能通过标准的 API 字段实现,提高了跨不同 Gateway Controller 实现的可移植性,降低了厂商锁定。
- 清晰的角色分离:
GatewayClass
,Gateway
,Route
资源分别对应基础设施提供者、集群操作员和应用开发者,使得职责边界清晰,权限管理更精细。 - 增强的可扩展性: 通过
parametersRef
和Policy
机制,提供了标准的方式来扩展网关功能和配置,而不会污染核心 API 资源。 - 更好的可管理性: 资源间的父子引用关系和状态字段提供了清晰的配置和状态信息,使得故障排查和管理更加容易。跨命名空间引用和
allowedRoutes
策略增强了安全性。 - API 版本的成熟度: Gateway API 经历了多个版本的迭代(alpha, beta, v1),并逐渐趋于稳定和通用可用 (GA)。核心的
GatewayClass
,Gateway
,HTTPRoute
已达到 GA 阶段,生产可用性高。
6. Gateway API 与 Ingress API 的对比
特性 | Ingress API | Gateway API |
---|---|---|
API Maturity | v1 (稳定) | GatewayClass, Gateway, HTTPRoute 已达到 v1 (稳定);其他 Route 类型和策略在不同阶段 |
角色导向 | 不明确,通常一个资源服务多个角色 | 清晰的角色分离 (Infrastructure, Operator, Developer) |
表达能力 | 有限 (主要依赖主机和路径),高级功能依赖注解 | 强大且标准化的字段支持复杂的匹配和动作 |
标准化程度 | 核心功能标准化,高级功能依赖厂商特定注解 | 大部分功能通过标准化 API 字段实现,可移植性高 |
可扩展性 | 主要通过非结构化的注解实现 | 通过 parametersRef 和 Policy 机制实现结构化扩展 |
资源结构 | 单一 Ingress 资源 |
分层的资源结构 (GatewayClass -> Gateway -> Route -> Policy ) |
流量拆分/权重 | 通常通过注解实现 | 原生支持 backendRefs 中的 weight 字段 |
头部/方法匹配 | 通常通过注解实现 | HTTPRouteRule.matches 原生支持 |
URL 重写/重定向 | 通常通过注解实现 | HTTPRouteRule.filters 原生支持 |
跨命名空间引用 | 不支持或依赖特定控制器实现 | 通过 parentRefs 和 allowedRoutes 标准化支持 |
TLS 配置 | 在 Ingress 资源中配置,受限于 Ingress 定义 |
在 Gateway.listeners 中配置,更灵活 |
总的来说,Gateway API 是 Ingress API 的自然演进和有力替代者。它吸收了 Ingress 的经验教训,从一开始就以更高的视角和更完善的设计来解决流量入口问题。
7. 生态系统和采纳现状
Gateway API 得到了 Kubernetes 社区和众多厂商的积极支持。主要的 Ingress Controller 提供商,如 NGINX, HAProxy, Traefik, Istio, Contour 等,都已经或正在开发其 Gateway API 实现。云服务提供商(如 Google GKE, Amazon EKS, Microsoft AKS)也正在将其托管的负载均衡服务集成到 Gateway API 中,允许用户通过 Gateway 资源直接配置云负载均衡器。
这意味着用户可以选择最适合其需求的 Gateway Controller 实现,而无需担心底层 API 的差异。
8. 如何开始使用 Gateway API
要开始使用 Gateway API,你需要:
- 在集群中安装 Gateway API CRDs: Gateway API 不是 Kubernetes 核心的一部分,需要单独安装其自定义资源定义 (CRDs)。通常可以通过
kubectl apply -k https://github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.1.0
(请替换为最新版本) 来安装。 - 部署一个 Gateway Controller 实现: 选择一个支持 Gateway API 的控制器,并按照其文档进行部署。这个控制器会负责监听 Gateway API 资源并配置底层网络。
- 创建 GatewayClass: 根据你选择的控制器文档,创建相应的
GatewayClass
资源。 - 创建 Gateway 实例: 创建
Gateway
资源,引用你创建的GatewayClass
,并配置监听器。 - 创建 Route 资源: 根据你的应用需求,创建
HTTPRoute
(或TLSRoute
等) 资源,并引用你创建的Gateway
实例。 - 验证状态: 检查
Gateway
和Route
资源的status
字段,确认它们是否已成功被控制器处理并生效。
9. 未来发展
Gateway API 社区仍在积极开发新的功能和 Route 类型。未来的工作可能包括更丰富的策略附件(如统一的认证/授权策略)、更多协议的支持、更好的观测性集成以及与其他网络功能的更紧密协同。随着 API 的成熟和采纳的广泛,Gateway API 将成为 Kubernetes 集群中管理流量入口和出口的标准方式。
10. 总结
Kubernetes Gateway API 是对传统 Ingress API 的一次重大升级,它通过引入 GatewayClass
, Gateway
, Route
等核心资源,实现了清晰的角色分离、强大的表达能力和良好的可扩展性。它解决了 Ingress API 在标准化、复杂性管理和高级功能支持方面的不足,为用户提供了一个更灵活、更安全、更易于管理的流量入口解决方案。
无论是对于基础设施提供者、集群操作员还是应用开发者,Gateway API 都提供了各自所需的抽象层次和控制能力。随着其 v1 版本的发布和生态系统的日益完善,Gateway API 正迅速成为 Kubernetes 网络领域的下一代标准。掌握 Gateway API 将帮助你更有效地管理和暴露在 Kubernetes 上运行的应用服务,应对日益复杂的网络需求。现在是时候开始了解和采纳 Gateway API 了!