标签:用法 google points 适应 manual Kubernete family 集中 type
在梳理开源的 API 网关和 ServiceMesh 项目时,最常遇到的一个词是 Envoy,Ambassador、Contour、Gloo、Istio 等项目的数据平面都选用了 Envoy。Envoy 何德何能受到众多项目的青睐? 掌握 Envoy 的脉络只需 2 分钟。
Envoy 是一个具有反向代理和负载均衡功能的单机软件,和 Nginx、Haproxy 属于同一类软件。与 Nginx 和 Haproxy 相比,Envoy 有一个的重要特色是:自带配置 API。
以 Nginx、Haproxy 为代表的负载均衡软件,在过去很多年的实际应用中,很少会在软件运行的时候更改配置,即使偶尔要修改配置文件,使用 reload 等命令重新加载就能满足需要。
以 Kubernetes 为代表的 PaaS 或者容器管理系统出现后,IT 系统沿着“分工专业化、更少的人做更多同质事情”的路线演进,在当前的演进过程中,反向代理与负载均衡的能力被集中管理、统一提供。
这一演进在 Kubernetes 中体现为作为集群出口的 ingress 代理集群内所有服务,在以 istio 为代表的 ServiceMesh 中体现为分散在各处的代理软件在同一个中心的控制下流转流量。 无论是作为 Kubernetes 的出口,还是作为 Mesh 中的一个节点,承担流量转发功能的组件都需要完成一个挑战: 在运行过程中频繁的更新配置。
新场景中的更新的频率是每秒 N 次,远远超过以往的场景中以周、月乃至年为周期的更新频率。这种情形下,热加载配置文件的方式明显迟缓笨重,有一些项目通过开发一个带有 API 功能的组件,实现生成配置文件、触发热加载的功能,以此赋予 Nginx、Haproxy 等传统负载均衡软件高频更新配置的能力。
但是,如果有一个软件原生带有配置 API,且专注于数据平面,它作为可靠的第三方存在,能够让控制平面专心于规则管理,那么它是不是会很受欢迎呢?
Envoy 就是这样一款软件。注意,这里只是在交代背景,不为 envoy 吹票,nginx、haproxy 等都在更新演进以适应场景的变化。
Envoy 的功能和使用细节繁杂,但只要搞清楚了 Cluster、Listener 和 Filter 的用途,就把握住了大方向。
Cluster 就是一组 IP,相当于 Nginx 中 upstream,负载均衡策略在 cluster 中设置,cluster 中可以是 IP 也可以是域名:
Listener 就是监听地址和转发规则:
Envoy 的配置文件是从零开始了解 Envoy 时遇到的最大困难,它的配置比较繁杂,而且缺少系统的介绍。
配置文件在 envoy 启动时,用 -c
指定,内容分为以下几个部分:
{
"node": {
"id": "...",
"cluster": "...",
"metadata": "{...}",
"locality": "{...}",
"build_version": "..."
},
"static_resources": {
"listeners": [],
"clusters": [],
"secrets": []
},
"dynamic_resources": {
"lds_config": "{...}",
"cds_config": "{...}",
"ads_config": "{...}"
},
"cluster_manager": {
"local_cluster_name": "...",
"outlier_detection": "{...}",
"upstream_bind_config": "{...}",
"load_stats_config": "{...}"
},
"hds_config": {
"api_type": "...",
"cluster_names": [],
"grpc_services": [],
"refresh_delay": "{...}",
"request_timeout": "{...}",
"rate_limit_settings": "{...}"
},
"flags_path": "...",
"stats_sinks": [
{
"name": "...",
"config": "{...}"
}
],
"stats_config": {
"stats_tags": [],
"use_all_default_tags": "{...}",
"stats_matcher": "{...}"
},
"stats_flush_interval": "{...}",
"watchdog": {
"miss_timeout": "{...}",
"megamiss_timeout": "{...}",
"kill_timeout": "{...}",
"multikill_timeout": "{...}"
},
"tracing": {