Envoy 基础教程:集成服务发现


为 Envoy 配置 CDS 和 EDS

Envoy 基础教程:集成服务发现

为 Envoy 配置 CDS 和 EDS

  • Kubernetes 知识图谱
  • 云原生导航
  • 谷歌搜索
  • Raft 协议动画演示
  • 搬瓦工

    在微服务中使用 Envoy,需要明确两个核心概念:数据平面控制平面

    • 数据平面 由一组 Envoy 实例组成,用来调解和控制微服务之间的所有网络通信。
    • 控制平面 从 Envoy 代理和其他服务收集和验证配置,并在运行时执行访问控制和使用策略。

    你可以使用静态类型的配置文件来实现控制平面,但为了能做出更加智能的负载均衡决策,最好的方法是通过 API 接口来实现。通过 API 接口来集中发现服务可以充分利用 Envoy 动态更新配置文件的能力。设置控制平面的第一步就是将 Envoy 连接到服务发现服务(SDS),通常分为三步:

    1. 实现一个控制平面
    2. 将控制平面中定义的服务发布到 Envoy 的 clusters
    3. 将 主机/容器/实例 发布到 Envoy 的 endpoints

    1. 实现一个控制平面


    控制平面必须要满足 Envoy v2 xDS APIs,同时为了更好地使用服务发现能力,你的控制平面最好能够实现集群发现服务(CDS)和端点发现服务(EDS)。为了避免重复造轮子,你可以选择社区已经实现好的控制平面:

    • Rotor : Rotor 是一种快速、轻量级的 xDS 实现,它可以和 KubernetesConsulAWS 等服务集成,并且提供了一组默认的路由发现服务(RDS)和监听器发现服务(LDS)。它也是 Turbine Labs 的商业解决方案 Houston 的组件之一,Houston 在 Rotor 的基础上增加了更多的路由、指标和弹性方面的配置。
    • go-control-plane : Envoy 官方仓库提供了一个开源版本的控制平面:go-control-plane。如果你想弄清楚如何从服务发现服务中获取所有内容,可以好好研究一下这个项目。
    • Pilot : 如果想将 Envoy 和 Kubernetes 集成,你可以选择 Istio 项目。Istio 中的控制平面是由 Pilot 组件来实现的,它会将 YAMl 文件的内容转换为相应的 xDS 响应。如果你不想使用 Istio,也不用担心,因为 Pilot 完全可以脱离 Istio 的其他组件(如 Mixer)来单独和 Envoy 集成。

    2. 将服务发布到 CDS


    集群是 Envoy 连接到的一组逻辑上相似的上游主机,通过它可以对流量进行负载均衡。你可以通过调用集群发现服务(CDS)的 API 来动态获取集群管理成员,Envoy 会定期轮询 CDS 端点以进行集群配置,配置文件形式如下:

    version_info: "0"
    resources:
    - "@type": type.googleapis.com/envoy.api.v2.Cluster
      name: some_service
      connect_timeout: 1.0s
      lb_policy: ROUND_ROBIN
      type: EDS
      eds_cluster_config:
        eds_config:
          api_config_source:
            api_type: GRPC
            cluster_names: [xds_cluster]
    

    服务发现收集的每个服务都会映射到 resources 下面的一个配置项,除此之外你还需要为负载均衡设置一些额外的配置参数:

    • lb_policy : 集群的负载均衡类型,有以下几种方式:
      • round_robin : 轮询主机
      • weighted_least_request : 最近获得最少请求的主机
      • random : 随机
    • connect_timeout : 设置连接超时。越小越好,从 1 秒开始慢慢往上增加,直到网络没有明显的抖动为止。
    • api_type : 设置服务的协议。Envoy 通过该协议和服务发现服务进行通信。

    通常情况下,你可以对端点(Endpoint)列表进行硬编码,但如果基础架构是动态的,则需要将 type 设置为 EDS,这将告诉 Envoy 轮询 EDS API 以获取可用的 IP/Port 列表。完整示例可以参考 Envoy 的官方文档

    设置好 CDS 之后,就可以为此集群设置端点发现服务(EDS)了。

    3. 将实例发布到 EDS


    Envoy 将端点(Endpoint)定义为集群中可用的 IP 和端口。为了能够对服务之间的流量进行负载均衡,Envoy 希望 EDS API 能够提供每个服务的端点列表。Envoy 会定期轮询 EDS 端点,然后生成响应:

    version_info: "0"
    resources:
    - "@type": type.googleapis.com/envoy.api.v2.ClusterLoadAssignment
      cluster_name: some_service
      endpoints:
      - lb_endpoints:
        - endpoint:
           address:
             socket_address:
               address: 127.0.0.2
               port_value: 1234
    

    通过这种配置方式,Envoy 唯一需要知道的就是该端点属于哪个集群,这比直接定义集群更简单。

    Envoy 将 CDS 和 EDS 视为一份份的报告并保持服务发现的最终一致性。如果到该端点的请求经常失败,就会从负载均衡中删除该端点,直到再次恢复正常访问。

    4. 最佳实践:对配置进行分区


    当集群中有很多服务时,Envoy 与 CDS 和 EDS 的交互量将会非常庞大,一旦出现问题,从几千个 API 响应中排查问题是很不现实的。标准的做法是以两种方式对配置进行分区:

    • 根据数据中心/区域划分 : 通常情况下,一个数据中心的服务不需要知道其他数据中心可用的服务端点。要想在不同区域之间建立通信,需要将远程数据中心的前端代理添加到本地的负载均衡器中。
    • 根据服务需求划分 : 通过为不同的服务配置 Envoy 边车代理(服务 envoy 与每个 serivce 实例一起运行),设置白名单来限制不同服务之间的相互通信,可以降低 1000 个级别的微服务之间相互通信的复杂度。同时边车(Sidecars)代理还可以通过阻止对服务的意外调用来加强安全保护。

    对配置进行分区可以降低对不同服务的运营和管理的难度,但它的代价是使控制平面变得更加复杂,但客户往往是不关心控制平面的,所以牺牲控制平面的复杂度还是很值得的。

    5. 下一步


    一旦控制平面发现了所有可用服务,就可以在这些服务上配置路由了。下一节将会介绍如何配置路由发现服务(RDS)。


    https://hugo-picture.oss-cn-beijing.aliyuncs.com/images/wechat.gif
    扫一扫关注微信公众号


    -------他日江湖相逢 再当杯酒言欢-------

    「真诚赞赏,手留余香」

    米开朗基杨

    真诚赞赏,手留余香

    使用微信扫描二维码完成支付


    相关推荐