Envoy xDS API基础

动态配置

xDS API概述

Envoy对xDS API的管理由后端服务器实现,包括LDS、CDS、RDS、SRDS(Scoped Route)、VHDS(Virtual Host)、EDS、SDS、RTDS(Runtime)等;

  • 所有这些API都提供了最终的一致性,并且彼此间不存在相互影响;

  • 部分更高级别的操作(例如执行服务的A/B部署)需要进行排序以防止流量被丢弃,因此,基于一个管理服务器提供多类API时还需要使用聚合发现服务(ADS)API;
    • ADS API允许所有其他API通过来自单个管理服务器的单个gRPC双向流进行编组,从而允许对操作进行确定性排序;

  • 另外,xDS的各API还支持增量传输机制,包括ADS;

Bootstrap node 配置段

配置说明

一个Management Server实例可能需要同时响应多个不同的Envoy实例的资源发现请求

  • Management Server上的配置需要为适配到不同的Envoy实例

  • Envoy实例请求发现配置时,需要在请求报文中上报自身的信息

    • 例如id、cluster、metadata和locality等

    • 这些配置信息定义在Bootstrap配置文件中

      • 专用的顶级配置段“node{…}”

配置格式

node:
  id: … # An opaque node identifier for the Envoy node. 
  cluster: … # Defines the local service cluster name where Envoy is running. 
  metadata: {…} # Opaque metadata extending the node identifier. Envoy will pass this directly to the management server.
  locality: # Locality specifying where the Envoy instance is running.
    region: …
    zone: …
    sub_zone: …
  user_agent_name: … # Free-form string that identifies the entity requesting config. E.g. “envoy” or “grpc”
  user_agent_version: … # Free-form string that identifies the version of the entity requesting config. E.g. “1.12.2” or “abcd1234” , or “SpecialEnvoyBuild”
  user_agent_build_version: # Structured version of the entity requesting config.
    version: …
    metadata: {…}
  extensions: [ ] # List of extensions and their versions supported by the node.
  client_features: [ ]
  listening_addresses: [ ] # Known listening ports on the node as a generic hint to the management server for filtering listeners to be returned.

API 流程

  • 对于典型的HTTP路由方案,xDS API的Management Server需要为其客户端(Envoy实例)配置的核心资源类型为Listener、RouteConfiguration、Cluster和ClusterLoadAssignment四个;
    • 每个Listener资源可以指向一个RouteConfiguration资源,该资源可以指向一个或多个Cluster资源,并且每个Cluster资源可以指向一个ClusterLoadAssignment资源;
  • Envoy实例在启动时请求加载所有Listener和Cluster资源,而后,再获取由这些Listener和Cluster所依赖的RouteConfiguration和ClusterLoadAssignment配置;
    • 此种场景中,Listener资源和Cluster资源分别代表着客户端配置树上的“根(root)”配置,因而可并行加载;
  • 类型gRPC一类的非代理式客户端可以仅在启动时请求加载其感兴趣的Listener资源,而后再加载这些特定Listener相关的RouteConfiguration资源;再然后,是这些RouteConfiguration资源指向的Cluster资源,以及由这些Cluster资源依赖的ClusterLoadAssignment资源;
    • 该种场景中,Listener资源是客户端整个配置树的“根”;

Envoy资源的配置源

  • 配置源(ConfigSource)用于指定资源配置数据的来源,用于为Listener、Cluster、Route、Endpoint、Secret和VirtualHost等资源提供配置数据;
  • 目前,Envoy支持的资源配置源只能是path、api_config_source或ads其中之一;

  • api_config_source或ads的数据来自于xDS API Server,即Management Server;

基于文件系统的订阅

基于文件系统的订阅说明

  • 为Envoy提供动态配置的最简单方法是将其放置在ConfigSource中显式指定的文件路径中

    • Envoy将使用inotify(Mac OS X上的kqueue)来监视文件的更改,并在更新时解析文件中的DiscoveryResponse报文
    • 二进制protobufs,JSON,YAML和proto文本都是DiscoveryResponse所支持的数据格式

  • 除了统计计数器和日志以外,没有任何机制可用于文件系统订阅ACK/NACK更新。除了统计计数器和日志以外,没有任何机制可用于文件系统订阅ACK/NACK更新。

基于文件系统的订阅EDS配置示例

以EDS为例,Cluster为静态定义,其各Endpoint通过EDS动态发现;

Cluster定义格式

# Cluster中的endpoint配置格式
clusters:
- name:
  ...
  eds_cluster_config:
    service_name:
    eds_config:
      path: ... # ConfigSource,支持使用path, api_config_source或ads三者之
      path_config_source: {...}
      api_config_source: {...}
      ads: {...}
      initial_fetch_timeout: {...}
      resource_api_version: ...

Cluster配置示例

