My apologies, I made a mistake and tried to use a tool that isn’t available. I cannot directly write the article to a file. Instead, I will output the article content here.
理解 Kubernetes Gateway API:全面介绍与实践
引言
在现代云原生应用中,高效、灵活地管理进出 Kubernetes 集群的流量至关重要。长期以来,Kubernetes Ingress API 在这一领域扮演了关键角色,但随着云原生生态的不断演进和复杂业务需求的增加,Ingress API 的局限性也日益凸显。为了解决这些挑战,并提供一个更强大、更具表达力且面向未来的流量管理标准,Kubernetes Gateway API 应运而生。它旨在成为下一代 Kubernetes 流量管理的事实标准,为集群操作员和应用开发者提供前所未有的控制力和灵活性。
Kubernetes Gateway API 是什么?
Kubernetes Gateway API 是一个官方的 Kubernetes 项目,专注于 Layer 4 (L4) 和 Layer 7 (L7) 路由。它提供了一套标准化的接口,用于配置和管理外部流量如何进入集群(Ingress)以及内部流量如何在服务之间进行路由。相较于主要关注 HTTP 流量的 Ingress API,Gateway API 的支持范围更广,包括 HTTP、HTTPS、gRPC、TCP 和 UDP(其中 UDPRoute 仍处于实验阶段)等多种协议。
其核心目标是:
* 灵活性: 支持更高级的流量路由场景。
* 可扩展性: 允许第三方扩展和自定义功能。
* 角色导向: 明确划分不同用户角色的职责,简化配置。
* 标准化: 减少厂商锁定,提高配置的可移植性。
为何选择 Gateway API?与 Ingress 的对比
为了更好地理解 Gateway API 的价值,我们首先回顾 Ingress API 的一些局限性,并与 Gateway API 的优势进行对比。
Ingress 的局限性回顾
- 表达能力有限: Ingress 资源本身的功能相对基础,例如高级的流量拆分、头部匹配或请求重写等功能往往需要通过特定 Ingress 控制器提供的注解(annotations)来实现。这导致配置不一致,并增加了厂商锁定风险。
- 配置复杂性: 在复杂的场景下,如需要对同一主机名进行多个路径或规则的路由,Ingress 规则可能变得冗长且难以管理。
- 厂商依赖性: 不同的 Ingress 控制器(如 NGINX Ingress Controller、HAProxy Ingress 等)对注解的实现和行为可能存在差异,导致配置在不同环境中不兼容,降低了可移植性。
- 协议支持有限: Ingress 主要为 HTTP/HTTPS 流量设计,对其他协议(如 TCP/UDP)的支持非常有限或根本没有。
- 缺乏角色导向设计: Ingress 资源通常由应用开发者直接管理,这使得基础设施团队难以在集群级别强制执行统一的流量策略或提供标准的入口点。
Gateway API 的优势
Gateway API 旨在克服上述限制,提供更强大、更清晰的流量管理模型:
- 更强大的表达能力和灵活性: Gateway API 原生支持许多 Ingress 需要注解才能实现的高级功能,例如:
- 细粒度的流量匹配(基于请求头、查询参数等)。
- 灵活的流量加权拆分(用于灰度发布、A/B 测试)。
- 请求重写和重定向。
- 跨命名空间路由。
- 原生支持多种协议: 除了 HTTP/HTTPS,Gateway API 还通过专门的
Route资源支持 gRPC、TCP 和 UDP 流量,满足更广泛的应用需求。 - 角色导向设计 (Role-Oriented Design): 这是 Gateway API 最显著的特点之一。它将流量管理的职责清晰地划分为不同的角色,每个角色负责管理不同的资源:
- 基础设施提供者 (Infrastructure Provider / “Ian”): 负责部署 Gateway API 控制器本身(例如 NGINX Gateway Fabric, Envoy Gateway, Istio 等),并可能创建和管理
GatewayClass资源,定义不同类型的网关实现。 - 集群操作员 (Cluster Operator / “Chihiro”): 负责创建
Gateway资源,定义集群的入口点、监听器和安全策略。他们是流量进入集群的守门人。 - 应用开发者 (Application Developer / “Ana”): 负责创建
Route资源(如HTTPRoute),将其应用绑定到Gateway,并配置具体的应用流量路由规则。
这种职责分离使得每个团队都能专注于自己的核心任务,降低了配置的复杂性和潜在的冲突。
- 基础设施提供者 (Infrastructure Provider / “Ian”): 负责部署 Gateway API 控制器本身(例如 NGINX Gateway Fabric, Envoy Gateway, Istio 等),并可能创建和管理
- 更好的可移植性: Gateway API 定义了一套标准化的 API 规范,不同的 Gateway 控制器都应遵循。这意味着一旦你为 Gateway API 编写了配置,它在不同的控制器实现之间具有更好的可移植性,减少了厂商锁定。
- 更强的安全性:
ReferenceGrant等机制允许对跨命名空间引用进行精细控制,增强了集群的安全性。
核心概念与资源
Gateway API 通过一系列自定义资源定义(CRD)协同工作,共同管理流量。理解这些资源是掌握 Gateway API 的关键。
角色划分
Gateway API 的设计明确了三个主要角色,每个角色负责管理特定类型的资源:
- 基础设施提供者 (Infrastructure Provider / “Ian”): 负责部署 Gateway API 控制器本身(例如 NGINX Gateway Fabric, Envoy Gateway, Istio 等),并可能创建和管理
GatewayClass资源,定义不同类型的网关实现。 - 集群操作员 (Cluster Operator / “Chihiro”): 负责定义
Gateway资源,指定实际的入口点和监听配置(如端口、协议、TLS 证书等)。他们是流量进入集群的守门人。 - 应用开发者 (Application Developer / “Ana”): 负责定义
Route资源(如HTTPRoute),将他们的服务暴露给Gateway,并配置具体的路由规则(如路径匹配、主机名、流量权重等)。
主要 CRD
-
GatewayClass- 作用:
GatewayClass是一个集群范围的资源,它定义了Gateway实例的模板以及哪个控制器将处理这些Gateway。它类似于 Ingress 中的 IngressClass,但功能更强大。一个GatewayClass指定了一个controllerName,该名称指向负责实现该类网关功能的控制器。 - 示例:
yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: my-gateway-class
spec:
controllerName: example.com/gateway-controller
- 作用:
-
Gateway- 作用:
Gateway代表集群中的一个实际网络入口点。它定义了监听器(listeners),包括端口、协议、TLS 配置等,以及它将使用哪个GatewayClass。它由集群操作员管理。 - 示例:
yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-simple-gateway
namespace: default
spec:
gatewayClassName: my-gateway-class # 确保替换为实际的 GatewayClass 名称
listeners:
- name: http
protocol: HTTP
port: 80
# - name: https # 示例:如果需要 HTTPS
# protocol: HTTPS
# port: 443
# tls:
# mode: Terminate
# certificateRefs:
# - kind: Secret
# name: my-tls-secret # 替换为您的 TLS Secret 名称
- 作用:
-
Route资源族
Route资源负责定义如何将流量从Gateway路由到后端的 KubernetesService。它们是协议特定的,并允许应用开发者定义细粒度的路由规则。-
HTTPRoute- 作用: 用于路由 HTTP/HTTPS 流量。它允许基于主机名、路径、HTTP 方法、请求头和查询参数进行匹配。支持复杂的流量管理功能,如多后端服务权重、请求重写、重定向等。
- 示例:
yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-app-route
namespace: default
spec:
parentRefs:
- name: my-simple-gateway # 绑定到之前定义的 Gateway
hostnames:
- "example.com" # 替换为您的域名,或留空以匹配所有
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: my-api-service # 路由到名为 my-api-service 的 Service
port: 80
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: my-webapp-service # 路由到名为 my-webapp-service 的 Service
port: 80
-
GRPCRoute- 作用: 专门用于路由 gRPC 流量,支持基于 gRPC 服务和方法名称的匹配。
-
TCPRoute/UDPRoute- 作用: 用于路由 TCP 和 UDP 流量,提供 L4 层的路由能力。
-
-
ReferenceGrant- 作用: 这是一个安全机制,允许
Route资源在不同命名空间中引用Service、Secret等资源。它解决了跨命名空间引用时的权限问题,由目标资源的拥有者创建。 - 示例:
yaml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-default-to-foo
namespace: foo # 允许在 foo 命名空间中被引用
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespaces: ["default"] # 允许 default 命名空间的 HTTPRoute 引用
to:
- group: ""
kind: Service
name: my-service # 允许引用 foo 命名空间下的 my-service
- 作用: 这是一个安全机制,允许
工作原理:流量管理流程
Gateway API 的流量管理遵循一个清晰的声明式工作流:
- 安装 CRD: 首先,Gateway API 的 CRD 必须安装到 Kubernetes 集群中。大多数 Gateway API 控制器会负责这一步骤。
- 部署 Gateway API 控制器: 部署一个实现了 Gateway API 规范的控制器(例如 NGINX Gateway Fabric, Envoy Gateway, Istio, Cilium Gateway 等)。这个控制器负责观察 Gateway API 资源并根据其配置管理底层网络基础设施。
- 定义
GatewayClass(基础设施提供者/集群操作员): 如果控制器没有默认的GatewayClass,或者需要定义不同的网关实现类型,则需要创建GatewayClass。 - 创建
Gateway实例 (集群操作员): 集群操作员创建Gateway资源,引用一个GatewayClass,并配置监听器(端口、协议、TLS)。Gateway将会提供一个实际的 IP 地址或 DNS 名称作为集群的入口。 - 配置
Route资源 (应用开发者): 应用开发者创建Route资源(如HTTPRoute),指定它们希望连接到哪个Gateway,并定义具体的路由规则。这些Route资源将流量从Gateway转发到后端的Service。
当这些资源都创建并生效后,外部流量到达 Gateway 定义的 IP/主机名和端口,Gateway 控制器会根据 Route 资源的规则将流量路由到正确的后端服务。
实践:一个简单的 HTTP 路由示例
为了演示 Gateway API 的实践,我们将概述如何配置一个简单的 HTTP 路由:
-
部署 Gateway API 控制器: 选择并安装一个 Gateway API 控制器,例如 NGINX Gateway Fabric 或 Envoy Gateway。安装过程通常会包含部署控制器 Pods 和相关的
GatewayClass资源。 -
创建
Gateway:
假设my-gateway-class已经由控制器安装。我们创建一个Gateway来监听 HTTP 流量。
yaml
# my-gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-simple-gateway
namespace: default
spec:
gatewayClassName: my-gateway-class # 使用你选择的控制器提供的 GatewayClass
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes: # 示例:允许来自 default 命名空间的所有 HTTPRoute 绑定
kinds:
- kind: HTTPRoute
namespaces:
from: Same
执行kubectl apply -f my-gateway.yaml。等待Gateway资源的状态变为Ready,并获取其分配的 IP 地址或主机名。 -
部署后端应用和
Service:
部署一个简单的 NGINX 应用作为后端服务。
yaml
# my-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx-app
namespace: default
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-nginx-service
namespace: default
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
执行kubectl apply -f my-app.yaml。 -
创建
HTTPRoute:
创建一个HTTPRoute将所有发送到my-simple-gateway的 HTTP 流量路由到my-nginx-service。
yaml
# my-httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: nginx-route
namespace: default
spec:
parentRefs:
- name: my-simple-gateway # 绑定到之前创建的 Gateway
namespace: default # Gateway 所在的命名空间
hostnames:
- "www.example.com" # 替换为您的域名,或如果通过 IP 访问则可省略
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: my-nginx-service
port: 80
执行kubectl apply -f my-httproute.yaml。
现在,当您通过 my-simple-gateway 的 IP 地址或 www.example.com(如果配置了 DNS 解析)访问集群时,流量将被路由到 my-nginx-app 服务。您可以通过 kubectl get gateway -o wide 和 kubectl get httproute 来检查资源的状态和详情。
总结与展望
Kubernetes Gateway API 不仅仅是对 Ingress API 的简单升级,它代表了 Kubernetes 流量管理哲学的一次重大演进。通过引入强大的表达能力、灵活的协议支持和创新的角色导向设计,Gateway API 为复杂的云原生环境提供了更健壮、更易于管理且更安全的企业级流量解决方案。
随着 Gateway API 的成熟和广泛采用(其核心资源如 GatewayClass, Gateway, HTTPRoute 已于 2023 年 10 月达到 GA 稳定版),它将成为构建高性能、高可用性和可扩展 Kubernetes 应用不可或缺的基石。对于任何希望在 Kubernetes 环境中实现精细化流量控制和优化网络架构的组织来说,理解和实践 Gateway API 都将是未来的必然趋势。