Envoy 进阶指南(上):从入门到核心功能全掌握

1.Envoy入门

1.1 什么是Envoy

Envoy 是一款 CNCF 旗下的开源项目,由 Lyft 开源。 Envoy 采用 C++ 实现,是面向 Service Mesh 的高性能网络代理服务。它与应用程序并行运行,通过以平台无关的方式提供通用功能来抽象网络。当基础架构中的所有服务流量都通过 Envoy 网格时,通过一致的可观测性,很容易地查看问题区域,调整整体性能。

Envoy 是为面向大型现代服务架构而设计的 L7 代理和通信总线。该项目源于以下理念:对于应用来说网络应该是透明的。当网络和应用出现故障时,应该非常容易定位问题发生的根源。

1.2 Envoy的核心功能

Envoy 于 2017 年 9 月作为孵化项目加入 CNCF。从孵化到毕业,Envoy 都是 CNCF 增长最快的项目之一,深得大型科技公司和开源组织的青睐。在最初发布的近两年半后,Envoy 已经在一些世界上最大和最著名的科技公司投入生产。
Envoy的核心功能如下:
非侵入式架构:Envoy 是一个独立进程,伴随每个应用服务运行。所有的 Envoy 形成一个透明的通信网格,每个应用与 localhost 收发信息,对网络的拓扑结构无感知。这种模式也被称为Sidecar。在服务间通信的场景下,进程外架构对比传统软件库的方式有两大优势:

  • Envoy 适用于任何应用编程语言。Envoy 部署可以在 Java、C++、Go、PHP、Python 等不同语言编写的应用之间形成一个网格。在面向服务架构中,使用多种应用框架和编程语言变得越来越普遍。Envoy 弥合了它们之间的差异。
  • 任何与面向大型服务架构打过交道的人都知道部署和升级软件库非常的苦。Envoy 可以透明地在整个基础架构上快速部署和升级。
    在这里插入图片描述
    L3/L4 filter 架构:Envoy 的核心是一个 L3/L4 网络代理。可插拔的 filter 链机制允许开发 filter 来执行不同 TCP/UDP 代理任务并将其插入到主服务中。现已有多个支持各种任务的 filter,如原始的 TCP 代理、UDP 代理、HTTP 代理、TLS 客户端证书认证、Redis、MongoDB 和 Postgres 等。
    HTTP L7 filter 架构:HTTP 是现代应用架构中的关键组件,Envoy 支持 额外的 HTTP L7 filter 层。可以将 HTTP filter 插入执行不同任务的 HTTP 连接管理子系统中,如 缓存、限速、路由/转发、嗅探 Amazon 的 DynamoDB 等。

顶级 HTTP/2 支持:当以 HTTP 模式运行时,Envoy 同时 支持 HTTP/1.1 和 HTTP/2。Envoy 可以作为 HTTP/1.1 和 HTTP/2 之间的双向透明代理。这意味着任意 HTTP/1.1 和 HTTP/2 客户端和目标服务器的组合都可以桥接在一起。建议配置所有服务之间的 Envoy 使用 HTTP/2 来创建持久连接的网格,以便可以实现请求和响应的多路复用。

HTTP L7 路由:当以 HTTP 模式运行时,Envoy 支持一种 路由 子系统,能够根据路径、权限、内容类型、运行时 参数值等对请求进行路由和重定向。这项功能在将 Envoy 用作前端/边缘代理时非常有用,同时在构建服务网格时也会使用此功能。

gRPC 支持:gRPC 是一个来自 Google 的 RPC 框架,它使用 HTTP/2 作为底层多路复用传输协议。Envoy 支持 被 gRPC 请求和响应的作为路由和负载均衡底层的所有 HTTP/2 功能。这两个系统是非常互补的。
服务发现和动态配置:Envoy 可以选择使用一组分层的 动态配置 API 来实现集中化管理。这些层为 Envoy 提供了以下内容的动态更新:后端集群内的主机、后端集群本身、HTTP 路由、监听套接字和加密材料。对于更简单的部署,可以 通过 DNS 解析 (甚至 完全跳过 )发现后端主机,使用静态配置文件将替代深层配置。