# 新格式的配置
clusters:
  - name: targetCluster
    connect_timeout: 0.25s
    lb_policy: ROUND_ROBIN
    type: EDS
    eds_cluster_config:
      service_name: webcluster
      eds_config:
        path: '/etc/envoy/eds.conf' # 指定订阅的文件路径

基于文件系统的订阅LDS和CDS配置示例

LDS和CDS配置示例说明

  • 各Listener的定义以Discovery Response的标准格式保存于一个文件中;

  • 各Cluster的定义同样以Discovery Response的标准格式保存于另一文件中;

Envoy Bootstrap配置示例

node:
  id: envoy_front_proxy
  cluster: MageEdu_Cluster
admin:
  profile_path: /tmp/envoy.prof
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
    address: 0.0.0.0
    port_value: 9901
dynamic_resources:
  lds_config:
    path: /etc/envoy/conf.d/lds.yaml
  cds_config:
    path: /etc/envoy/conf.d/cds.yaml

lds.yaml

查看代码
resources:
 - "@type": type.googleapis.com/envoy.config.listener.v3.Listener
  name: listener_http
  address:
    socket_address: { address: 0.0.0.0, port_value: 80 }
  filter_chains: 
  - filters:
    name: envoy.http_connection_manager
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
      stat_prefix: ingress_http
      route_config:
        name: local_route
        virtual_hosts: 
        - name: local_service
          domains: ["*"]
          routes:
          - match:
              prefix: "/"
            route:
              cluster: webcluster
       http_filters: 
       - name: envoy.filters.http.router

cds.yaml

查看代码
resources:
- "@type": type.googleapis.com/envoy.config.cluster.v3.Cluster
  name: webcluster
  connect_timeout: 1s
  type: STRICT_DNS
  load_assignment:
    cluster_name: webcluster
    endpoints:
    - lb_endpoints: 
      - endpoint:
        address:
          socket_address:
            address: webserver01
            port_value: 8080
      - endpoint:
        address:
          socket_address:
            address: webserver02
            port_value: 8080

gRPC订阅

gRPC订阅说明

  • Enovy支持为每个xDS API独立指定gRPC ApiConfigSource,它指向与管理服务器对应的某上游集群;
    • 这将为每个xDS资源类型启动一个独立的双向gRPC流,可能会发送给不同的管理服务器
    • 每个流都有自己独立维护的资源版本,且不存在跨资源类型的共享版本机制;
    • 在不使用ADS的情况下,每个资源类型可能具有不同的版本,因为Envoy API允许指向不同的EDS/RDS资源配置并对应不同的ConfigSources;
  • API的交付方式采用最终一致性机制;

基于gRPC的动态配置说明

  • 以LDS为例,它配置Listener以动态方式发现和加载,而内部的路由可由发现的Listener直接提供,也可配置再经由RDS发现;
  • 提供gRPC API服务的Management Server(控制平面)也需要定义为Envoy上的集群,并由envoy实例通过xDS API进行请求;
    • 通常,这些管理服务器需要以静态资源的格式提供;

    • 类似于,DHCP协议的Server端的地址必须静态配置,而不能经由DHCP协议获取;

基于gRPC的动态配置格式

dynamic_resouces:
  lds_config:
    api_config_source:
      api_type: ... # API可经由REST或gRPC获取,支持的类型包括REST、gRPC和delta_gRPC
      resource_api_version: ... # xDS资源的API版本,对于1.19及之后的Envoy版本,要使用v3;
      rate_limit_settings: {...} # 速率限制
      grpc_services: # 提供grpc服务的一到多个服务源
        transport_api_version: ... # xDS传输协议使用的API版本,对于1.19及之后的Envoy版本,要使用v3;
        envoy_grpc: # Envoy内建的grpc客户端,envoy_grpc和google_grpc二者仅能用其一;
          cluster_name: ... # grpc集群的名称;
        google_grpc: # Google的C++ grpc客户端
        timeout: ... # grpc超时时长;

基于gRPC管理服务器订阅LDS和CDS配置示例

基于gRPC的订阅功能需要向专用的Management Server请求配置信息。

front-envoy.yaml

查看代码
node:
  id: envoy_front_proxy
  cluster: webcluster

admin:
  profile_path: /tmp/envoy.prof
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
       address: 0.0.0.0
       port_value: 9901

dynamic_resources:
  lds_config:
    resource_api_version: V3
    api_config_source:
      api_type: GRPC
      transport_api_version: V3
      grpc_services:
      - envoy_grpc:
          cluster_name: xds_cluster

  cds_config:
    resource_api_version: V3
    api_config_source:
      api_type: GRPC
      transport_api_version: V3
      grpc_services:
      - envoy_grpc:
          cluster_name: xds_cluster

static_resources:
  clusters:
  - name: xds_cluster
    connect_timeout: 0.25s
    type: STRICT_DNS
    typed_extension_protocol_options:
      envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
        "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
        explicit_http_config:
          http2_protocol_options: {}
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: xds_cluster
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: my-control-plane
                port_value: 18000

