K8s Gateway API 入门与实践
引言
在 Kubernetes 的生态系统中,如何有效地管理集群内外部流量的路由一直是一个核心且复杂的问题。传统的 Ingress API 在简化 HTTP/HTTPS 流量管理方面发挥了重要作用,但随着云原生应用的日益复杂,Ingress 的局限性也逐渐显现。为了解决这些挑战,Kubernetes 社区推出了新一代的服务网络 API——Gateway API。
Gateway API 旨在提供比 Ingress API 更强大、更灵活、更具表达力的流量管理能力。它是一个官方的 Kubernetes 项目,专注于 Kubernetes 中的 L4(传输层)和 L7(应用层)路由,并已被设计为通用、富有表现力且面向角色的标准。
为什么选择 Gateway API?
Gateway API 的引入,旨在解决 Ingress 长期存在的痛点,并带来以下核心优势:
- 面向角色 (Role-oriented): Gateway API 将基础设施提供者、集群操作员和应用开发人员等不同角色的职责明确划分。这使得各方能够安全、高效地共享和管理底层网络基础设施,从而减少沟通障碍和潜在冲突。
- 可移植性 (Portable): 作为开放标准,Gateway API 拥有众多实现(如 Envoy Gateway, NGINX Gateway Fabric, Cilium Gateway 等),确保了其核心概念和资源在不同实现和环境中的一致性,避免了供应商锁定。
- 表达能力强 (Expressive): Gateway API 内置支持丰富的路由功能,例如基于 Header 匹配、流量加权、请求重写、流量镜像等高级特性。这些功能在 Ingress 中通常需要依赖控制器特定的注解才能实现,而 Gateway API 将其标准化并提升为 API 的一部分。
- 可扩展性 (Extensible): 允许在 API 的各个层链接自定义资源 (Custom Resources),从而在 API 结构内的适当位置进行更精细的定制和功能扩展,满足各种复杂的流量管理需求。
核心概念与资源
Gateway API 通过引入一套新的 Kubernetes 资源对象来管理流量。理解这些核心资源是掌握 Gateway API 的关键:
-
GatewayClass (网关类):
GatewayClass类似于存储领域的StorageClass,它定义了一组共享相同配置和行为的网关。每个GatewayClass都由一个特定的网关控制器 (Controller) 实现。集群管理员通常会定义GatewayClass来指定可用的网关实现及其配置。- 角色: 基础设施提供者 / 集群管理员
- 示例: 一个
GatewayClass可能指定使用 Envoy Gateway 或 NGINX Gateway Fabric 作为其控制器。
-
Gateway (网关):
Gateway资源代表了集群的流量入口点,它描述了如何将外部流量转换为集群内的服务。Gateway定义了监听器 (Listener),每个监听器指定一个端口、协议 (如 HTTP, HTTPS, TCP, TLS, UDP) 和可选的主机名,并可以配置 TLS 终止。Gateway可以映射到物理或虚拟的网络基础设施,例如云负载均衡器、服务网格的边缘代理或集群内部代理。- 角色: 集群操作员
- 示例: 定义一个监听 80 端口的 HTTP Gateway,或者一个监听 443 端口并配置 TLS 的 HTTPS Gateway。
-
Route (路由):
Route资源定义了协议特定的规则,用于将流量从Gateway监听器映射到集群内的后端服务。Gateway API 提供了多种类型的Route来支持不同的协议:- HTTPRoute: 最常用的
Route类型,用于定义 HTTP/HTTPS 请求的路由规则。它支持基于路径、Header、Query 参数、Host 的匹配规则,以及流量加权、请求重写、重定向等高级功能。 - GRPCRoute: 专门为 gRPC 服务设计的路由类型,支持基于 gRPC 方法、服务、Header 的匹配。
- TCPRoute, TLSRoute, UDPRoute: 分别用于管理 TCP、TLS 和 UDP 流量的路由。
- 角色: 应用开发人员
- 示例: 将
Host: example.com且Path: /api的 HTTP 请求路由到my-backend-service。
- HTTPRoute: 最常用的
这些资源通过相互引用形成一个完整的流量管理链条,实现清晰的角色分离和强大的功能。
与 Ingress 的对比
为了更好地理解 Gateway API 的价值,我们有必要将其与传统的 Ingress 进行对比。
| 特性 | Ingress | Gateway API |
|---|---|---|
| 层级 | 仅 L7 (HTTP/HTTPS) | L4 和 L7 (HTTP, HTTPS, TCP, TLS, UDP, gRPC) |
| 角色分离 | 基础设施与应用逻辑混杂,边界不清晰 | 清晰的角色分离 (基础设施提供者、集群操作员、应用开发人员) |
| 表达能力 | 基础路由功能,高级特性依赖注解,缺乏标准化 | 原生支持高级路由,如流量加权、Header 匹配、请求重写,标准化程度高 |
| 可扩展性 | 主要通过控制器特定注解,导致不一致性和供应商锁定 | 通过 API 结构内链接 CRD 实现可扩展,更灵活、统一 |
| 资源模型 | 扁平,所有规则集中在 Ingress 资源中 | 分层设计 (GatewayClass -> Gateway -> Route),模块化、易管理 |
| 多租户 | 支持有限,易产生冲突 | 原生支持多租户场景,不同团队可独立管理 Route |
Ingress 的主要局限在于其设计初衷是简化 HTTP 流量的基本路由。当需要更复杂的流量管理策略、多协议支持或多团队协作时,Ingress 的局限性便会凸显,往往需要依赖特定 Ingress 控制器的非标准注解,这导致了配置的碎片化和供应商锁定。
Gateway API 正是为了解决这些问题而生,它通过更模块化的设计、清晰的角色分离和更丰富的路由功能,提供了一个更灵活、更强大、更适应云原生未来的流量管理解决方案。
入门与实践
要开始使用 Kubernetes Gateway API,通常需要遵循以下步骤。这里以一个简单的 HTTP 路由为例:
步骤 1: 安装 Gateway API CRDs
首先,你需要在 Kubernetes 集群中安装 Gateway API 的自定义资源定义 (CRDs)。这是使用 Gateway API 的基础。
bash
kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
{ kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml; }
注意:
v1.0.0是一个示例版本,请根据 Gateway API 的最新稳定版本进行调整。
步骤 2: 部署 Gateway 控制器
Gateway API 本身是一套规范和资源定义,它不包含内置的控制器来实际处理流量。你需要选择并部署一个实现了 Gateway API 的控制器。常见的选择包括:
- Envoy Gateway: 一个由 Envoy 支持的官方实现,功能强大。
- NGINX Gateway Fabric: NGINX 官方提供的实现。
- Cilium Gateway: Cilium 网络插件集成的 Gateway API 实现。
- 云服务商的实现: 例如 Google Cloud Load Balancing, AWS Load Balancer Controller 等都可能提供 Gateway API 的实现。
以部署 Envoy Gateway 为例 (这可能需要根据其官方文档进行更详细的配置):
“`bash
请参考 Envoy Gateway 官方文档获取最新的安装指南
示例 (可能不适用于最新版本):
helm install envoy-gateway –create-namespace –namespace envoy-gateway oci://docker.io/envoyproxy/gateway-helm –version v0.4.0
“`
重要: 请务必查阅你选择的 Gateway 控制器的官方文档以获取准确的安装和配置说明。
步骤 3: 定义 GatewayClass
GatewayClass 告诉 Kubernetes 使用哪个控制器来管理 Gateway 资源。
“`yaml
gateway-class.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: eg
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
“`
bash
kubectl apply -f gateway-class.yaml
步骤 4: 创建 Gateway
创建一个 Gateway 资源作为集群的入口。这里我们创建一个简单的 HTTP Gateway。
“`yaml
gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-http-gateway
spec:
gatewayClassName: eg # 引用之前定义的 GatewayClass
listeners:
– name: http
port: 80
protocol: HTTP
“`
bash
kubectl apply -f gateway.yaml
等待 Gateway 状态变为 Ready,并获取其外部 IP 地址或主机名。
bash
kubectl get gateway my-http-gateway
步骤 5: 部署示例应用
部署一个简单的 Deployment 和 Service 作为后端服务。
“`yaml
app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-app
spec:
selector:
matchLabels:
app: example-app
replicas: 2
template:
metadata:
labels:
app: example-app
spec:
containers:
– name: example-app
image: nginxdemos/hello:plain-text
ports:
– containerPort: 80
apiVersion: v1
kind: Service
metadata:
name: example-service
spec:
selector:
app: example-app
ports:
– protocol: TCP
port: 80
targetPort: 80
“`
bash
kubectl apply -f app.yaml
步骤 6: 定义 HTTPRoute
现在,定义一个 HTTPRoute 将 Gateway 接收到的流量路由到 example-service。
“`yaml
http-route.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: example-route
spec:
parentRefs:
– name: my-http-gateway # 引用之前创建的 Gateway
hostnames:
– “example.com” # 或者使用 Gateway 的 IP 地址
rules:
– matches:
– path:
type: PathPrefix
value: /
backendRefs:
– name: example-service # 引用后端服务
port: 80
“`
bash
kubectl apply -f http-route.yaml
注意: 如果你的
Gateway没有外部 DNS 名称,你可以通过修改hostnames为*(不推荐用于生产) 或省略hostnames字段,并通过Gateway的 IP 地址访问。在生产环境中,通常会配置 DNS 解析将example.com指向Gateway的外部 IP。
步骤 7: 测试设置
获取 my-http-gateway 的外部 IP 地址 (EXTERNAL-IP)。
bash
kubectl get gateway my-http-gateway
假设外部 IP 是 XXX.XXX.XXX.XXX。现在你可以使用 curl 命令测试:
bash
curl -H "Host: example.com" http://XXX.XXX.XXX.XXX/
如果一切配置正确,你应该会看到 example-app 返回的 “Hello from NGINX” 或类似响应。
结论
Kubernetes Gateway API 代表了 Kubernetes 流量管理领域的重要演进。它通过引入一套结构化、面向角色的资源模型,显著提升了流量路由的灵活性、表达能力和可扩展性。相较于传统的 Ingress,Gateway API 不仅支持更广泛的协议,还提供了更强大的高级路由功能,并且通过清晰的角色划分促进了多团队协作。
对于正在寻求现代化其 Kubernetes 流量管理解决方案的组织而言,Gateway API 无疑是一个值得深入探索和实践的关键技术。随着其生态系统的不断成熟和更多控制器的涌现,Gateway API 必将成为 Kubernetes 中管理服务网络的事实标准。