健康检查:推荐 使用将服务发现视为最终一致的过程的方式来建立 Envoy 网格。Envoy 包含了一个 健康检查,可以选择对上游服务集群执行主动健康检查。然后,Envoy 联合使用服务发现和健康检查信息来确定健康的负载均衡目标。Envoy 还通过 异常检查 子系统支持被动健康检查。
高级负载均衡:负载均衡 <arch_overview_load_balancing> 是分布式系统中不同组件之间的一个复杂问题。由于 Envoy 是一个独立代理而不是软件库,因此可以独立实现高级负载均衡以供任何应用程序访问。目前,Envoy 支持 自动重试、熔断、通过外部速率限制服务的 全局限速、请求映射 和 异常检测。未来还计划支持请求竞争。

前端/边缘代理支持:在边缘使用相同的软件大有好处(可观察性、管理、相同的服务发现和负载均衡算法等)。Envoy 包含足够多的功能,可作为大多数现代 Web 应用程序的边缘代理。包括 TLS 终止、HTTP/1.1 和 HTTP/2 支持,以及 HTTP L7 路由。

最佳的可观察性:如上所述,Envoy 的主要目标是让网络透明化。然而,在网络层面和应用层面都有可能出现问题。Envoy 包含对所有子系统的强大 统计 支持。目前支持 statsd <https://github.com/etsy/statsd>_(和兼容程序)作为统计信息接收器,但是插入不同的接收器并不困难。
统计信息也可以通过 :ref:管理 `<operations_admin_interface> 端口查看。通过第三方提供商,Envoy 还支持分布式追踪。

1.3 Envoy术语

在深入研究主架构文档之前本文介绍一些定义。部分定义在行业中略有争议,但是在整个文档和代码库中,Envoy 就是这么使用的,所以,我们就这样定义吧。

主机(Host): 能够进行网络通信的实体(如移动设备、服务器上的应用程序)。在此文档中,主机是逻辑网络应用程序。一块物理硬件上可能运行有多个主机,只要它们是可以独立寻址的。

下游(Downstream): 下游主机连接到 Envoy,发送请求并接收响应。

上游(Upstream): 上游主机接收来自 Envoy 的连接和请求,并返回响应。

监听器(Listener): 监听器是被命名的网络地址(例如,端口、Unix 域套接字等),它可以被下游客户端连接。Envoy 给下游主机暴露一个或多个监听器来连接。
集群(Cluster): 集群是指 Envoy 连接到的逻辑上相同的一组上游主机。Envoy 通过 服务发现 来发现集群的成员。可以选择通过 主动健康检查 来确定集群成员的健康状态。Envoy 通过 负载均衡策略 来决定将请求路由到哪个集群成员。

网格(Mesh): 一组协调提供一致网络拓扑的主机。在本文档中,“Envoy 网格”是一组 Envoy 代理,它们构成了分布式系统的消息传递基础,这个分布式系统由很多不同服务和应用程序平台组成。

运行时配置(Runtime configuration): 外置实时配置系统和 Envoy 一起部署。可以更改配置设置来影响运行,而无需重启 Envoy 或更改主要配置。
侦听器(listener): 可以由下游客户端连接的命名网络位置(例如,端口、unix 域套接字等)。Envoy 公开一个或多个下游主机连接的侦听器。一般是每台主机运行一个 Envoy,使用单进程运行,但是每个进程中,可以启动任意数量的 Listener(监听器)。目前只监听 TCP,每个监听器都独立配置一定数量的(L3/L4)网络过滤器。Listenter 也可以通过 Listener Discovery Service(LDS)动态获取。

Listener filter:Listener 使用 listener filter(监听器过滤器)来操作链接的元数据。它的作用是在不更改 Envoy 的核心功能的情况下,添加更多的集成功能。Listener filter 的 API 相对简单,因为这些过滤器最终是在新接受的套接字上运行。在链中可以互相衔接以支持更复杂的场景,例如调用速率限制。Envoy 已经包含了多个监听器过滤器。

Http Route Table:HTTP 的路由规则,例如请求的域名,Path 符合什么规则,转发给哪个 Cluster。

Health checking:健康检查会与 SDS 服务发现配合使用。但是,即使使用其他服务发现方式,也有相应需要进行主动健康检查的情况。

1.4 设计目标

Envoy 官方的设计目标是这么说的:
Envoy 并不是很慢(我们已经花了相当长的时间来优化关键路径)。基于模块化编码,易于测试,而不是性能最优。我们的观点是,在其他语言或者运行效率低很多的系统中,部署和使用 Envoy 能够带来很好的运行效率。其他语言或者运行效率低很多的系统中,部署和使用 Envoy 能够带来很好的运行效率。
虽然 Envoy 没有把追求极致的性能作为首要目标,但并不表示 Envoy 是没有追求的,只是扩展性优先,性能稍微靠边。Envoy 和 Nginx 一样,也采用了 多线程 + 非阻塞 + 异步IO(Libevent) 的架构,性能仍然很强悍。

1.5 Sidecar模式

大部分应用和服务都需要实现额外的服务治理功能,这些功能可以作为单独的组件或服务而存在。如果将这些功能集成到业务应用中,就会与业务应用运行在同一个进程中,从而可以有效地共享资源。从另一方面来看,这也意味着服务治理组件与业务应用之间的隔离性很弱,一旦其中一个组件出现故障,可能会影响其他组件甚至整个应用程序。除此之外,服务治理组件需要使用与父应用程序相同的技术栈来实现,因此它们之间有密切的相互依赖性。

上述问题的解决方案是,将服务治理功能从应用本身剥离出来作为单独进程,与主应用程序共同放在一台主机(Host)中,但会将它们部署在各自的进程或容器中。这种方式也被称为 Sidecar(边车)模式。
下图展示了服务治理功能与主应用程序的部署关系图。
在这里插入图片描述
该模式允许我们向应用无侵入添加多种功能,避免了为满足第三方组件需求而向应用添加额外的配置代码。
在软件架构中,Sidecar 附加到主应用,或者叫父应用上,以扩展/增强功能特性,同时 Sidecar 与主应用是松耦合的。这就像是如下图所示的边三轮摩托车那样,将边车(Sidecar)安装在一辆摩托车上,就变成了边三轮摩托车。每辆边三轮摩托车都有自己的边车。类似同样的方式,Sidecar 服务共享其父应用程序的主机。对于应用程序的每个实例,边车的实例被部署并与其一起托管。

使用 Sidecar 模式的好处有很多:

  • 通过将服务治理相关功能抽象到不同的层来降低微服务的代码复杂性
  • 在运行时环境和编程语言方面,Sidecar 独立于其主要应用程序,不需要为每个微服务编写服务治理功能的代码,减少了微服务架构中的代码重复。
  • Sidecar 可以访问与主应用程序相同的资源。例如,Sidecar 可以监视 Sidecar 本身和主应用程序使用的系统资源。
  • 由于它靠近主应用程序,因此在它们之间进行通信时没有明显的延迟。
    降低了应用与底层平台的耦合度。

Envoy 是为云原生应用设计的代理,可以在服务旁运行,以平台无关的方式提供必要的特性,所有到服务的流量都通过 Envoy 代理,这里 Envoy 扮演的就是 Sidecar 的角色。
在这里插入图片描述
总的来说,在从一体化架构向微服务架构的转型让我们可以相对独立、大规模地部署应用,而在容器环境中,Sidecar 模式可以很好地兼容,帮助我们降低微服务架构复杂性,更好地实现服务发现、流量管理、负载均衡、路由。

2.初识Envoy

2.1 安装Envoy

Envoy 本身是很难编译的,需要使用到项目构建工具 Bazel,为了解决这个问题,Tetrate 的工程师(包括 Envoy 的核心贡献者和维护者)发起了 GetEnvoy 项目,目标是利用一套经过验证的构建工具来构建 Envoy,并通过常用的软件包管理器来分发,包括:apt、yum 和 Homebrew。安装方式如下:

MacOS:
     $ brew update

$ brew install envoy
==> Installing envoy

==> Downloading https://ghcr.io/v2/homebrew/core/envoy/manifests/1.18.3-1
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/envoy/blobs/sha256:d03fb86b48336c8d3c0f3711cfc3df3557f9fb33c966ceb1caecae1653935e90
######################################################################## 100.0%
==> Pouring envoy--1.18.3.big_sur.bottle.1.tar.gz
🍺  /usr/local/Cellar/envoy/1.18.3: 300 files, 119.5MB

CentOS:
# 安装 yum-config-manager 
$ yum install -y yum-utils
# 添加 Envoy 仓库
$ yum-config-manager --add-repo https://getenvoy.io/linux/centos/tetrate-getenvoy.repo
# 安装 Envoy
$ yum install -y getenvoy-envoy

Ubuntu:
  # 更新 apt 索引 
$ apt update
# 安装 HTTPS 依赖
$ apt install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg2 \
software-properties-common
# 添加 Tetrate GPG 密钥
$ curl -sL 'https://getenvoy.io/gpg' | sudo apt-key add -
# 通过指纹验证密钥
$ apt-key fingerprint 6FF974DB | grep "5270 CEAC"
pub   4096R/6FF974DB 2019-03-01
Key fingerprint = 5270 CEAC 57F6 3EBD 9EA9  005D 0253 D0B2 6FF9 74DB
uid                  GetEnvoy <getenvoy@tetrate.io>
sub   4096R/7767A960 2019-03-01
# 添加仓库
$ add-apt-repository \
"deb [arch=amd64] https://dl.bintray.com/tetrate/getenvoy-deb \
$(lsb_release -cs) \
stable"
# 安装 Envoy
$ apt update && apt install -y getenvoy-envoy


Docker:
Envoy 社区不提供已经编译好的二进制的文件,只提供了 Docker 镜像(当然现在有 GetEnvoy 项目了)。社区提供的镜像位于 envoyproxy 中,常用的有:
envoyproxy/envoy-alpine : 基于 alpine 的发行镜像
envoyproxy/envoy-alpine-dev : 基于 alpine 的 Nightly 版本发行镜像
envoyproxy/envoy : 基于 Ubuntu 的发行镜像
envoyproxy/envoy-dev : 基于 Ubuntu 的 Nightly 版本发行镜像
获取镜像:
$ docker pull envoyproxy/envoy:v1.18.3



启动 Envoy 容器时,可以用本地的envoy.yaml覆盖镜像中的 envoy.yaml:
→ docker run -d --network=host -v `pwd`/envoy.yaml:/etc/envoy/envoy.yaml envoyproxy/envoy:v1.18.3

2.2 简单示例了解Envoy

本文的示例使用 Envoy 作为边缘代理,根据不同的路由配置将请求转发到百度和 Bing。指定请求头 host: baidu.com 时会将请求转发到 www.baidu.com;指定请求头 host: bing.com 时会将请求转发到 cn.bing.com。
Envoy 使用 YAMl 配置来控制代理的行为,为了快速开始,使用以下静态配置文件进行实践演示:

static_resources:
  listeners:
  - address:
      # Tells Envoy to listen on 0.0.0.0:15001
      socket_address:
        address: 0.0.0.0
        port_value: 15001
    filter_chains:
    # Any requests received on this address are sent through this chain of filters
    - filters:
      # If the request is HTTP it will pass through this HTTP filter
      - name: envoy.filters.network.http_connection_manager 
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          codec_type: auto
          stat_prefix: http
        access_log:
          name: envoy.access_loggers.file
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
            path: /dev/stdout
          route_config:
            name: search_route
            virtual_hosts:
            - name: backend
              domains:
              - "*"
              routes:
              # Match on host (:authority in HTTP2) headers
              - match:
                  prefix: "/"
                  headers:
                    - name: ":authority"
                      exact_match: "baidu.com"
                route:
                  # Send request to an endpoint in the Google cluster
                  cluster: baidu
                  host_rewrite_literal: www.baidu.com
              - match:
                  prefix: "/"
                  headers:
                    - name: ":authority"
                      exact_match: "bing.com"
                route:
                  # Send request to an endpoint in the Bing cluster
                  cluster: bing
                  host_rewrite_literal: cn.bing.com
          http_filters:
          - name: envoy.filters.http.router
  clusters:
  - name: baidu
    connect_timeout: 1s
    # Instruct Envoy to continouously resolve DNS of www.google.com asynchronously
    type: logical_dns 
    dns_lookup_family: V4_ONLY
    lb_policy: round_robin
    load_assignment:
      cluster_name: baidu
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: www.baidu.com
                port_value: 80
  - name: bing
    connect_timeout: 1s
    # Instruct Envoy to continouously resolve DNS of www.bing.com asynchronously
    type: logical_dns
    dns_lookup_family: V4_ONLY
    lb_policy: round_robin
    load_assignment:
      cluster_name: bing
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: cn.bing.com
                port_value: 80
admin:
  access_log_path: "/dev/stdout"
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 15000

第一次使用 Envoy,可能会觉得它的配置太复杂了,让人眼花缭乱。其实不然,我们不妨先脑补一下网络代理程序的流程,比如作为一个代理,首先要能获取请求流量,通常是采用监听端口的方式实现;其次拿到请求数据后需要对其做微处理,例如附加 Header 或校验某个 Header 字段的内容等,这里针对来源数据的层次不同,可以分为 L3/L4/L7,然后将请求转发出去;转发这里又可以衍生出如果后端是一个集群,需要从中挑选一台机器,如何挑选又涉及到负载均衡等。
脑补完大致流程后,再来看 Envoy 是如何组织配置信息的,先简单解释一下其中的关键字段,详细的解释可以看后面的章节。

  • listener : Envoy 的监听地址,就是真正干活的。Envoy 会暴露一个或多个 Listener 来监听客户端的请求。
  • filter : 过滤器。在 Envoy 中指的是一些“可插拔”和可组合的逻辑处理层,是 Envoy 核心逻辑处理单元。
  • route_config : 路由规则配置。即将请求路由到后端的哪个集群。
  • cluster : 服务提供方集群。Envoy 通过服务发现定位集群成员并获取服务,具体路由到哪个集群成员由负载均衡策略决定。
    结合关键字段和上面的脑补流程,可以看出 Envoy 的大致处理流程如下:
    在这里插入图片描述

Envoy 内部对请求的处理流程其实跟我们上面脑补的流程大致相同,即对请求的处理流程基本是不变的,而对于变化的部分,即对请求数据的微处理,全部抽象为 Filter,例如对请求的读写是 ReadFilter、WriteFilter,对 HTTP 请求数据的编解码是 StreamEncoderFilter、StreamDecoderFilter,对 TCP 的处理是 TcpProxyFilter,其继承自 ReadFilter,对 HTTP 的处理是 ConnectionManager,其也是继承自 ReadFilter 等等,各个 Filter 最终会组织成一个 FilterChain,在收到请求后首先走 FilterChain,其次路由到指定集群并做负载均衡获取一个目标地址,然后转发出去。

启动 Envoy
配置完成后,就可以通过静态配置文件直接启动 Envoy 了:

1	$ envoy -c ./basic-front-proxy.yaml

打开一个新的 shell,使用 curl 访问 Envoy,并添加 Header 字段 host: baidu.com:

$ curl -s -o /dev/null -vvv -H 'Host: baidu.com' xx.xx.xx.xx:15001

* Rebuilt URL to: xx.xx.xx.xx:15001/
*   Trying xx.xx.xx.xx...
* TCP_NODELAY set
* Connected to xx.xx.xx.xx (xx.xx.xx.xx) port 15001 (#0)
> GET / HTTP/1.1
> Host: baidu.com
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< accept-ranges: bytes
< cache-control: private, no-cache, no-store, proxy-revalidate, no-transform
< content-length: 2381
< content-type: text/html
< date: Sun, 03 May 2020 09:46:59 GMT
< etag: "588604c8-94d"
< last-modified: Mon, 23 Jan 2017 13:27:36 GMT
< pragma: no-cache
< server: envoy
< set-cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
< x-envoy-upstream-service-time: 19
<
{ [1048 bytes data]
* Connection #0 to host xx.xx.xx.xx left intact

可以看到请求被转发到了 baidu.com,并且在转发的时候将 host 修改成了 www.baidu.com。访问时去掉参数 -s -o /dev/null 可以看到完整的响应内容:

$ curl -vvv -H 'Host: baidu.com' xx.xx.xx.xx:15001

* Rebuilt URL to: xx.xx.xx.xx:15001/
*   Trying xx.xx.xx.xx...
* TCP_NODELAY set
* Connected to xx.xx.xx.xx (xx.xx.xx.xx) port 15001 (#0)
> GET / HTTP/1.1
> Host: baidu.com
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< accept-ranges: bytes
< cache-control: private, no-cache, no-store, proxy-revalidate, no-transform
< content-length: 2381
< content-type: text/html
< date: Sun, 03 May 2020 09:50:07 GMT
< etag: "588604c8-94d"
< last-modified: Mon, 23 Jan 2017 13:27:36 GMT
< pragma: no-cache
< server: envoy
< set-cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
< x-envoy-upstream-service-time: 37
<
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
* Connection #0 to host xx.xx.xx.xx left intact

同理可以访问 bing.com:

curl -s -o /dev/null -vvv -H 'Host: bing.com' localhost:15001

...
* Connected to xx.xx.xx.xx (xx.xx.xx.xx) port 15001 (#0)
> GET / HTTP/1.1
> Host: bing.com
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< cache-control: private, max-age=0
< content-length: 112683
< content-type: text/html; charset=utf-8
< p3p: CP="NON UNI COM NAV STA LOC CURa DEVa PSAa PSDa OUR IND"
< set-cookie: SRCHD=AF=NOFORM; domain=.bing.com; expires=Tue, 03-May-2022 13:08:55 GMT; path=/
< set-cookie: SRCHUID=V=2&GUID=D8E47780338144C587A3F6EC1D831373&dmnchg=1; domain=.bing.com; expires=Tue, 03-May-2022 13:08:55 GMT; path=/
< set-cookie: SRCHUSR=DOB=20200503; domain=.bing.com; expires=Tue, 03-May-2022 13:08:55 GMT; path=/
< set-cookie: _SS=SID=3E6E525A1E406DCF27B15CE51F6E6C28; domain=.bing.com; path=/
< x-msedge-ref: Ref A: BB80A686B64D4DCAB5713DB6ADF294C8 Ref B: BJ1EDGE0217 Ref C: 2020-05-03T13:08:55Z
< set-cookie: _EDGE_S=F=1&SID=3E6E525A1E406DCF27B15CE51F6E6C28; path=/; httponly; domain=bing.com
< set-cookie: _EDGE_V=1; path=/; httponly; expires=Fri, 28-May-2021 13:08:55 GMT; domain=bing.com
< set-cookie: MUID=20CC7B7828C26CF93BE175C729EC6D8A; samesite=none; path=/; secure; expires=Fri, 28-May-2021 13:08:55 GMT; domain=bing.com
< set-cookie: MUIDB=20CC7B7828C26CF93BE175C729EC6D8A; path=/; httponly; expires=Fri, 28-May-2021 13:08:55 GMT
< date: Sun, 03 May 2020 13:08:53 GMT
< x-envoy-upstream-service-time: 151
< server: envoy
<
{ [6069 bytes data]

查看 Envoy 的日志:

[2020-05-03T13:10:39.968Z] "GET / HTTP/1.1" 200 - 0 2381 50 49 "-" "curl/7.54.0" "201f8fe4-3446-4063-b6f2-b6289100529a" "www.baidu.com" "198.18.5.232:80"
[2020-05-03T13:10:47.501Z] "GET / HTTP/1.1" 200 - 0 112348 263 160 "-" "curl/7.54.0" "d291ec6b-3669-426a-8f79-9be696d8c97a" "cn.bing.com" "198.18.10.118:80"

可以看到这两个不同的请求都得到了正确响应。

2.3 管理视图

Envoy 提供了一个管理视图,可以让我们去查看配置、统计信息、日志以及其他 Envoy 内部的一些数据。
我们可以通过添加其他的资源定义来配置 admin,其中也可以定义管理视图的端口,不过需要注意该端口不要和其他监听器配置冲突。

[2020-05-03T13:10:39.968Z] "GET / HTTP/1.1" 200 - 0 2381 50 49 "-" "curl/7.54.0" admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address: { address: 0.0.0.0, port_value: 9901 }

当然我们也可以通过 Docker 容器将管理端口暴露给外部用户。上面的配置就会将管理页面暴露给外部用户,当然我们这里仅仅用于演示是可以的,如果你是用于线上环境还需要做好一些安全保护措施,可以查看 Envoy 的相关文档 了解更多安全配置。
要将管理页面也暴露给外部用户,我们使用如下命令运行另外一个容器:

$ docker run --name=envoy-with-admin -d \
    -p 9901:9901 \
    -p 10000:10000 \
    -v $(pwd)/manifests/envoy.yaml:/etc/envoy/envoy.yaml \
envoyproxy/envoy:latest

运行成功后,现在我们可以在浏览器里面输入 localhost:9901 来访问 Envoy 的管理页面:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值