在开始部署之前,我们需要先理解几个关键概念,因为这确实容易让人混淆:
Kubernetes Gateway API 是 Kubernetes 社区推出的新一代入口流量管理标准,它是一组 CRD(Custom Resource Definitions)资源定义,用于替代传统的 Ingress API。Gateway API 由 Kubernetes SIG-NETWORK 社区维护,是 Kubernetes 的官方项目。
Gateway API 的主要特点:
Envoy Gateway 是 Kubernetes Gateway API 的一个官方参考实现,由 Envoy Proxy 社区(CNCF 项目)维护。它使用 Envoy Proxy 作为数据平面,实现了 Gateway API 规范定义的各种功能。
简单来说:
官方推荐: Envoy Gateway 作为 Gateway API 的官方参考实现,由 Envoy 社区积极维护,是目前最推荐使用的 Gateway API 实现之一。它提供了完整的 Gateway API 功能支持,并且有良好的性能和稳定性保证。
其他常见的 Gateway API 实现还包括:
重要背景: NGINX Ingress Controller 维护者已经宣布,该项目将逐步减少维护力度,社区建议迁移到更现代的解决方案。这使得 Gateway API 成为 Kubernetes 入口流量管理的首选方案。
Gateway API 相比 Ingress 的优势:
本文基于以下版本进行部署:
# 检查 Kubernetes 版本
kubectl version --short
# 检查节点状态
kubectl get nodes
Gateway API 的 CRD 需要单独安装,因为它们是标准定义,独立于具体实现。
# 安装 Gateway API 标准版本 (v1.4.1 - 最新稳定版)
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/standard-install.yaml
可选
如果需要使用实验性功能(如 TCPRoute、UDPRoute、GRPCRoute 等):
# 安装包含实验性功能的完整版本 (v1.4.1)
# 注意: 实验性 CRD 可能较大,需要使用 server-side apply
kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/experimental-install.yaml
如果遇到
The CustomResourceDefinition "httproutes.gateway.networking.k8s.io" is invalid: metadata.annotations: Too long: may not be more than 262144 bytes
则需要分步安装:
wget https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/experimental-install.yaml
kubectl replace -f experimental-install.yaml
# 查看已安装的 Gateway API CRDs
kubectl get crd | grep gateway
# 应该能看到类似以下输出:
# gatewayclasses.gateway.networking.k8s.io
# gateways.gateway.networking.k8s.io
# httproutes.gateway.networking.k8s.io
# referencegrants.gateway.networking.k8s.io
以下两种方式安装 Envoy Gateway,推荐使用 Helm 方式。
推荐
# 添加 Envoy Gateway Helm 仓库
helm repo add envoy-gateway https://gateway.envoyproxy.io
helm repo update
# 创建命名空间
kubectl create namespace envoy-gateway-system
# 安装 Envoy Gateway
helm install eg envoy-gateway/gateway-helm \
--namespace envoy-gateway-system \
--create-namespace
# 可以先 pull
# helm pull envoy-gateway/gateway-helm --version 1.6.1 --untar
# 安装 Envoy Gateway v1.6.1 (最新稳定版)
kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/v1.6.1/install.yaml
# 检查 Envoy Gateway 控制器状态
kubectl get pods -n envoy-gateway-system
# 输出示例:
# NAME READY STATUS RESTARTS AGE
# envoy-gateway-7d8d8c8f6d-xxxxx 1/1 Running 0 1m
# 检查 GatewayClass
kubectl get gatewayclass
# 输出示例:
# NAME CONTROLLER ACCEPTED AGE
# eg gateway.envoyproxy.io/gateway True 1m
在创建 Gateway 之前,理解 Gateway API 与传统 Ingress 在服务暴露方式上的关键区别非常重要:
1. 部署 ingress-nginx-controller (控制平面)
↓
2. 手动创建/暴露一个 Service (LoadBalancer/NodePort)
↓
3. 创建多个 Ingress 资源 (路由规则)
↓
4. 所有 Ingress 共用同一个 LoadBalancer IP
特点:
1. 部署 Envoy Gateway (控制平面,无需暴露)
↓
2. 创建 Gateway 资源 (定义监听器)
↓
3. 系统自动创建 Envoy Proxy Deployment + Service (LoadBalancer)
↓
4. 创建多个 HTTPRoute/GRPCRoute 资源 (路由规则)
↓
5. 所有 Route 通过 parentRef 引用同一个 Gateway
↓
6. 复用同一个 LoadBalancer IP
特点:
parentRefs 引用同一个 Gateway 实现 IP 复用场景: 为 10 个应用配置不同域名的路由
使用 Ingress-nginx:
# 1 个 ingress-nginx Service (LoadBalancer)
# + 10 个 Ingress 资源 (复用同一个 IP)
# = 1 个 SLB IP
使用 Gateway API (正确方式):
# 1 个 Gateway 资源 (自动创建 LoadBalancer)
# + 10 个 HTTPRoute 资源 (通过 parentRef 引用同一个 Gateway)
# = 1 个 SLB IP
成本完全一样!
| 概念 | Ingress-nginx | Gateway API |
|---|---|---|
| 控制平面 | ingress-nginx-controller | Envoy Gateway |
| 需要暴露控制平面? | ✅ 是 | ❌ 否 |
| 路由资源 | Ingress | HTTPRoute/GRPCRoute |
| 入口点资源 | Service (手动创建) | Gateway (自动创建 Service) |
| IP 复用方式 | 多个 Ingress 共享 Service | 多个 Route 引用同一个 Gateway |
| 角色分离 | ❌ 不支持 | ✅ Gateway(运维) + Route(开发) |
重要:
创建一个简单的 HTTP Gateway:
# gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
namespace: default
spec:
gatewayClassName: eg
listeners:
- name: http
protocol: HTTP
port: 80
应用配置:
kubectl apply -f gateway.yaml
# 查看 Gateway
kubectl get gateway my-gateway
# 查看详细信息
kubectl describe gateway my-gateway
# 查看 Envoy 代理 Pod (由 Gateway 自动创建)
kubectl get pods -l gateway.envoyproxy.io/owning-gateway-name=my-gateway
# 查看自动创建的 Service (这是真正对外暴露的服务)
kubectl get svc -l gateway.envoyproxy.io/owning-gateway-name=my-gateway
# 注意: 这个 Service 的类型默认是 LoadBalancer
# 方式1: 查看 Gateway 的 LoadBalancer IP/Hostname
kubectl get gateway my-gateway -o jsonpath='{.status.addresses[0].value}'
# 方式2: 查看自动创建的 Service
kubectl get svc -l gateway.envoyproxy.io/owning-gateway-name=my-gateway
## 7.1 部署示例应用
# 输出示例:
# NAME TYPE EXTERNAL-IP PORT(S)
# envoy-my-gateway-xxxx LoadBalancer <SLB-IP> 80:30080/TCP
重要说明:
envoy-{gateway-name}-{hash}# demo-app.yaml
apiVersion: v1
kind: Namespace
metadata:
name: demo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
namespace: demo
spec:
replicas: 2
selector:
matchLabels:
app: httpbin
template:
metadata:
labels:
app: httpbin
spec:
containers:
- name: httpbin
image: kennethreitz/httpbin
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
namespace: demo
spec:
selector:
app: httpbin
ports:
- port: 80
targetPort: 80
应用配置:
kubectl apply -f demo-app.yaml
关键: HTTPRoute 通过 parentRefs 引用 Gateway,实现 IP 复用
# httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin-route
namespace: demo
spec:
parentRefs:
- name: my-gateway
namespace: default
hostnames:
- 'httpbin.example.com'
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: httpbin
port: 80
应用配置:
kubectl apply -f httproute.yaml
可选
# 第二个应用的路由 - 复用同一个 Gateway IP
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app2-route
namespace: demo
spec:
parentRefs:
- name: my-gateway # 引用同一个 Gateway
namespace: default
hostnames:
- 'app2.example.com' # 不同的域名
rules:
- backendRefs:
- name: app2-service
port: 8080
说明: 多个 HTTPRoute 可以引用同一个 Gateway,它们会共享同一个 LoadBalancer IP,通过域名进行区分。
# 获取 Gateway 地址
GATEWAY_IP=$(kubectl get gateway my-gateway -n default -o jsonpath='{.status.addresses[0].value}')
# 测试访问
curl -H "Host: httpbin.example.com" http://$GATEWAY_IP/get
# 或者配置 /etc/hosts 后直接访问
# echo "$GATEWAY_IP httpbin.example.com" | sudo tee -a /etc/hosts
# curl http://httpbin.example.com/get
以上示例展示了 Gateway API 的基本使用。对于更多高级功能,请参考官方文档:
# 检查 LoadBalancer 服务状态
kubectl get svc -A | grep envoy
# 如果使用云环境,检查云厂商配额
# 如果是本地环境,需要安装 MetalLB 或使用 NodePort
# 检查 HTTPRoute 状态
kubectl describe httproute <route-name> -n <namespace>
# 检查 parentRef 是否正确指向 Gateway
# 检查命名空间是否需要 ReferenceGrant
# 查看 Envoy Gateway 控制器日志
kubectl logs -n envoy-gateway-system -l control-plane=envoy-gateway --tail=100
# 获取 Envoy 代理 Pod
ENVOY_POD=$(kubectl get pod -l gateway.envoyproxy.io/owning-gateway-name=my-gateway -o jsonpath='{.items[0].metadata.name}')
# 查看配置
kubectl exec $ENVOY_POD -- curl -s localhost:19000/config_dump
| Ingress-nginx | Gateway API | 说明 |
|---|---|---|
| ingress-nginx-controller | Envoy Gateway | 控制平面 |
| Service (LoadBalancer) | Gateway 资源 | 入口点配置 |
| Ingress | HTTPRoute | 路由规则 |
| IngressClass | GatewayClass | 控制器类型 |
更多迁移指南请参考: 从 Ingress 迁移到 Gateway API
详细的生产环境最佳实践请参考: Envoy Gateway 生产部署指南
Kubernetes Gateway API 是 Kubernetes 入口流量管理的未来方向,相比传统的 Ingress API 提供了更丰富的功能和更好的扩展性。Envoy Gateway 作为 Gateway API 的官方参考实现之一,提供了生产级别的性能和稳定性。
随着 NGINX Ingress Controller 维护力度的减弱,现在是迁移到 Gateway API 的好时机。通过本文的指导,你应该能够:
评论