imjoey / blog

My Blog based on Github Issues.
286 stars 44 forks source link

【Envoy.EP2】如何使用 xDS 动态配置 Envoy #30

Open imjoey opened 6 years ago

imjoey commented 6 years ago

写在前面

上一篇【Envoy.EP1】 介绍了如何使用filesystemruntime对象 来实现 Envoy 的动态配置。但生产环境下,要配置的 Envoy 实例很多而且配置也更复杂,filesystem 就无法满足需求了;同时 Envoy 支持对接外部的配置服务(基于 RESTful 接口),所以这篇文章继续探究更方便的、可用于生产环境的 Envoy 的动态配置方式 --- xDS。

本文源于官方文档Dynamic configuration翻译和整理而来。

xDS

xDS 是一类发现服务的统称,其包括如下几类:

本小节以 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 要求必须实现以下接口:

Envoy 官方文档里只提到这一个接口,不过官方提供了一个 Python 的 SDS 实现,提供了包括服务注册、服务注销等接口。详见 Python SDS

配置 SDS

在之前的文章初战 Envoy中提到,cluster_manager >> clusters >> type 配置项支持五种属性:staticstrict_dnslogical_dnsoriginal_dstsds,其中最后一项 sds 设置该 cluster 中的节点发现使用 sds 方式。

下面是一段使用 sdscluster_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 要求必须实现以下接口:

配置 CDS

与 CDS 的配置无差别,这里就不赘述了。

利用 HTTP Request Header 和 CDS 实现动态路由

当使用 CDS,但没有使用 RDS 时,通过在 route 中配置使用 cluster_header 属性作为路由规则,可以实现动态路由功能。

HTTP Connection Manager 中的 RDS

用于发现路由配置规则的服务,实现路由规则的动态配置,路由配置前后不影响当前请求。

RDS RESTful API

Envoy 中的 RDS v1 要求必须实现以下接口:

配置 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 要求必须实现以下接口:

LDS 配置

LDS 配置与 listeners 同级,即:

{
  "listeners": [],
  // 如果不定义,则只加载 listeners 配置项配置的静态监听器;如果定义,则都加载
  "lds": {
    // 提供 LDS 服务的 cluster 名称,必须在 cluster_manager 中定义,与 SDS/CDS 不同
    "cluster": "...",
    "refresh_delay_ms": 30000
  }
}

参考文档

startan commented 5 years ago

请问SDS服务如何搭建?