envoyのxDS設定

envoyのconfigは、設定ファイルにスタティックに定義する方法のほか、xDSプロトコルに沿って動的に設定する方法も利用できます。

xDSはgRPCサービスを構成する方法と、configファイルをxDSの規約に沿って書く方法があります。xDSの有無それぞれのケースを確認すると目的を理解しやすいでしょう。
xDSを使わない場合のconfigは以下のような定義になります。

static_resources:
  listeners:
  - name: listener_http
    ...
  clusters:
  - name: upstream_host
    ...

そしてxDSを利用すると、以下のような定義になります(v1.22以降)。

dynamic_resources:
  lds_config:
    path_config_source:
      path: "/etc/envoy/listeners.yaml"
      watched_directory: 
        path: /etc/envoy
    resource_api_version: V3
  cds_config:
    path_config_source:
      path: "/etc/envoy/clusters.yaml"
      watched_directory: 
        path: /etc/envoy
    resource_api_version: V3

watched_directoryはオプションです。主にKubernetesのconfigMapを用いて設定を供給している場合のリロード用設定です。
KubernetesのconfigMapはファイル更新をシンボリックリンクで実装しているために、動的更新が効かなかった点への機能追加です。

v1.21以前にはpath_config_sourceがないため、以下の記述です。

# This format is deprecated in v1.23
dynamic_resources:
  lds_config:
    path: "/etc/envoy/listeners.yaml"
    resource_api_version: V3
  cds_config:
    path: "/etc/envoy/clusters.yaml"
    resource_api_version: V3

xDSを利用する場合には、動的変更がある想定であるためdynamic_resourcesとなり、configを別ファイルに分割できます。副次的な効果として、YAMLのネストも浅くなります。
なお、resource_api_versionV3以降必要になりました。

※ なおxDS利用時にはconfig トップレベルnodeを定義しておく必要があります

ファイルベースのxDSでは、configの変更をウォッチする挙動となり、更新に応じて設定更新がかかります。

clusterのconfig例は以下のとおりです。

version_info: "1"
resources:
- name: https_upstream
  "@type": type.googleapis.com/envoy.config.cluster.v3.Cluster
  type: STRICT_DNS
  connect_timeout: 3s
  lb_policy: round_robin
  load_assignment:
    cluster_name: https_upstream
    endpoints:
    - lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address: https_upstream
              port_value: 80

xDSではversion_infoにより、configの変更を定義しておきます。resources以下がプロトコルに沿ったリソース定義です。xDSといえども、スタティックに定義する場合とデータ構造は基本的に同じです。

リソースのフォーマットは、 xDS REST and gRPC protocolにマニュアルがあります。上の例では、CDSv3に沿って記述しています。

CDS(Cluster Discovery Service)やLDS(Listener Discovery Service)のほかにも、Listenerリソースのfilter_chains[].filters[].typed_config.rdsに定義できる RDS(Route Discovery Service)やTLS証明書用のSDS(Secret Discovery Service)もあります。

リファレンスがフラットに書かれているため探しにくい面がありますが、各xDSごとに定義できる階層は異なります。RDSはrouteを定義できる階層に定義でき、同様にVirtualHost定義をVHDSで置き換えることが可能です。

そのほか、xDSのラインアップについては xDS configuration API overviewを参照してください。

KubernetesのConfigMap

xDSは動的コンフィグの機構ですが、現状、kubernetesのConfigMapやSecret経由でマウントした設定ファイルについては、動的に反映できません。以下のissueで議論されているとおり、Secretなどはsymlinkによるファイル差し替え実装になっており、envoyがinotifyを受け取れない、ということのようです。

実際に検証してみましたが、Secret更新によりenvoyコンテナ内の設定ファイルの変更は可能ですが、envoyの挙動には反映しない動作となりました。コンテナ再起動により、新設定が有効になります。

中馬崇尋
Chuma Takahiro