欢迎光临
我们一直在努力

K8s Gateway API 全面指南:从入门到实践

K8s Gateway API 全面指南:从入门到实践

引言
随着 Kubernetes 集群规模的不断扩大和应用复杂度的提升,传统的 Ingress API 已逐渐难以满足现代服务网络管理的需求。作为 Kubernetes 官方推出的新一代服务网络 API,Gateway API 以其强大的路由能力、灵活的多团队支持和标准化的扩展机制,成为了构建现代化 Kubernetes 网络的理想选择。

本文将从 Gateway API 的基本概念出发,详细对比其与 Ingress 的差异,带你一步步完成安装配置,并通过实际示例掌握其核心使用方法,帮助你快速上手这一 Kubernetes 网络新利器。

一、什么是 Gateway API?

1.1 概述

Gateway API 是 Kubernetes 官方推出的新一代服务网络 API,旨在替代和扩展传统的 Ingress API。它提供了更强大、更灵活的流量管理能力,支持更复杂的路由场景和多团队协作。

  • 官网:https://gateway-api.sigs.k8s.io/
  • Envoy Gateway 控制器官网:https://gateway.envoyproxy.io/
  • MetalLB 官网:https://metallb.io

1.2 核心特性

  • 层次化设计:通过 GatewayClass、Gateway、Route 等资源实现分层管理

  • 更丰富的路由能力:支持基于路径、方法、头部的精细化路由

  • 多团队支持:内置的所有权和权限模型

  • 类型安全:强类型的 API 定义

  • 扩展性:更好的插件和自定义能力

二、Gateway API 与 Ingress 的对比

特性IngressGateway API
API 版本 v1 v1 (稳定版)
路由能力 基础的路径和主机路由 支持路径、方法、头部、查询参数等多种路由规则
多团队支持 有限,需要额外配置 内置的 RBAC 集成和所有权模型
扩展性 依赖注解,不标准 标准的扩展机制
流量类型 主要支持 HTTP/HTTPS 支持 HTTP/HTTPS、TCP、UDP 等多种协议
策略管理 分散在各个资源中 集中的策略定义和复用
实现状态 广泛实现 主流 ingress 控制器已支持

Envoy Gateway 依赖于 Envoy Proxy 和 Gateway API,并在 Kubernetes 集群中运行。并非所有版本的 Envoy Proxy 和 Gateway API 都能兼容运行。支持的版本组合如下所示;粗体字表示每个 Envoy Gateway 版本实际编译的 Envoy Proxy 和 Gateway API 版本。
在这里插入图片描述

三、安装 Gateway API

3.1 前提条件

  • Kubernetes 集群(推荐 1.24+)

  • kubectl 命令行工具

  • 支持 Gateway API 的 Ingress 控制器(如 Contour、Istio、NGINX Kubernetes Ingress Controller 等)

  • Gateway API 的控制器默认不创建对外 server,它只负责路由逻辑,真正的对外暴露仍需通过 LoadBalancer/NodePort/MetalLB 等手段配合实现。(意思就是需要云服务器或者有负载均衡的地址)

  • 因为测试环境没有 LB 地址,还需要安装 MetalLB

  • MetalLB 官网:https://metallb.io

3.2 可直接在裸机上部署的控制器

Cilium Gateway

Cilium 网络栈集成后,它会用 LoadBalancer 或 NodePort 类型的 Service 来暴露数据平面(Envoy or embedded listener)。

  • 支持主机网络模式(host network),可让 Gateway 监听在所有节点的 0.0.0.0,从而在裸金属上直接暴露端口,无需 LoadBalancer/MetalLB
Istio Gateway API 实现

Istio IngressGateway 或 Gateway API 模式下,会自动创建 Envoy Deployment 和对应 Service。这样,配置好 Gateway 之后,它会自动生成一组对外可访问的入口资源(Service / Deployment)并更新状态。

Contour(Envoy-based)
  • 在裸金属和本地环境中,Contour 的 Service 通常也能通过 LoadBalancer/NodePort 方式配置对外访问。

本教程以 Envoy Gateway 为例进行演示,并且 Gateway API 允许同时安装多个控制器

3.3 安装 Gateway API CRDs

执行以下命令安装最新稳定版 Gateway API CRDs:

# 安装最新稳定版 Gateway API CRDs
kubectl apply –server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/standard-install.yaml

# 验证安装。下面这两个命令任选其一验证即可。
kubectl get crd | grep networking.k8s.io
# 或更具体地验证关键 CRD
kubectl get crd gateways.gateway.networking.k8s.io httproutes.gateway.networking.k8s.io gatewayclasses.gateway.networking.k8s.io

安装成功后,你将看到类似以下输出:

backendtlspolicies.gateway.networking.k8s.io 2026-02-06T09:10:49Z
gatewayclasses.gateway.networking.k8s.io 2026-02-06T09:10:49Z
gateways.gateway.networking.k8s.io 2026-02-06T09:10:49Z
grpcroutes.gateway.networking.k8s.io 2026-02-06T09:10:49Z
httproutes.gateway.networking.k8s.io 2026-02-06T09:11:04Z
referencegrants.gateway.networking.k8s.io 2026-02-06T09:11:05Z

3.3 安装 Envoy Gateway 控制器

使用 Helm 安装 Envoy Gateway 控制器:

# 官方安装方法很多,根据自己喜好即可。这里使用 Helm 安装
helm install eg oci://docker.io/envoyproxy/gateway-helm –version v1.7.0 -n envoy-gateway-system –create-namespace

# 等待 Envoy Gateway 可用:
kubectl wait –timeout=5m -n envoy-gateway-system deployment/envoy-gateway –for=condition=Available

安装完成后,Envoy Gateway 控制器将在 envoy-gateway-system 命名空间中运行,随时准备处理 Gateway API 资源。

3.4 安装 MetalLB

首先,修改 kube-proxy 配置以启用 strictARP:

对于二进制安装的 Kubernetes:

# 编辑 kube-proxy 配置文件
cat /etc/kubernetes/kube-proxy.yaml
# 添加以下内容
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
strictARP: true

# 修改好以后重启服务
systemctl restart kube-proxy.service

对于 kubeadm 安装的 Kubernetes:

# 编辑 kube-proxy 配置
kubectl edit cm kube-proxy -n kube-system
# 添加和修改上面的内容

# 修改好以后重启服务
kubectl patch daemonset kube-proxy -n kube-system -p "{\\"spec\\":{\\"template\\":{\\"metadata\\":{\\"annotations\\":{\\"date\\":\\"$(date +'%s')\\"}}}}}"

3.5 安装 MetalLB 服务

执行以下命令安装 MetalLB:

# 安装 MetalLB
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.3/config/manifests/metallb-native.yaml

提示:如果这个配置文件下载不了,可以私信我获取。

3.6 配置 MetalLB IP 池 & 广播

创建 metallb-config.yaml 文件并应用:

# metallb-config.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: publicippool
namespace: metallbsystem
spec:
addresses: # 这个是地址池,可以配置多个地址,官网有详细的配置方法
192.168.1.100/32 # 这个地址必须是未使用的地址,不能使用高可用的 IP 地址


apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: publicipadvertisement
namespace: metallbsystem
spec:
ipAddressPools:
publicippool

应用配置:

kubectl apply -f metallb-config.yaml

四、使用 Gateway API

4.1 基本概念

  • GatewayClass:定义网关类型,类似于 StorageClass

  • Gateway:实际的网关实例,管理网络流量入口

  • HTTPRoute:定义 HTTP/HTTPS 流量的路由规则

  • TCPRoute/UDPRoute:定义 TCP/UDP 流量的路由规则

4.2 示例:创建基本的 HTTP 路由

4.2.1 创建 GatewayClass

GatewayClass 是 Gateway 的类别模板,指明使用哪种控制器来管理对应的 Gateway。它是集群级资源(Cluster-scoped),没有命名空间的概念。

# 创建 GatewayClass
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: eg # GatewayClass 名称
spec:
controllerName: gateway.envoyproxy.io/gatewayclasscontroller # 指定使用 Envoy Gateway 控制器

应用配置:

kubectl apply -f gatewayclass.yaml

4.2.2 创建 Gateway

Gateway 定义实际的监听器(端口/协议/路由绑定行为等,类似 Ingress 开放的默认端口 80 或者 443)。它是命名空间级(Namespaced)资源,在不同的命名空间可以有同名的资源。

默认情况下,Gateway 只接受同一命名空间的 Routes,但可以通过 allowedRoutes 设置跨 Namespace 规则。

# 创建 Gateway(在 demo01 命名空间中)
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: eg
namespace: demo01
spec:
gatewayClassName: eg # 引用之前创建的 GatewayClass
addresses:
type: IPAddress
value: 192.168.1.100 # 修改为刚刚配置的 MetalLB 地址池中的地址
listeners:
name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All # 允许所有命名空间的 Routes 绑定到这个 Gateway

应用配置:

# 首先创建 demo01 命名空间
kubectl create namespace demo01

# 应用 Gateway 配置
kubectl apply -f gateway.yaml

4.2.3 创建应用

创建一个简单的后端应用,包括 Service、ServiceAccount 和 Deployment:

# app.yaml
apiVersion: v1
kind: Service
metadata:
name: backend
namespace: demo01
labels:
app: backend
service: backend
spec:
ports:
name: http
port: 3000
targetPort: 3000
selector:
app: backend

apiVersion: v1
kind: ServiceAccount
metadata:
name: backend
namespace: demo01

apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
namespace: demo01
spec:
replicas: 1
selector:
matchLabels:
app: backend
version: v1
template:
metadata:
labels:
app: backend
version: v1
spec:
serviceAccountName: backend
containers:
image: gcr.io/k8sstaginggatewayapi/echobasic:v20231214v1.0.0140gf544a46e
imagePullPolicy: IfNotPresent
name: backend
ports:
containerPort: 3000
env:
name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace

应用配置:

kubectl apply -f app.yaml

4.2.4 创建 HTTPRoute

HTTPRoute 指定如何将来自 Gateway 的请求路由到特定后端服务。它是命名空间级(Namespaced)资源,按 namespace 进行隔离,但可以通过 parentRefs 引用某个 Gateway(可以是同命名空间也可以跨命名空间)。

# httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: backend
namespace: demo01
spec:
parentRefs:
name: eg # 引用之前创建的 Gateway
namespace: demo01
hostnames:
"gateway.demo.cn" # 配置域名
rules:
backendRefs:
group: ""
kind: Service
name: backend # 引用后端服务
port: 3000
weight: 1
matches:
path:
type: PathPrefix
value: / # 匹配所有路径

应用配置:

kubectl apply -f httproute.yaml

配置完成后,你可以通过添加 host 记录(将 gateway.demo.cn 指向 192.168.1.100)来访问这个服务。

4.3 示例:配置 HTTPS 访问

4.3.1 准备证书或自签证书

要启用 HTTPS 访问,你需要:

  • 创建 Kubernetes Secret 存放证书和私钥
  • 在 Gateway 的 listener 上启用 HTTPS/TLS 并引用这个 Secret
4.3.2 创建 Kubernetes Secret

将证书和私钥封装进 Secret:

kubectl create secret tls example-cert \\
–cert=example.com.crt \\
–key=example.com.key \\
-n envoy-gateway-system

👉 命名空间应与你部署 Gateway 的 namespace 一致(通常是 Envoy Gateway 安装命名空间)或者是 listener 所在的 namespace。

4.3.3 配置 Gateway 加入 HTTPS listener

下面是一个常见的 HTTPS listener 示例:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: mygateway
namespace: envoygatewaysystem
spec:
gatewayClassName: envoygateway
listeners:
name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
kind: Secret
name: examplecert
allowedRoutes:
namespaces:
from: All

五、在不同命名空间配置方法

举例:Gateway 在 demo01 命名空间,HTTPRoute 和服务可以在其他命名空间

首先,修改 Gateway 配置以允许所有 Namespace 的 HTTPRoute 绑定:

# shared-gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: sharedgateway
namespace: demo01
spec:
gatewayClassName: eg
listeners:
name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All # 允许所有 Namespace HTTPRoute 绑定

应用配置:

kubectl apply -f shared-gateway.yaml

应用

修改命名空间为demo02

## 只粘贴了部分代码
apiVersion: v1
kind: Service
metadata:
name: backend
namespace: demo02
labels:
app: backend
service: backend
spec:
ports:
name: http
port: 3000
targetPort: 3000
selector:
app: backend

apiVersion: v1
kind: ServiceAccount
metadata:
name: backend
namespace: demo02

apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
namespace: demo02
spec:
replicas: 1
selector:
matchLabels:

创建 HTTPRoute

例如:应用和 httproute 都在demo02 中的想要使用 demo01的gateway 配置如下

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: approute
namespace: demo02 ## 应用和HTTPRoute所在命名空间
spec:
parentRefs:
name: sharedgateway
namespace: demo01 ## gateway所咋的命名空间
hostnames:
"app.example.com"
rules:
matches:
path:
type: PathPrefix
value: /
backendRefs:
name: appsvc
port: 80

  • 在生产环境里,不一定要每个命名空间都部署一个 Gateway 通常由基础设施团队部署一两个“共享的 Gateway”,各业务命名空间通过 HTTPRoute(有或没有跨命名空间权限)来挂载到这些 Gateway 上。
  • 跨命名空间访问要通过 allowedRoutes.namespaces 明确允许,并可能配合 ReferenceGrant 控制另一种跨命名空间引用(比如 backend Service)。

六、ReferenceGrant(跨命名空间引用 Service/Secret)

如果你的 HTTPRoute 想引用的是 另一个命名空间的 Service 或证书 Secret
(比如 demo01 想路由到 demo02 的 Service),这需要 ReferenceGrant 来显式授权:
意思就是 服务A要访问服务B,就在B服务的命名空间创建 ReferenceGrant 授权。

apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allowfrontendtobackend
namespace: demo02
spec:
from:
group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: demo01
to:
group: ""
kind: Service

  • 注意:ReferenceGrant 是用于 跨 namespace 引用资源(如 Service/Secret),和 allowedRoutes 不同——allowedRoutes 是允许路由附加到 Gateway。

七、HTTPRoute(来自 frontend Namespace)

下面是 frontend 的 HTTPRoute,它引用 backend 的 Service:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: frontendroute
namespace: demo01
spec:
parentRefs:
name: sharedgateway
namespace: demo01 # 明确引用不同 Namespace 的 Gateway
hostnames:
"app.example.com"
rules:
matches:
path:
type: PathPrefix
value: /
backendRefs:
name: backendsvc
namespace: demo02 # 引用 backend Namespace 的 Service
port: 80

主要点:

  • 共享 Gateway + 各命名空间 HTTPRoute 是推荐模式
  • 跨命名空间路由 由 Gateway 的 allowedRoutes.namespaces 控制
  • 跨命名空间服务引用(Service/Secret)由 ReferenceGrant 授权控制(需要提前授权)
  • 只有当 HTTPRoute 或其它路由资源引用了 不同命名空间 的 Kubernetes 对象(比如 Service / Secret)时,才需要创建 ReferenceGrant。**
  • 如果路由引用的是 当前 HTTPRoute 所在 namespace 内的资源(同 namespace),则 不需要 ReferenceGrant。这是 Gateway API 的标准行为。
场景是否需要 ReferenceGrant
HTTPRoute → 同 namespace 的 Service / Secret ❌ 不需要
HTTPRoute → 不同 namespace 的 Service / Secret ✅ ReferenceGrant 必须存在
Gateway → 不同 namespace 的 Secret / 参数引用 ✅ ReferenceGrant 必须存在
Route 附加到不同 namespace 的 Gateway ⚠️ 需 allowedRoutes 显式允许

为什么会有这个规则?

在 Kubernetes Gateway API 里:

  • 同名空间引用本地资源时(比如 HTTPRoute → Service 在同一个 namespace),引用默认是允许的,不需要额外授权。
  • 跨命名空间引用时(比如 HTTPRoute 在 foo namespace 引用 bar namespace 的 Service),为了安全和权限约束,必须由 目标 namespace 中的管理员显式授权这个跨 namespace 的引用关系——这就是 ReferenceGrant 的作用。
    ReferenceGrant 是一种安全防护机制,用来避免恶意或无意间跨 namespace 使用资源而没有被 Namespace 资源所有者允许的情况。

八、总结

作为 Kubernetes 官方力推的新一代服务网络解决方案,Gateway API 以其层次化设计、强大的路由能力和原生的多团队支持,为我们打开了 Kubernetes 网络管理的新篇章。与传统的 Ingress API 相比,它不仅解决了原有方案的局限性,更通过标准化的扩展机制和类型安全的 API 定义,为我们提供了一套更加灵活、可靠的服务网络管理工具。

通过本文的学习,您已经掌握了:

  • Gateway API 的核心概念和优势
  • 与传统 Ingress 的详细对比
  • 完整的安装配置流程(包括 MetalLB 配置)
  • 基本的 HTTP 路由创建方法
  • 跨命名空间路由和服务引用的实现技巧

写在最后:

我在生产环境中并未使用过 Gateway API 此文档依据官方文档和测试环境搭建并撰写如有问题请私信或留言。


关注微信公众号 Linux容器运维 并回复关键字 “视频资料”,即可获取我们整理的 Kubernetes、Docker 容器、Python 编程、Linux 运维等教学视频合集(总计 548GB)。本资源仅面向学习交流使用,请遵守版权和使用规范,严禁商用、转售或违规传播。

赞(0)
未经允许不得转载:171主机测评 » K8s Gateway API 全面指南:从入门到实践
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址