内容简介:Envoy是与HAProxy和ngin一样,都是同一领域中的新型网络代理/网络服务器。关于任何软件,你可能会有几种问题:
Envoy是与HAProxy和ngin一样,都是同一领域中的新型网络代理/网络服务器。
关于任何软件,你可能会有几种问题:
- 怎么用?
- 为什么有用?
- 它在内部如何工作?
什么是Envoy
它是一个网络代理。你编译以后把它放在你的服务器上,告诉它使用哪个配置文件,然后就可以了!
下面可能是使用Envoy最简单的例子。配置文件见 这里 。此案例在端口7777上启动一个Web服务器,该服务器其实代理另外一个端口为8000的HTTP服务器。
如果您有Docker,可以立即尝试 - 只需下载配置,启动Envoy docker镜像,然后离开!
python -mSimpleHTTPServer & # Start a HTTP server on port 8000 wget https://gist.githubusercontent.com/jvns/340e4d20c83b16576c02efc08487ed54/raw/1ddc3038ed11c31ddc70be038fd23dddfa13f5d3/envoy_config.json docker run --rm --net host -v=$PWD:/config envoyproxy/envoy /usr/local/bin/envoy -c /config/envoy_config.json
以上命令将启动Envoy HTTP服务器,然后你就可以向Envoy发出请求!
curl localhost:7777
它会代理你的请求转发到localhost:8000。
Envoy基本概念:集群,监听器,路由和过滤器
我们刚刚运行的这个小小的 envoy_config.json 包含了所有基本的Envoy概念!
首先,有一个监听器。这告诉Envoy绑定到一个端口,在本例中为7777:
<font>"listeners"</font><font>: [{ </font><font>"address"</font><font>: { </font><font>"socket_address"</font><font>: { </font><font>"address"</font><font>: </font><font>"127.0.0.1"</font><font>, </font><font>"port_value"</font><font>: 7777 } </font>
接下来,监听器有一个过滤器。过滤器告诉监听器如何处理它收到的请求,并为Envoy提供一系列过滤器。如果您需要做一些复杂的事情,那么要对每个请求使用几个过滤器。
有几种不同类型的过滤器( 请参阅TCP过滤器列表 ),但最重要的过滤器可能是envoy.http_connection_manager过滤器,它用于代理HTTP请求。HTTP连接管理器还有一个适用 的HTTP过滤器列表 ( 请参阅HTTP过滤器列表 )。其中最重要的是将envoy.router的请求路由到后端的过滤器。
在我们的示例中,有一个TCP过滤器(envoy.http_connection_manager)和1个HTTP过滤器(envoy.router):
<font>"filters"</font><font>: [ { </font><font>"name"</font><font>: </font><font>"envoy.http_connection_manager"</font><font>, </font><font>"config"</font><font>: { </font><font>"stat_prefix"</font><font>: </font><font>"ingress_http"</font><font>, </font><font>"http_filters"</font><font>: [{ </font><font>"name"</font><font>: </font><font>"envoy.router"</font><font>, </font><font>"config"</font><font>: {} }], </font>
接下来,我们来谈谈路由。您可能会注意到,到目前为止,我们还没有告诉envoy.router过滤器如何处理它收到的请求,应该在哪里代理这些请求?它应该匹配哪些路径?在我们的例子中,答案将是“代理对localhost:8000的所有请求”。
envoy.router过滤器被配置为路由的阵列。在我们的例子中,只有一条路由规则。
<font>"route_config"</font><font>: { </font><font>"virtual_hosts"</font><font>: [ { </font><font>"name"</font><font>: </font><font>"blah"</font><font>, </font><font>"domains"</font><font>: </font><font>"*"</font><font>, </font><font>"routes"</font><font>: [ { </font><font>"match"</font><font>: { </font><font>"prefix"</font><font>: </font><font>"/"</font><font> }, </font><font>"route"</font><font>: { </font><font>"cluster"</font><font>: </font><font>"banana"</font><font> } </font>
这里定义了要匹配的域列表(这些域与请求主机头匹配)。如果我们更换"domains": "*"到"domains": "my.cool.service",那么我们就需要传递头部信息“Host: my.cool.service”才行。
你会注意到我们案例中被代理的端口 8000未在任何地方定义过。只是有"cluster": "banana"。什么是集群?
好吧,集群是一个服务后端的地址(IP地址/端口)集合。例如,如果您有8台机器运行同一种HTTP服务,那么这个群集中可以有8台host主机集合。每个服务都需要自己的集群。这里示例集群非常简单:它只是一个在localhost上运行的IP /端口。
<font>"clusters"</font><font>:[ { </font><font>"name"</font><font>: </font><font>"banana"</font><font>, </font><font>"type"</font><font>: </font><font>"STRICT_DNS"</font><font>, </font><font>"connect_timeout"</font><font>: </font><font>"1s"</font><font>, </font><font>"hosts"</font><font>: [ { </font><font>"socket_address"</font><font>: { </font><font>"address"</font><font>: </font><font>"127.0.0.1"</font><font>, </font><font>"port_value"</font><font>: 8000 } } ] } ] </font>
手动编写Envoy配置的提示
从头开始编写Envoy配置非常耗时 - 在Envoy存储库( https://github.com/envoyproxy/envoy )中有一些例子,但即使使用Envoy一年后,这个基本配置实际上还是花了我近45分钟,以下是一些提示:
- Envoy有两种不同的API:v1和v2 API。许多较新的功能仅在v2 API中可用,我发现它的文档更容易导航,因为它是从protocol buffers自动生成的。(例如,集群文档是从 cds.proto 生成的)
- Envoy API文档中的一些好的起点: 监听器 , 集群 , 过滤器 , 虚拟主机 。要获得所需的所有信息,您需要点击很多资料(例如,查看如何为需要从“虚拟主机”启动的路由配置群集,然后单击route_config - > virtual_hosts - > routes - > route - > cluster ),但按照它这样做还是奏效的。
- 这个 体系结构概述文档 是有用的,并给出一些Envoy是如何配置的全面解释。
- 可以使用json或yaml配置Envoy。上面我使用了JSON。
使用服务器配置Envoy
尽管我们从磁盘上的配置文件开始,但使用Envoy与HAProxy或nginx完全不同的一点是,Envoy通常不是通过配置文件配置的。相反,可以使用一个或多个动态的配置服务器去更改配置Envoy 。
假设您正在使用Envoy将请求加载到50个后端服务器,这些服务器是您定期轮换出来的EC2实例。因此 http://your-website.com 请求转到Envoy,并被路由到Envoy 群集,该群集需要是这些服务器的50个IP地址和端口的列表。
但是,如果随着时间的推移, 也许你正在推出新的服务器或者它们中一些会被终止。您可以通过定期更改Envoy配置文件并重新启动Envoy来处理此问题。要么!!可以设置“群集发现服务”(或“CDS”),例如,可以查询AWS API并将后端服务器的所有IP返回给Envoy。
我不打算详细介绍如何配置发现服务,但基本上它看起来像这样(来自 这个模板 )。您可以告诉它刷新的频率以及服务器的地址。
dynamic_resources: cds_config: api_config_source: cluster_names: - cds_cluster refresh_delay: 30s ... - name: cds_cluster connect_timeout: 0.25s type: STRICT_DNS lb_policy: ROUND_ROBIN hosts: - socket_address: protocol: TCP address: cds.yourcompany.net port_value: 80
4种Envoy发现服务
有四种资源可以为Envoy设置发现服务 - 路由(“集群应该请求这个HTTP头转到什么地方”),集群(“这个服务有哪些后端?”),监听器(过滤器用于端口)和端点。这些分别称为RDS,CDS,LDS和EDS。 XDS 是整体协议。
从头开始编写发现服务的最简单方法可能是在 Go 中使用 go-control-plane 库。
从头开始编写Envoy配置服务绝对是可能的,但还有一些其他开源项目可以实现Envoy发现服务。以下是我所知道的,但我确信还有更多:
- 有一个叫做 rotor 开源Envoy发现服务看起来很有趣。建造它的公司几周前就 关闭了 。
- Istio (据我所知)基本上是一个Envoy发现服务,它使用来自Kubernetes API的信息(例如集群中的服务)来配置Envoy集群/路由。它有自己的配置语言。
- consul可能会增加对Envoy的支持(请参阅 此博客文章 ),但我并不完全了解那里的状态
什么是服务网格?
我听到的另一个术语是“服务网格”。基本上,“服务网格”是先安装Envoy,并通过Envoy代理所有网络请求。它可以让您更轻松地控制一堆不同的应用程序(可能用不同的编程语言编写)如何相互通信。
如果您的所有网络流量都是通过Envoy代理的,并且可从中央服务器控制所有Envoy配置,那么您可以:
无需在任何地方更改任何应用程序代码。基本上它是一个非常强大/灵活的分散式负载均衡器。
显然,设置一堆发现服务并运行它们和使用它们,这种以复杂的方式配置内部网络基础架构比单独“编写一个nginx配置文件”要复杂得多,对大多数人来说。我不打算告诉你谁应该或不应该使用Envoy,但我的经验是,像Kubernetes一样,它既非常强大又非常复杂。
超时标题和指标衡量
我真正喜欢Envoy的一个原因是你可以传递一个HTTP标头来告诉它如何重试/超时你的请求!这是惊人的,因为每种编程语言正确实现超时/重试逻辑的工作方式不同,人们总是弄错。因此能够传递如何测量指标就非常棒。
超时和重试头都记录 在这里 ,这里是我的最爱:
- x-envoy-max-retries:重试次数
- x-envoy-retry-on:哪些失败重试(例如5xx或connect-failure)
- x-envoy-upstream-rq-timeout-ms:总超时
- x-envoy-upstream-rq-per-try-timeout-ms:每次重试超时
以上所述就是小编给大家介绍的《Envoy基础知识》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。