Envoy 基础教程


Envoy 的基础概念

Envoy 的请求流如下图所示:

请求首先到达监听器,然后通过 filter_chains (网络过滤器链) 到达路由构件。路由构件根据特定的规则将请求路由到 cluster 中,cluster 中可以定义多个 endpoint,endpoint 代表了上游的服务。

HCM (HTTP Connection Manager) 过滤器是一种特殊的,内置的网络过滤器,它会将字节信息解析成 HTTP 请求,在它上面可以对 HTTP 请求/响应做一些操作。

HCM 还支持配置多个 http 过滤器,在 http 过滤器中我们可以对 http 请求/响应 进行多种操作。

HTTP 过滤器链中的最后一个过滤器必须是路由器过滤器(envoy.filters.HTTP.router)。路由器过滤器负责执行路由任务。这最终把我们带到了第二个构件 —— 路由。

下面以一个简单的例子进行说明

  1. 我们需要定义 cluster,这里定义了两个 cluster,它们分别包含了 127.0.0.1:8000 端点 和 127.0.0.1:8001 端点。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  clusters:
  - name: app_service
    connect_timeout: 5s
    load_assignment:
      cluster_name: app_service
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 127.0.0.1
                port_value: 8000
  - name: api_service
    connect_timeout: 5s
    load_assignment:
      cluster_name: api_service
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 127.0.0.1
                port_value: 8001
  1. 定义网络过滤器链,这里我们只使用了 HCM 这一个网络过滤器
1
2
3
4
5
6
filter_chains:
- filters:
    - name: envoy.filters.network.http_connection_manager
    typed_config:
        "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
        stat_prefix: ingress_http
  1. 在 HCM 中定义路由规则

我们这个例子比较简单,只是根据 http url 进行路由,所以只用了一个 http filter,路由器过滤器(envoy.filters.http.router),在 route_confing 配置段中,可以设置路由器过滤器的路由规则,我们定义了两条规则

  1. 对于任意域名,匹配 /api 的请求发送到 api_service 中(127.0.0.1:8001)
  2. 对于任意域名,匹配 / 的请求发送到 app_service 中(127.0.0.1:8001)

envoy 的 HCM 的路由规则和 nginx 很像,也是先根据 Hostauthority header 匹配 virutal_host,然后再去根据 url 匹配。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
        http_filters:
        - name: envoy.filters.http.router
        typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
        route_config:
        name: hello_world_service
        virtual_hosts:
        - name: hello_world_service
            domains:
            - "*"
            routes:
            # 注意: routes 中定义的规则是有顺序的,/api 要放到 / 之前,要不然所有的请求都会匹配到 app_service 上
            - match:
                prefix: "/api"
            route:
                cluster: api_service
            - match:
                prefix: "/"
            # 注意: route 和 match 是平级的
            route:
                cluster: app_service

以上完整配置文件见 Github

HTTP/2

Envoy 代理被设计成一个 HTTP/2 复用代理,在 HTTP/2 中,流代表已建立连接中的字节的双向流动,每个流可以携带一个或多个消息。消息是一个完整的帧(frame),映射到一个 HTTP 请求或响应。

帧是 HTTP/2 的最小通信单位,每个帧包括一个帧头,它至少可以识别帧所属的流,也可以携带 HTTP Header,消息有效载荷等信息。

无论流来自哪个链接,Envoy 都使用一个叫做 编解码 API(codec API) 的功能,将不同的协议翻译成流、请求,响应等协议无关模型。协议无关模型意味着 Envoy 的大部分代码不需要理解每个协议的具体内容。