Envoy配置使用


Envoy配置使用

Envoy代理有兩個常見用途。一是用作服務代理(sidecar),二是用作網關。

用作sidecar時,Envoy是一個位於服務旁邊的四層或七層的應用代理,可以生成指標、應用策略和控制流量。

用作API網關時,Envoy作為一個“前置代理”接受inbound流量,核對請求中的信息並將其定向到目的地。本文的例子將演示如何使用Envoy作為前置代理。我們將編寫一個靜態配置,返回例如HTTP和IPv4等不會改變的靜態數據。正如你將在本例中看到的那樣,這一用途很簡單,適合處理幾乎不變化的信息。

envoy基本請求流程

img
  • listener:與端口綁定並監聽到達網關的inbound請求,listener 的監聽地址是互斥的,兩個 listener 不能監聽同一個 socket 地址
  • filter chain:請求被listener接受進入Envoy后應當被如何處理,它由一些filter組成,filter決定請求能否被傳遞到下一個filter或發生短路。filter chains是network filter,可以有多組。
  • Route:請求通過所有filter后,route將會將請求定向到正確的服務

編寫yaml文件

#聲明靜態資源
static_resources:
  listeners:
    - address:
        socket_address:
          address: 0.0.0.0
          port_value: 8080
      filter_chains:  #過濾鏈和路由
        - filters:
            - name: envoy.filters.network.http_connection_manager
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                codec_type: auto
                stat_prefix: ingress_http
                route_config:
                  name: local_route
                  virtual_hosts:
                    - name: backend
                      domains:
                        - "*"
                      routes:
                        - match:
                            prefix: "/service/1"
                          route:
                            cluster: service1
                        - match:
                            prefix: "/service/2"
                          route:
                            cluster: service2
                http_filters:
                  - name: envoy.filters.http.router
                    typed_config: {}
  clusters: #設置集群
    - name: service1
      connect_timeout: 0.25s
      type: strict_dns
      lb_policy: round_robin
      http2_protocol_options: {}
      load_assignment:
        cluster_name: service1
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: 10.244.1.1
                      port_value: 8000
    - name: service2
      connect_timeout: 0.25s
      type: strict_dns
      lb_policy: round_robin
      http2_protocol_options: {}
      load_assignment:
        cluster_name: service2
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: service2
                      port_value: 8000
admin:
  access_log_path: "/dev/null"
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 8001

envoy動態配置方法

Listener、Cluster等除了在配置文件中靜態配置,還可以從控制平面動態獲取。下發動態配置的服務叫做控制平面,它的地址以cluster的形式在配置文件中靜態配置,然后在dynamic_resources中引用這個cluster。可以動態下發的配置主要有:CDS、LDS、EDS、RDS、SDS,其中只有CDS和LDS的發現地址是在dynamic_resources中指定的。

配置文件中使用同樣ID和Cluster的envoy才會接受這個控制平面下發的配置。

基於文件方式

基於文件的方式需要在envoy容器中指定xDS的配置文件路徑,envoy將使用inotify來監視文件系統的更改,並在更新時解析文件中的DiscoveryResponse原型。

node:
  id: id_1
  cluster: test

dynamic_resources:
  cds_config:
    path: /var/lib/envoy/cds.yaml
  lds_config:
    path: /var/lib/envoy/lds.yaml

admin:
  access_log_path: "/dev/null"
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 19000

其中cds_config和las_config內容和靜態配置方式內容一樣:

#cds內容
resources:
- "@type": type.googleapis.com/envoy.config.cluster.v3.Cluster
  name: example_proxy_cluster
  connect_timeout: 1s
  type: strict_dns
  http2_protocol_options: {}
  load_assignment:
    cluster_name: example_proxy_cluster
    endpoints:
    - lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address: service1
              port_value: 8080
 -----
 
 
 #lds內容
 resources:
- "@type": type.googleapis.com/envoy.config.listener.v3.Listener
  name: listener_0
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 10001
  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
        http_filters:
        - name: envoy.router
        route_config:
          name: local_route
          virtual_hosts:
          - name: local_service
            domains:
            - "*"
            routes:
            - match:
                prefix: "/"
              route:
                cluster: example_proxy_cluster

