赞
踩
Envoy官网 https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/intro/terminology
以下信息皆参考官网
Envoy采用单进程多线程的模式,监听器在接收到请求后会交给工作线程进行处理,工作线程采用100%非阻塞进行通讯(Epoll)。这里建议工作线程的数量配置为等于机器上的硬件线程的数量。
根据上面的流程图,我们开始对每个模块进行详解。
在讲解之间,我们先了解一下他们的基本意思:
在看该模块之前,请先跳转到下面阅读官网DEMO实例YAML分析,请注意观察"@type" 属性,该属性配置了一个URL,那么这个URL的作用是什么那?这就是接下来我们要讲解的内容。
支持以下 v3 xDS 资源类型:
typeURL的概念 出现在下面,并采用以下形式——例如, 对于资源。在来自 Envoy 的各种请求和管理服务器的响应中,都说明了资源类型 URL。type.googleapis.com/type.googleapis.com/envoy.config.cluster.v3.ClusterCluster
比如 type.googleapis.com/envoy.extensions.filters.listener.http_inspector.v3.HttpInspector 标明了Http检测监听过滤器类型
说白了就是,我们在使用插件的过程中只需要指定插件的名称即可,而在Envoy中我们需要指定当前插件类型在GRPC中的URL地址
:::info
Envoy支持TCP与UDP监听。
:::
:::success
请求到达监听器后首先会经过监听器的过滤器,然后我们可以根据过滤器的结果选择网络过滤器链,对请求元数据进行更改。比如监听过滤器判断当前请求是否为Http,如果是,然后选择运行不同的网络过滤器。
:::
| ### Envoy内置了几个监听过滤器
| |
| — | — |
| #### 过滤器名称
| #### 过滤器作用
|
| Http检查器 | 检查是否为http请求 |
| 原始目的地 | 当传入连接通过 iptables REDIRECT 或 TPROXY 目标或使用代理协议重定向到 Envoy 时,可以使用原始目标集群。在这些情况下,路由到原始目标集群的请求被转发到由重定向元数据寻址的上游主机,而无需任何显式主机配置或上游主机发现。 |
| 原始来源 | 当Envoy向上游发送请求时,原始IP是Envoy的ip并不是下游的IP,所以该过滤器功能是修改原始IP将envoy的IP变成下游请求的IP再发送给上游主机。注意Linux 上需要 CAP_NET_ADMIN 功能。CAP_NET_ADMIN 提供了普通用户也可以修改原始IP地址的权限。 |
| 代理协议 | 如果下游源地址没有被转换或代理,Envoy就可以使用简单的原始来源过滤器 更换源IP。否则源地址已经被代理更换了,那么就是会使用该协议,该协议会将源IP地址添加到受信任的 http 标头或者使用 HAProxy 代理协议,在这种协议下假定下游连接来自将原始坐标(IP、PORT)放入连接字符串的代理。Envoy 然后提取这些并将它们用作远程地址。 |
| TLS 检查 | TLS Inspector 侦听器过滤器允许检测传输是 TLS 还是纯文本,以此来决定接下来要走的链 |
# 这里是监听过滤链,元素为监听过滤器 listener_filters: - name: envoy.filters.listener.http_inspector typed_config: "@type": type.googleapis.com/envoy.extensions.filters.listener.http_inspector.v3.HttpInspector # 该chains是当前监听器所有过滤链 filter_chains: - filter_chain_match: # 这里判断传输协议为h2 application_protocols: ["h2"] filters: #该数组里的元素为网络过滤器 - name: my_http2_filter ... - filter_chain_match: application_protocols: ["http/1.1"] filters: - name: my_http1_filter
当请求通过监听过滤器之后,通过过滤链匹配机制到达网络过滤器(比如,我们使用了Http检查过滤器,那么网络过滤链需要设置传输协议为h2或h1.1/h1.0才能进行匹配),网络过滤器是一个网络级别的过滤器可以进行连接限制、TLS握手、TCP代理等。
| ## Envoy有几个默认的网络过滤器
| |
| — | — |
| ### 过滤器名称
| ### 作用
|
| Dubbo代理 | dubbo 代理过滤器对 dubbo 客户端和服务器之间的 RPC 协议进行解码。解码后的 RPC 信息被转换为元数据。元数据包括基本请求ID、请求类型、序列化类型,以及路由所需的服务名、方法名、参数名和参数值。 |
| 客户端TLS身份验证 | 通过从 REST VPN 服务获取的证书列表执行 TLS 客户端身份验证。此过滤器将提供的客户端证书哈希与证书列表进行匹配,以确定是否应允许连接。还可以配置可选的 IP 许可名单。此功能可用于为 Web 基础架构构建边缘代理 VPN 支持。 调用的是GET /v1/certs/list/approved |
| 连接限制过滤器 | 连接限制过滤器将连接限制应用于由过滤器的过滤器链处理的传入连接。过滤器处理的每个连接都标记为活动连接,如果活动连接数达到最大连接数限制,将关闭连接,无需进一步过滤器迭代。 |
| TCP代理 | TCP 代理过滤器在下游客户端和上游集群之间执行基本的 1:1 网络连接代理。它可以单独用作 stunnel 的替代品,也可以与其他过滤器(例如MongoDB 过滤器或速率限制过滤器)结合使用。 |
| … | … |
:::info
多个网络过滤器称之为过滤器链,共同完成请求过滤作用。每个侦听器都有多个过滤器链和一个可选的默认过滤器链。与每个过滤器链相关联。如果找不到最佳匹配过滤器链,将选择默认过滤器链来服务请求。如果未提供默认过滤器链,则连接将关闭。
:::
Envoy的过滤器可以对元数据进行修改,那么既然如此我们对请求进行转发,重定向就可以直接在过滤器中实现而不必再进入应用内部处理.Envoy也是这么做的,接下来就让我们了解一下HTTP connection management(HCM) - 一个运行在envoy的网络过滤器插件.
:::info
HTTP 是现代面向服务架构的关键组件,Envoy 实现了大量的 HTTP 特定功能。Envoy 有一个内置的网络级过滤器,称为 HTTP 连接管理器。此过滤器将原始字节转换为 HTTP 级别的消息和事件(例如,收到的标头、收到的正文数据、收到的尾标等)。它还处理所有 HTTP 连接和请求共有的功能,例如访问记录、请求 ID 生成和跟踪、 请求/响应标头操作、路由表管理和统计。
:::
它主要提供的功能有:
HCM对于这些功能的实现也是采用过滤器的形式,字段http_filters 可以进行配置(有顺序性).比如envoy.filters.http.router提供流量路由的功能,可以说HCM的配置都是为http_filters 配置的过滤器提供服务的.
注意,在HCM配置中有一个字段是route_config 它的功能配置管理器的静态路由表.而envoy.filters.http.router过滤器就是读取静态路由表然后对请求进行路由.
下面是一个简单的路由配置:
static_resources: # 创建监听器 listeners: - name: listener_0 # 配置监听地址与端口号 address: socket_address: address: 0.0.0.0 port_value: 10000 # 当前监听器的过滤链 filter_chains: - filters: # 使用HCM 网络过滤器 - name: envoy.filters.network.http_connection_manager typed_config: # 通过该URL获取到HCM类型 "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager # 适用于统计时的标识 stat_prefix: hello_service # 设置http过滤器 ,这里使用的是路由转发过滤器,就是说开启了路由转发功能 http_filters: - name: envoy.filters.http.router # 配置路由表 route_config: name: route virtual_hosts: - name: hello_vhost # 匹配的域名 domains: ["hello.io"] routes: # 根据uri进行转发、重定向等功能 - match: path: "/api" # 这里可以配置直接响应,就是说直接返回给下游 状态码为200 内容为 hellp - path的数据 direct_response: status: 200 body: inline_string: "hello - path" - match: # 对于uri的匹配,可以是前缀匹配、完全匹配、正则表达式匹配等 safe_regex: google_re2: {} regex: ^/hello/\d+$ direct_response: status: 200 body: inline_string: "hello - regex" - match: prefix: "/" direct_response: status: 200 body: inline_string: "hello - prefix"
:::info
集群从推理的角度来将,由服务发现发现出来的主机的合集称之为集群(Envoy的集群)
:::
那么服务发现是如何发现的那?下面让我们对三种方式进行讲解
官网提供了详细的例子供我们进行理解,接下来就让我们走进这个例子
static_resources: # 创建一个监听器 listeners: # 监听器的名称 - name: listener_https # 监听地址 address: socket_address: protocol: TCP address: 0.0.0.0 port_value: 443 # 这是监听过滤链 # 这是一个TLS监听过滤器,判断当前请求是否为TLS listener_filters: # 过滤链的名称,只标识一个名称 - name: "envoy.filters.listener.tls_inspector" typed_config: # 过滤链类型 "@type": type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector # 网络过滤链 filter_chains: - filter_chain_match: # 这里获取当前域名用于sni证书判断 server_names: ["acme.com"] # Downstream TLS configuration. transport_socket: # 使用TLS连接下游请求 name: envoy.transport_sockets.tls typed_config: "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext # 配置TLS连接需要服务器证书与秘钥 common_tls_context: tls_certificates: - certificate_chain: {filename: "certs/servercert.pem"} private_key: {filename: "certs/serverkey.pem"} filters: # 此过滤器将原始字节转换为 HTTP 级别的消息和事件(例如,收到的标头、收到的正文数据、收到的尾标等)。 # 它还处理所有 HTTP 连接和请求共有的功能,例如访问记录、请求 ID 生成和跟踪、 请求/响应标头操作、路由表管理和统计。 - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager # 每个连接管理器都有一个以http.<stat_prefix> 为根的统计树 stat_prefix: ingress_http # 如果设置为 true,则连接管理器将在确定内部与外部来源并处理各种标头时使用客户端连接的真实远程地址。 # 如果设置为 false 或不存在,连接管理器将使用 x-forwarded-for HTTP 标头。 use_remote_address: true # 直接传递给 HTTP/2 编解码器的附加 HTTP/2 设置 http2_protocol_options: # 连接同一个IP的最大数量 max_concurrent_streams: 100 # 管理器使用的日志配置 access_log: - name: envoy.access_loggers.file typed_config: # 使用的日志插件 "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog # 写入访问日志条目的本地文件的路径。 path: "/var/log/envoy/access.log" # 路由配置 route_config: name: local_route # 虚拟主机 virtual_hosts: # 虚拟主机的逻辑名称。这在发出某些统计信息时使用,但与路由无关。 - name: local_service # 将与此虚拟主机匹配的域列表(主机/权限标头)。后缀或前缀形式支持通配符主机。 # 搜索顺序为 确切的域名:www.foo.com. 后缀域通配符:*.foo.com或*-bar.foo.com. 前缀域通配符:foo.*或foo-*. *匹配任何域的特殊通配符。 domains: ["acme.com"] routes: # - match: # 路由匹配参数 path: "/foo" # 将请求路由到 some_service 集群上 route: cluster: some_service # 使用的过滤器,这里只使用了路由转发的功能 http_filters: # - name: some.customer.filter - name: envoy.filters.http.router typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router # 集群 clusters: - name: some_service # 指定与上游连接的类型,如果为指定则使用明文连接 transport_socket: name: envoy.transport_sockets.tls typed_config: "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext load_assignment: # 集群名称 cluster_name: some_service # Static endpoint assignment. # 这里使用静态配置 endpoints: - lb_endpoints: #配置了两个节点 # 这里并没有配置负载均衡策略,默认使用加权轮询 - endpoint: address: socket_address: address: 10.1.2.10 port_value: 10002 - endpoint: address: socket_address: address: 10.1.2.11 port_value: 10002 typed_extension_protocol_options: # 与上游连接提供的连接协议 envoy.extensions.upstreams.http.v3.HttpProtocolOptions: "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicit_http_config: http2_protocol_options: # 配置工作线程中连接池的最大个数 max_concurrent_streams: 100
对于Envoy来说最重要的要数Filter了,我们从上面可以看到,Envoy的每个环节都有过滤器的身影,请求进入Envoy开始先是经过监听过滤器到达网络过滤器,网络过滤器处理完成后到达集群过滤器(是有集群过滤器的只是上面例子没有给出),给人的感觉为Envoy的应用功能(提供应用服务的)都是由过滤器完成的,比如说路由功能由网络过滤器中的HCM完成,日志记录由日志过滤器完成.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。