今天来简单说说envoy的配置
想象一下网络代理程序的流程,比如作为一个代理,首先要能获取请求流量,通常是采用监听端口的方式实现;其次拿到请求数据后需要对其做微处理,例如附加 Header
或校验某个 Header
字段的内容等,这里针对来源数据的层次不同,可以分为 L3/L4/L7
,然后将请求转发出去;转发这里又可以衍生出如果后端是一个集群,需要从中挑选一台机器,如何挑选又涉及到负载均衡等。
脑补完大致流程后,再来看 Envoy 是如何组织配置信息的:
代码语言:javascript复制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的设计跟我们上面说的大体一致,其实我们熟悉的ngxin也是一样。
先简单解释一下其中的关键字段,详细的解释可以看后面的章节。
listener
: Envoy 的监听地址,就是真正干活的。Envoy 会暴露一个或多个 Listener 来监听客户端的请求。filter
: 过滤器。在 Envoy 中指的是一些“可插拔”和可组合的逻辑处理层,是 Envoy 核心逻辑处理单元。route_config
: 路由规则配置。即将请求路由到后端的哪个集群。cluster
: 服务提供方集群。Envoy 通过服务发现定位集群成员并获取服务,具体路由到哪个集群成员由负载均衡策略决定。
Envoy 内部对请求的处理流程其实跟我们上面脑补的流程大致相同,即对请求的处理流程基本是不变的,而对于变化的部分,即对请求数据的微处理,全部抽象为 Filter
Envoy 的插件当前采用的是静态注册的方式,插件代码和 Envoy 代码一块进行编译,和 Nginx 不同,Envoy 从最开始就支持插件的动态加载,Envoy 通过独特的 XDS API 设计,可以随时对 Envoy 的 XDS 插件进行定制修改,Istio 将修改后的 XDS 配置通过 Grpc 的方式推送给 Envoy 动态加载和生效。
Envoy 的配置管理部分设计得就比较优雅,配置格式直接使用了 Protobuf 3,复用了 Protobuf 3 的数据描述能力和自动代码生成机制,完全省去了配置解析的过程,并且也非常方便对配置格式的有效性进行验证。Nginx 的配置都是静态配置,不支持任何形式的动态配置能力。动态配置能力是 Envoy 相比 Nginx 最核心的竞争力,通过动态配置,可以在线修改流量路由和链路治理策略,实现策略配置修改的即时生效。