本文将介绍 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 协议的路由。通过 TCPRouteUDPRoute 对象,你可以根据端口号等条件来路由相应的流量,确保在不同协议下流量的正确分发。

实验功能
TCPRouteUDPRoute 资源是 Kubernetes Gateway API 中的实验阶段。

使用步骤:

  1. 定义 Gateway 和 GatewayClass
    • 首先,创建一个 GatewayClass 和一个 Gateway 资源。
    • Gateway 中配置 TCP 监听器,指定监听的端口和允许的路由类型(如 TCPRoute)。
  2. 配置 TCPRoute/UDPRoute
    • 创建 TCPRoute / UDPRoute资源,为每个 TCP/UDP 监听器定义路由规则。
    • TCPRoute / UDPRoute 中,通过 parentRefs 将其与 Gateway 的特定监听器关联。
    • rules 中指定要将流量路由到的后端服务和端口。
  3. 部署后端服务
    • 部署相应的后端服务(如 Kubernetes 的 ServiceDeployment),这些服务将接收来自 Gateway 的 TCP/UDP 流量。

详细步骤请参考 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 APIServiceImport 对象和 Gateway API 的 HTTPRoute 来实现。这种设置通常用于跨集群的服务调用,适合在多区域或多数据中心的部署环境中使用。

使用步骤:

  1. 设置多集群环境

    • 使用 Submariner 项目来配置多集群环境,使服务能够跨集群暴露和访问。
    • 在多个集群中安装 Submariner 并配置 ServiceImport 对象以导出服务。
  2. 安装 Envoy Gateway

    • 在主集群(Cluster1)中安装 Envoy Gateway 并配置 Gateway API 的 CRD。
  3. 部署应用程序并导出服务

    • 在另一个集群(Cluster2)中部署后端应用程序,并使用 subctl 命令导出服务,使其在多集群环境中可用。
  4. 配置 Gateway API 对象

    • 在主集群中创建 GatewayClassGatewayHTTPRoute 对象。
    • 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: /

核心要点:

  • ServiceImportServiceImport 对象由 Multicluster Service API 定义,用于跨集群访问服务。在 HTTPRoute 中,可以通过 backendRefs 引用 ServiceImport 来实现跨集群路由。
  • ReferenceGrant:为了使 HTTPRoute 能够跨命名空间引用 ServiceImport,需要配置 ReferenceGrant 对象。这允许来自一个命名空间的资源(如 HTTPRoute)访问另一个命名空间中的资源(如 ServiceImport)。

HTTP 流量分割

Envoy Gateway 支持通过 HTTPRoute 资源进行流量分割,将流量根据比例分配到多个后端服务。这可以用于蓝绿部署、A/B 测试等场景。

配置步骤:

  1. 单一后端配置

    • HTTPRoute 仅配置一个 backendRef 时,所有流量都会被路由到该后端服务。
  2. 多后端配置

    • 如果配置了多个 backendRef,默认情况下流量将平均分配到这些后端。你也可以通过设置 weight 字段来调整流量分配比例。
  3. 流量权重配置

    • 使用 weight 字段控制流量分配比例。例如,将 80% 的流量分配给一个后端,20% 的流量分配给另一个后端。
  4. 处理无效的后端引用

    • 如果配置了无效的 backendRef(例如,引用了不存在的服务或端口),Envoy Gateway 会对本应路由到该后端的请求返回 500 错误。

配置示例:

定义了一个 HTTPRoute 资源,将所有以 / 开头的请求路由到两个后端服务(backend-1backend-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 资源来实现这一目的。

配置步骤:

  1. 定义外部服务
    • 在 Kubernetes 内部创建一个服务(Service),并使用 EndpointSlice 将该服务与外部服务(例如 httpbin.org)的 FQDN 进行关联。这样,Envoy Gateway 可以将流量路由到这个外部服务。
  2. 更新 Gateway 配置
    • 在 Gateway 中添加一个 TLS 监听器,设置为透传模式。这允许 Gateway 将接收到的加密流量直接传递给外部服务,而不进行解密处理。
  3. 创建路由规则
    • 使用 TLSRoute 配置,将 Gateway 接收到的流量根据定义的规则路由到外部服务。通过这种方式,可以将外部服务视为 Kubernetes 内部的一部分进行流量管理。

详细步骤请参考 Envoy Gateway 文档

最后更新于 2024/11/07