envoy 可以针对 http 协议的 tcp 请求进行协议解析,以 http 的元数据(metadata)用作转发配置的匹配数据。

envoy 的 HttpConnectionManager 过滤器将 tcp 的数据 (payload) 解析为 headers 和 body。为了更简化的处理数据会将 http/https 的协议标识处理成 header[:schema]、请求的 host 处理成 header[:host] 以及请求路径处理成 header[:path] 等内部元数据(metadata)。

配置 envoy 转发 http 请求到 envoy 官网

envoy 的配置如下

static_resources:
  listeners:
    - name: listener_0
      address:
        socket_address:
          protocol: TCP
          address: 0.0.0.0
          port_value: 7080
      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 # http 协议数据解析
                access_log: # 访问日志配置到标准输出
                  - name: envoy.access_loggers.stdout
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
                route_config: # 路由配置
                  name: local_route
                  virtual_hosts:
                    - name: local_service # 配置一个虚拟主机,匹配特定的域名
                      domains: ["*"]
                      routes:
                        - match: # 路由配置,将匹配 http 元数据的请求转发到指定的 cluster
                            prefix: "/"
                          route:
                            host_rewrite_literal: www.envoyproxy.io
                            cluster: service_envoyproxy_io
                http_filters:
                  - name: envoy.filters.http.router
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
  clusters:
    - name: service_envoyproxy_io
      type: LOGICAL_DNS
      # Comment out the following line to test on v6 networks
      dns_lookup_family: V4_ONLY
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: service_envoyproxy_io
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: www.envoyproxy.io # cluster 的 endpoint 的 address 也可以使用域名,但是需要指定对应 cluster.type
                      port_value: 80

使用 curl 命令请求代理地址 localhost:7080,可以看到响应内容就是 envoy 官网返回的 http 跳转到 https 的响应。

 curl localhost:7080 -v
* Host localhost:7080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:7080...
* connect to ::1 port 7080 from ::1 port 64792 failed: Connection refused
*   Trying 127.0.0.1:7080...
* Connected to localhost (127.0.0.1) port 7080
> GET / HTTP/1.1
> Host: localhost:7080
> User-Agent: curl/8.6.0
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< content-type: text/plain; charset=utf-8
< date: Fri, 02 Aug 2024 03:08:44 GMT
< location: https://www.envoyproxy.io/
< server: envoy
< x-nf-request-id: 01J48GZ9TEZ46MQCYN80X4EPD7
< content-length: 41
< x-envoy-upstream-service-time: 44
< 
* Connection #0 to host localhost left intact
Redirecting to https://www.envoyproxy.io/%    

小结

这个简单的示例并没有其他的功能,仅仅是普通的 http 反向代理,将对应的 http 请求接受转发到其他站点。