config.yaml

查看代码
name: myconfig
spec:
  listeners:
  - name: listener_http
    address: 0.0.0.0
    port: 80
    routes:
    - name: local_route
      prefix: /
      clusters:
      - webcluster
  clusters:
  - name: webcluster
    endpoints:
    - address: 172.31.15.11
      port: 80

ADS

ADS说明

交互顺序保证MS资源分发时的流量丢弃是一项很有挑战的工作,而ADS允许单一MS通过单个gRPC流提供所有的API更新;

  • 配合仔细规划的更新顺序,ADS可规避更新过程中流量丢失

  • 使用 ADS,在单个流上可通过类型 URL 来进行复用多个独立的DiscoveryRequest/DiscoveryResponse 序列

ADS配置示例

查看代码
node:
  # set <cluster identifier>
  cluster: envoy_cluster
  # set <node identifier>
  id: envoy_node

dynamic_resources:
  ads_config:
    api_type: GRPC
    transport_api_version: V3
    grpc_services:
    - envoy_grpc:
        cluster_name: ads_cluster
  cds_config:
    resource_api_version: V3
    ads: {}
  lds_config:
    resource_api_version: V3
    ads: {}

static_resources:
  clusters:
  - name: ads_cluster
    type: STRICT_DNS
    load_assignment:
      cluster_name: ads_cluster
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                # set <ADS management server address>
                address: my-control-plane
                # set <ADS management server port>
                port_value: 777
    # It is recommended to configure either HTTP/2 or TCP keepalives in order to detect
    # connection issues, and allow Envoy to reconnect. TCP keepalive is less expensive, but
    # may be inadequate if there is a TCP proxy between Envoy and the management server.
    # HTTP/2 keepalive is slightly more expensive, but may detect issues through more types
    # of intermediate proxies.
    typed_extension_protocol_options:
      envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
        "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
        explicit_http_config:
          http2_protocol_options:
            connection_keepalive:
              interval: 30s
              timeout: 5s
    upstream_connection_options:
      tcp_keepalive: {}

REST-JSON轮询订阅

REST-JSON轮询订阅说明

  • 通过REST端点进行的同步(长)轮询也可用于xDS单例API

  • 上面的消息顺序是类似的,除了没有维护到管理服务器的持久流

  • 预计在任何时间点只有一个未完成的请求,因此响应nonce在REST-JSON中是可选的

  • proto3的JSON规范转换用于编码DiscoveryRequest和DiscoveryResponse消息

  • ADS不适用于REST-JSON轮询

  • 当轮询周期设置为较小的值时,为了进行长轮询,则还需要避免发送DiscoveryResponse,除非发生了对底层资源的更改

基于REST管理服务器订阅配置格式

提供REST API服务的管理服务器也需要定义为Envoy上的集群,并由LDS等相关的动态发现服务进行调用;但这些管理服务器需要以静态配置的格式提供;

dynamic_resources:
  lds_config:
    resource_api_version: … # xDS资源配置遵循的API版本,v1.19版本及以后仅支持V3 ;
    api_config_source:
      transport_api_version: ... # xDS传输协议中使用API版本,v1.19版本及以后仅支持V3;
      api_type: ... # API可经由REST或gRPC获取,支持的类型包括REST、GRPC和DELTA_GRPC
      cluster_names: ... # 提供服务的集群名称列表,仅能与REST类型的API一起使用;多个集群用于冗余之目的,故障时将循环访问;
      refresh_delay: ... # REST API轮询时间间隔;
      request_timeout: ... # REST API请求超时时长,默认为1s;

基于REST管理服务器订阅配置示例

查看代码
 node:
  # set <cluster identifier>
  cluster: envoy_cluster
  # set <node identifier>
  id: envoy_node

dynamic_resources:
  cds_config:
    resource_api_version: V3
    api_config_source:
      api_type: REST
      transport_api_version: V3
      refresh_delay: {nanos: 500000000} # 1/2s
      cluster_names: 
      - xds_cluster
  lds_config:
    resource_api_version: V3
    api_config_source:
      api_type: REST
      transport_api_version: V3
      refresh_delay: {nanos: 500000000} # 1/2s
      cluster_names: 
      - xds_cluster
static_resources:
  clusters:
  - name: ads_cluster
    type: STRICT_DNS
    load_assignment:
      cluster_name: ads_cluster
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: my-control-plane
                port_value: 777

参考文档

https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol#xds-protocol

https://www.envoyproxy.io/docs/envoy/latest/configuration/overview/xds_api#v3-grpc-streaming-endpoints

https://www.envoyproxy.io/docs/envoy/latest/configuration/overview/mgmt_server

posted @ 2022-08-25 16:49  小吉猫  阅读(1012)  评论(0编辑  收藏  举报