blog
blog copied to clipboard
【Envoy.EP2】如何使用 xDS 动态配置 Envoy
写在前面
上一篇【Envoy.EP1】 介绍了如何使用filesystem
和runtime对象
来实现 Envoy 的动态配置。但生产环境下,要配置的 Envoy 实例很多而且配置也更复杂,filesystem
就无法满足需求了;同时 Envoy 支持对接外部的配置服务(基于 RESTful 接口),所以这篇文章继续探究更方便的、可用于生产环境的 Envoy 的动态配置方式 --- xDS。
本文源于官方文档Dynamic configuration翻译和整理而来。
xDS
xDS 是一类发现服务的统称,其包括如下几类:
- SDS/EDS: Service/Endpoint(v2) Discovery Service -- 节点发现服务
- CDS: Cluster Discovery Service -- 集群发现服务
- RDS: Route Discovery Service -- 路由规则发现服务
- LDS: Listener Discovery Service -- 监听器发现服务
本小节以 v1
为例,介绍如何使用和扩展自己的 xDS。
v2
版本改用了 gRPC 协议,同时支持 RESTful JSON 接口,支持的功能更多,具体可参见:
全局的 SDS/EDS
用于发现 cluster
内的所有节点,其是 Envoy 官方推荐的节点发现方式,可以规避传统 DNS 方式的问题(如:maximum records in a response),同时还能比 DNS 携带更多信息(如:canary status, zone等),用于实现智能 LB 和 routing。
SDS RESTful API
Envoy 的 SDS v1 要求必须实现以下接口:
- 通过 service 名称获取服务详情。地址:
GET /v1/registration/(string: service_name)
Envoy 官方文档里只提到这一个接口,不过官方提供了一个 Python 的 SDS 实现,提供了包括服务注册、服务注销等接口。详见 Python SDS。
配置 SDS
在之前的文章初战 Envoy中提到,cluster_manager >> clusters >> type
配置项支持五种属性:static
、strict_dns
、logical_dns
、original_dst
、sds
,其中最后一项 sds
设置该 cluster 中的节点发现使用 sds
方式。
下面是一段使用 sds
的 cluster_manager
配置(其他配置项与非 sds 的配置无异),此配置使用 k8s 的 kubernetes-envoy-sds 插件作为 Envoy 的全局 SDS。
参考文档:
{
// cluster_manager 支持以下子属性:
// clusters -- 定义 upstream 集群
// sds -- 配置全局的 节点发现 服务
// cds -- 配置全局的 集群发现 服务
// local_cluster_name / outlier_detection 等
// https://www.envoyproxy.io/docs/envoy/latest/api-v1/cluster_manager/cluster_manager
"cluster_manager": {
"clusters": [
{
"name": "flask-app-envoy-service.default.svc.cluster.local",
"connect_timeout_ms": 250,
"type": "sds",
"lb_type": "round_robin",
// servce_name 就是微服务的名称,通过此名称去 sds 获取访问方式
"service_name": "flask-app-envoy-service.default.svc.cluster.local"
}
],
// 全局 SDS 服务的配置
// https://www.envoyproxy.io/docs/envoy/latest/api-v1/cluster_manager/sds.html#config-cluster-manager-sds
"sds": {
// 以一个 upstream cluster 方式配置 sds
"cluster": {
"name": "kubernetes-envoy-sds.kube-system",
"type": "logical_dns",
"connect_timeout_ms": 250,
"lb_type": "round_robin",
"hosts": [
{"url": "tcp://kubernetes-envoy-sds.kube-system:80"}
]
},
// 必选项,刷新延迟 ms,最大的刷新延迟是 2*refresh_delay_ms
"refresh_delay_ms": 1000
}
}
}
全局的 CDS
用于发现 upstream clusters
的服务,实现集群的动态配置。
对于静态配置的
upstream cluster
,CDS API 无法修改。
CDS RESTful API
Envoy 的 CDS v1 要求必须实现以下接口:
- 根据 service_cluster 名称和 service_node 名称获取 upstream clusters 列表。地址:
GET /v1/clusters/(string: service_cluster)/(string: service_node)
配置 CDS
与 CDS 的配置无差别,这里就不赘述了。
利用 HTTP Request Header 和 CDS 实现动态路由
当使用 CDS,但没有使用 RDS 时,通过在 route 中配置使用 cluster_header 属性作为路由规则,可以实现动态路由功能。
HTTP Connection Manager 中的 RDS
用于发现路由配置规则的服务,实现路由规则的动态配置,路由配置前后不影响当前请求。
RDS RESTful API
Envoy 中的 RDS v1 要求必须实现以下接口:
- 通过 (route_config_name, service_cluster, service_node) 获取路由规则配置。地址是:
GET /v1/routes/(string: route_config_name)/(string: service_cluster)/(string: service_node)
配置 RDS
RDS 与全局的 SDS、CDS 不同,RDS 的定义位于 HTTP Connection Manager
下,如下所示:
{
"name": "http_connection_manager",
"config": {
"codec_type": "auto",
"stat_prefix": "ingress_http",
// rds 与 route_config 是二选一的
// https://www.envoyproxy.io/docs/envoy/v1.5.0/api-v1/network_filters/http_conn_man.html#config-http-conn-man-rds-option
"rds": {
// 必选项,指定提供 rds 服务的 cluster 名称,必须在 cluster_manager 中定义
"cluster": "rds",
// 必选项,指定此路由配置的名称,此值会用于从 RDS 中获取配置规则
"route_config_name": "rds_route_conf_1",
// 可选项
"refresh_delay_ms": 30000
},
"filters": [
{
"name": "router",
"config": {}
}
]
}
}
全局的 LDS
用于发现 listeners
的服务,实现监听器的动态配置。由于绝大多数配置项均在监听器中定义,所以使用 LDS 服务会大大减少 Envoy 的重启(仅 admin配置修改、tracing配置修改、envoy bin 文件更新等才需要重启)。
LDS RESTful API
Envoy 的 LDS v1 要求必须实现以下接口:
- 根据 service_cluster 名称和 service_node 名称获取 listeners 列表。地址:
GET /v1/listeners/(string: service_cluster)/(string: service_node)
LDS 配置
LDS 配置与 listeners
同级,即:
{
"listeners": [],
// 如果不定义,则只加载 listeners 配置项配置的静态监听器;如果定义,则都加载
"lds": {
// 提供 LDS 服务的 cluster 名称,必须在 cluster_manager 中定义,与 SDS/CDS 不同
"cluster": "...",
"refresh_delay_ms": 30000
}
}
参考文档
请问SDS服务如何搭建?