使用這種方式,雖說可以動態修改envoy路由,但仍需要手動更改xds配置文件,並且每次修改后需要重新啟動envoy才能刷新。

基於控制平面方式

用XDS下發配置

首先在配置文件中靜態配置控制平面的地址,然后在cds_config和lds_config中引用前面配置的xds_cluster。

dynamic_resources:
  cds_config:
    api_config_source:
      api_type: GRPC
      grpc_services:
        envoy_grpc:
          cluster_name: xds_cluster
  lds_config:
    api_config_source:
      api_type: GRPC
      grpc_services:
        envoy_grpc:
          cluster_name: xds_cluster

用ADS下發配置

Cds_config和las_config是分開的,這意味着cluster和listener配置可以從不同的控制平面獲取,這樣會遇到配置不同步的問題,即時他們用的是同一個控制平面也可能因為到達次序不同而不同步。譬如 listenerA 中使用了 clusterA,但是 listenerA 的配置可能在 clusterA 之前下發到 envoy ,使 envoy 認為 listenerA 使用了一個不存在的 clusterA。

ADS 支持所有類型動態配置的下發,並且會處理配置間的依賴,保證配置的下發順序,是優先選用的配置發現方法,實現原理見配置下發協議的說明 xDS REST and gRPC protocol

node:
  cluster: test-cluster
  id: test-id

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

static_resources:
  clusters:
  - connect_timeout: 1s
    type: strict_dns
    http2_protocol_options: {}
    name: xds_cluster
    load_assignment:
      cluster_name: xds_cluster
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: go-control-plane
                port_value: 18000

admin:
  access_log_path: /dev/null
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 19000

envoy 的 lds/cds/rds/sds/eds

dynamic_resources 配置中只有 lds_configcds_configads_config,分別對應 listenter、cluster 和聚合發現。但可以動態下發的配置不只有 listener 和 cluster。

cluster 中的 endpoint、tls 用到的 secret、HttpConnectionManager 中用到 route 也可以動態下發,對應的發現服務分別是 edssdsrds。這些發現服務不在 dynamic_resources 中配置,而是獨立配置或者在用到它們的 filter 中配置。

控制平面實現

Go-control-plane的基本用法

go-control-plane 是一個框架,提供了配置下發接口,在它的基礎上根據自己的需要開發其它功能。

動態配置是關聯到 envoy 的 ,每個 envoy 的動態配置都要單獨維護。

在 envoy 的配置文件中有一段 node 配置,標注了當前 envoy 所屬的 cluster 和 id,envoy 只接受使用同樣的 cluster 和 id 的動態配置,使用 go-control-plane 實現的控制平面要為每個 envoy 實例維護一份配置:

node := &core.Node{
    Id:      "envoy-64.58",
    Cluster: "test",
}

node_config := &NodeConfig{
    node:      node,
    endpoints: []cache.Resource{}, //[]*api_v2.ClusterLoadAssignment
    clusters:  []cache.Resource{}, //[]*api_v2.Cluster
    routes:    []cache.Resource{}, //[]*api_v2.RouteConfiguration
    listeners: []cache.Resource{}, //[]*api_v2.Listener
}

Go-control-plane中filter定義與下發

Listener是envoy中最復雜的配置,其中filter又是Listerner中最繁瑣的。從 socket 中收取的請求先經過 listener_filters 處理,然后再由 filter_chains 處理,前者包含的 filter 稱為 listener filter,后者包含的 filter 稱為 network filter。因為 listener_filters 先起作用,因此它可以修改請求的信息,從而影響 filter_chains 的匹配。filter一共有以下幾大類:

Listener filters
Network filters
HTTP filters
Thrift filters
Common access log types
Common fault injection types
Dubbo filters

Filter 是填充在 listener 中作為 listener 配置下發的,listener 在 go-control-plane/envoy/api/v2/lds.pb.go中定義,filter 的接口在 envoy/api/v2/listener/listener.pb.go 中定義,filter 的實現在 go-control-plane/envoy/config/filter/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM