本文将介绍 Envoy Gateway 中的各种流量路由机制,包括 HTTP 和 gRPC 路由、请求镜像、多协议支持、跨集群路由、流量分割以及 Kubernetes 外部路由。通过这些功能,用户可以灵活配置流量的分发方式,满足不同应用场景的需求。
HTTP 路由
HTTP 路由是基于请求的路径、方法、头信息等条件来路由 HTTP 请求的核心功能。在 EG 中,你可以通过配置 HTTPRoute
对象来定义多种匹配规则,将请求路由到相应的后端服务。
配置示例:
定义一个 HTTPRoute
资源,用于将所有对以 /foo
开头的 URL 请求路由到名为 foo-service
的服务的 80 端口。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: example-route
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- path:
type: Prefix
value: "/foo"
backendRefs:
- name: foo-service
port: 80
GRPC 路由
GRPC 路由功能允许你根据 GRPC 服务的方法和消息类型来路由请求。在 Envoy Gateway 中,这通过 GRPCRoute
对象来实现,提供了细粒度的流量控制。
配置示例:
定义一个 GRPCRoute
资源,用于将匹配到的 gRPC 请求(服务为 example-service
,方法为 ExampleMethod
)路由到名为 grpc-service
的服务的 50051 端口。
apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
name: example-grpc-route
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- method:
service: "example-service"
method: "ExampleMethod"
backendRefs:
- name: grpc-service
port: 50051
HTTPRoute 请求镜像
请求镜像功能允许你将请求的副本发送到不同的后端服务,而不影响原始请求的处理。这对于在生产环境中测试新服务,或实现数据流复制非常有用。请求镜像是在 HTTPRoute
上使用 Gateway API 的 HTTPRequestMirrorFilter 完成的。
配置示例:
定义一个 HTTPRoute
资源,用于将所有匹配到的请求(路径以 /
开头)镜像到名为 backend-2
的服务,同时将原始请求转发到名为 backend
的服务。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-mirror
spec:
parentRefs:
- name: example-gateway
hostnames:
- backends.example
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: RequestMirror
requestMirror:
backendRef:
kind: Service
name: backend-2
port: 3000
backendRefs:
- group: ""
kind: Service
name: backend
port: 3000
多协议支持的路由
Envoy Gateway 不仅支持 HTTP 和 GRPC,还支持 TCP 和 UDP 协议的路由。通过 TCPRoute
和 UDPRoute
对象,你可以根据端口号等条件来路由相应的流量,确保在不同协议下流量的正确分发。
TCPRoute
和 UDPRoute
资源是 Kubernetes Gateway API 中的实验阶段。
使用步骤:
- 定义 Gateway 和 GatewayClass:
- 首先,创建一个
GatewayClass
和一个Gateway
资源。 - 在
Gateway
中配置 TCP 监听器,指定监听的端口和允许的路由类型(如TCPRoute
)。
- 首先,创建一个
- 配置
TCPRoute
/UDPRoute
:- 创建
TCPRoute
/UDPRoute
资源,为每个 TCP/UDP 监听器定义路由规则。 - 在
TCPRoute
/UDPRoute
中,通过parentRefs
将其与Gateway
的特定监听器关联。 - 在
rules
中指定要将流量路由到的后端服务和端口。
- 创建
- 部署后端服务:
- 部署相应的后端服务(如 Kubernetes 的
Service
和Deployment
),这些服务将接收来自 Gateway 的 TCP/UDP 流量。
- 部署相应的后端服务(如 Kubernetes 的
详细步骤请参考 Envoy Gateway 文档。
TCP 路由配置示例:
定义一个 TCPRoute
资源,用于将所有发送到 3306 端口的 TCP 请求路由到名为 db-service
的服务的 3306 端口。
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: example-tcp-route
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- port: 3306
backendRefs:
- name: db-service
port: 3306
UDP 路由配置示例:
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: UDPRoute
metadata:
name: example-udp-route
spec:
parentRefs:
- name: example-gateway
rules:
- matches:
- port: 53
backendRefs:
- name: dns-service
port: 53
多集群服务路由
Envoy Gateway 支持多集群服务路由,这允许您将来自一个 Kubernetes 集群的请求路由到另一个集群中的服务。多集群服务路由通过结合使用 Multicluster Service API 的 ServiceImport
对象和 Gateway API 的 HTTPRoute
来实现。这种设置通常用于跨集群的服务调用,适合在多区域或多数据中心的部署环境中使用。
使用步骤:
-
设置多集群环境:
- 使用
Submariner
项目来配置多集群环境,使服务能够跨集群暴露和访问。 - 在多个集群中安装
Submariner
并配置ServiceImport
对象以导出服务。
- 使用
-
安装 Envoy Gateway:
- 在主集群(Cluster1)中安装 Envoy Gateway 并配置 Gateway API 的 CRD。
-
部署应用程序并导出服务:
- 在另一个集群(Cluster2)中部署后端应用程序,并使用
subctl
命令导出服务,使其在多集群环境中可用。
- 在另一个集群(Cluster2)中部署后端应用程序,并使用
-
配置 Gateway API 对象:
- 在主集群中创建
GatewayClass
、Gateway
和HTTPRoute
对象。 - 在
HTTPRoute
中,通过backendRefs
引用ServiceImport
对象,将流量从主集群路由到另一个集群中的服务。
- 在主集群中创建
配置示例:
以下是一个简单的多集群路由配置示例,定义了一个 GatewayClass 和一个 Gateway,允许 Envoy 代理在 80 端口上监听 HTTP 请求,并将所有匹配到的以 /
开头的请求转发到名为 backend-default-cluster2
的 ServiceImport 服务(位于 submariner-operator
命名空间的 3000 端口),同时指定了主机名为 www.example.com
:
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: eg
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: eg
namespace: default
spec:
gatewayClassName: eg
listeners:
- name: http
protocol: HTTP
port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: backend
namespace: default
spec:
parentRefs:
- name: eg
hostnames:
- "www.example.com"
rules:
- backendRefs:
- group: multicluster.x-k8s.io
kind: ServiceImport
name: backend-default-cluster2
namespace: submariner-operator
port: 3000
matches:
- path:
type: PathPrefix
value: /
核心要点:
- ServiceImport:
ServiceImport
对象由 Multicluster Service API 定义,用于跨集群访问服务。在HTTPRoute
中,可以通过backendRefs
引用ServiceImport
来实现跨集群路由。 - ReferenceGrant:为了使
HTTPRoute
能够跨命名空间引用ServiceImport
,需要配置ReferenceGrant
对象。这允许来自一个命名空间的资源(如HTTPRoute
)访问另一个命名空间中的资源(如ServiceImport
)。
HTTP 流量分割
Envoy Gateway 支持通过 HTTPRoute
资源进行流量分割,将流量根据比例分配到多个后端服务。这可以用于蓝绿部署、A/B 测试等场景。
配置步骤:
-
单一后端配置:
- 当
HTTPRoute
仅配置一个backendRef
时,所有流量都会被路由到该后端服务。
- 当
-
多后端配置:
- 如果配置了多个
backendRef
,默认情况下流量将平均分配到这些后端。你也可以通过设置weight
字段来调整流量分配比例。
- 如果配置了多个
-
流量权重配置:
- 使用
weight
字段控制流量分配比例。例如,将 80% 的流量分配给一个后端,20% 的流量分配给另一个后端。
- 使用
-
处理无效的后端引用:
- 如果配置了无效的
backendRef
(例如,引用了不存在的服务或端口),Envoy Gateway 会对本应路由到该后端的请求返回500
错误。
- 如果配置了无效的
配置示例:
定义了一个 HTTPRoute
资源,将所有以 /
开头的请求路由到两个后端服务(backend-1
和 backend-2
),并根据指定的权重(8:2)进行流量分配。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-headers
spec:
parentRefs:
- name: eg
hostnames:
- backends.example
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ""
kind: Service
name: backend-1
port: 3000
weight: 8
- group: ""
kind: Service
name: backend-2
port: 9000
weight: 2
Kubernetes 外部路由
Envoy Gateway 支持将流量路由到 Kubernetes 集群外的端点,这一功能在许多需要与外部服务集成的场景中非常有用。你可以通过定义 FQDN(完全限定域名)地址的 EndpointSlice
或使用 Backend
资源来实现这一目的。
配置步骤:
- 定义外部服务:
- 在 Kubernetes 内部创建一个服务(Service),并使用
EndpointSlice
将该服务与外部服务(例如httpbin.org
)的 FQDN 进行关联。这样,Envoy Gateway 可以将流量路由到这个外部服务。
- 在 Kubernetes 内部创建一个服务(Service),并使用
- 更新 Gateway 配置:
- 在 Gateway 中添加一个 TLS 监听器,设置为透传模式。这允许 Gateway 将接收到的加密流量直接传递给外部服务,而不进行解密处理。
- 创建路由规则:
- 使用
TLSRoute
配置,将 Gateway 接收到的流量根据定义的规则路由到外部服务。通过这种方式,可以将外部服务视为 Kubernetes 内部的一部分进行流量管理。
- 使用
详细步骤请参考 Envoy Gateway 文档。