天天看點

envoy

Envoy

目錄

  • Envoy
    • BootStrap 配置檔案
      • admin
      • node
      • layered_rumtime
      • static_resources
        • echo
        • tcp_proxy
        • http_connection_manager
          • route
            • 路由規則定義
            • 路由規則比對
            • 流量遷移
            • 流量分割
            • 流量鏡像
            • 故障注入
            • 限速
            • 逾時和重試
          • cluster
            • 排程政策
            • 基于位置權重
            • 基于位置priority
            • 超配因子
            • 叢集子集
            • 主動健康檢查和異常值檢測
            • 斷路器
        • tls
        • 日志

envoy:是一個7層代理和L3/L4的服務總線,使用c++編寫,envoy 單程序,多線程。

envoy 提供了服務網格的資料平面,istio 使用了envoy作為資料平面,自生又實作了服務網格的控制平面。

配置檔案文法測試

envoy --mode validate -c envoy.yaml

BootStrap 配置檔案

admin

位置:頂級配置段

/ready envoy的健康狀态

/certs envoy 已加載的證書

/listeners envoy 已監聽的監聽器

admin:
  address:
    socket_address:
      address: 127.0.0.1
      port_value: 9901
           

node

位置:頂級配置段
node: # 使用xds動态配置服務時 node資訊必須配置
  id: test-01
  cluster: test
           

layered_rumtime

位置:頂級配置段
layered_runtime:
  layers:
  - name admin
    admin_layer: {}
           

static_resources

位置:頂級配置段

echo

static_resources:
  listeners:
  - name: listener_0
      address:
        socket_address: { address: 0.0.0.0, port_value: 80 }
    filter_chains:
    - filters:
      - name: envoy.filters.network.echo
           
使用方式: nc 101.43.43.9 9999
           

tcp_proxy

位置: static_resources
static_resources:
  listeners:
  - name: listener_0
      address:
        socket_address: { address: 0.0.0.0, port_value: 80 }
    filter_chains:
    - filters:
      - name: envoy.filters.network.tcp_proxy
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
          stat_prefix: tcp
          cluster: local_cluster
           

http_connection_manager

位置: static_resources
static_resources:
  listeners:
  - name: listener_0
      address:
        socket_address: { address: 0.0.0.0, port_value: 80 }
    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
          stat_prefix: http
          codec_type: AUTO
          route_config:
            name: local_route
            virtual_hosts:
            - name: loacl_service
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: mycluster
          http_filters:
            name: envoy.filtes.http.router
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
           
route
route_config:
  name: local_route
  virtual_hosts:
  - name: local_service
    domains: ["*"]
    routes:
    - match:
        prefix: /	# prefix 、path 、safe_regex 、headers、request_parameters
      route:
        cluster: mycluster  # cluster redirect direct_response weighted_cluster
           

路由規則定義

  • route_config.routes[0].match.prefix
routes:
- match:
    prefix: "/login" # 字尾比對
  route:
    cluster: version1.0
           
  • route_config.routes[0].match.path
routes:
- match:
    path: "/static"  #請求必須完全比對
  route:
    cluster: version1.0
           
  • route_config.routes[0].match.safe_regex
routes:
- match:
    safe_regex:
      goole_re2: {}
      regex: "^list/[0-9]{,2}$"
  route:
    cluster: version1.0
           
  • route_config.routes[0].match.headers
routes:
- match:
    prefix: "/login" # 字尾比對
    headers:
      name: User-Agent
      exact_macth: "chrome"
  route:
    cluster: version1.0
           
  • route_config.routes[0].match.request_parameters
routes:
- match:
    prefix: "/login" # 字尾比對
    request_parameters:
      name: name
      exact: "AAA"
  route:
    cluster: version1.0
           

路由規則比對

  • route_config.routes[0].route.cluster
routes:
- match:
    prefix: "/login" # 字尾比對
  route:
    cluster: version1.0
           
  • route_config.routes[0].route.weighted_clusters
routes:
- match:
    prefix: "/login" # 字尾比對
  route:
    weighted_clusters:
      clusters:
      - name: version1.0
        weight: 10
      - name: version2.0
        weight: 90
      total_weight: 100
      runtime_key_prefix: weight_cluster
           
  • route_config.routes[0].redirect
routes:
- match:
    prefix: "/login" # 字尾比對
  redirect:
    https_redirect: true
    port_redirect: 443
    host_redirect: "www.baidu.com"
    prefix_redirect: "/search"
           
  • route_config.routes[0].response
routes:
- match:
    prefix: "/login" # 字尾比對
  resopnse:
    status: 200
    body:
      inline_string: "hello world"
      #filename: /tmp/filename.txt
      #inline_bytes: "b'hellp world'"  
           

流量遷移

route_config:
  name: local_route
  virtual_hosts:
  - name: local_service
    domains: ["*"]
    routes:
    - match:
        prefix: /
        runtime_fraction:
          default_value:
            numerator: 100
            denominator: HUNDER
          runtime_key: traffic_shift
      route:
        cluster: mycluster_v1
    - match:
        prefix: /
      route:
        cluster: mycluster_v2
           

流量分割

route_config:
  name: local_route
  virtual_hosts:
  - name: local_service
    domains: ["*"]
    routes:
    - match:
        prefix: /
      route:
        weighted_cluster:
          clusters:
          - name: mycluster_v1
            weight: 10
          - name: mycluster_v2
            weight: 90
          total_weight: 100
          runtime_key_prefix: routing.traffic_split.demoapp
           

流量鏡像

route_config:
  name: local_route
  virtual_hosts:
  - name: local_service
    domains: ["*"]
    routes:
    - match:
        prefix: /
      route:
        cluster: version1.0
        request_mirrors_polices:
          cluster: version2.0
          runtime_fracton:
            default_value:
              numerator: 10
              denominator: HUNDRED
            runtime_key: traffic_mirrors
           

故障注入

route_config:
  name: local_route
  virtual_hosts:
  - name: local_service
    domains: ["*"]
    routes:
    - match: 
        perfix: "/"
      route:
        cluster: version1.0
http_filters:
- name: envoy.filters.http.fault
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault
    max_active_faults: 100
    abort:
      http_status: 503
      header_abort: {}
      percentage:
        numerator: 10
        denominator: HUNDRED #10% 的流量傳回 5xx
           
route_config:
  name: local_route
  virtual_hosts:
  - name: local_service
    domains: ["*"]
    routes:
    - match: 
        perfix: "/"
      route:
        cluster: version1.0
http_filters:
- name: envoy.filters.http.fault
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault
    max_active_faults: 100
    delay:
      header_delay: {}
      percentage:
        numerator: 100 #100% 的流量進行延遲
           
route_config:
  name: local_route
  virtual_hosts:
  - name: local_service
    domains: ["*"]
    routes:
    - match: 
        perfix: "/"
      route:
        cluster: version1.0
http_filters:
- name: envoy.filters.http.fault
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault
    max_active_faults: 100
    response_rate_limit:
      header_limit: {}
      percentage:
        numerator: 100  #100% 的流量進行限制
           

限速

逾時和重試

route_config:
  name: local_route
  vitual_hosts:
  - name: local_service
    domains: ["*"]
    routes:
    - match:
        prefix: "/"
      route:
        cluster: version1.0
        timeout: 1s  # 連接配接cluster逾時時長1s
        retry_policy:
          retry_on: "5xx"
          num_retries: 3
           
cluster
clusters:
- name: mycluster  #叢集的唯一名稱,當為提供alt_stat_name時該名稱被引用到統計資訊中
  alt_stat_name: mycluster # 統計資訊中标記該叢集
  connect_timeout: 1s
  lb_policy: ROUND_ROBIN # least_request  ring_hash random maglev cluster_provided
  type: STATIC # strict_dns  logical_dns  ends
  load_assignment:
    cluster_name: mycluster
    endpoints:
    - lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address: 0.0.0.0
              port_value: 80
           

排程政策

  • wrr
clusters:
- name: mycluster
  connect_timeout: 1s
  lb_policy: ROUND_ROBIN
  type: STATIC
  load_assignment:
    cluster_name: mycluster
    endpoints:
    - lb_endpoints:
      - endpoint:
          address: 
            socket_address:
              address: 127.0.0.1
              port_value: 80
        load_balacing_weight: 10
    - lb_endpoints:
      - endpoint:
          address: 
            socket_address:
              address: 127.0.0.1
              port_value: 8080
        load_balacing_weight: 90
           
  • wlr
clusters:
- name: mycluster
  connect_timeout: 1s
  lb_policy: LEAST_REQUEST
  least_request_lb_config:
    choice_count: 2
  type: STATIC
  load_assignment:
    cluster_name: mycluster
    endpoints:
    - lb_endpoints:
      - endpoint:
          address: 
            socket_address:
              address: 127.0.0.1
              port_value: 80
        load_balacing_weight: 10
    - lb_endpoints:
      - endpoint:
          address: 
            socket_address:
              address: 127.0.0.1
              port_value: 8080
        load_balacing_weight: 90
           
  • ring_hash
route_config:
  name: local_route
  virtual_hosts:
  - name: local_server
    domains: ["*"]
    routes:
    - match:
        prefix: "/"
      route:
        cluster: mycluster
        hash_policy:
          header:
            header_name: User-Agent
#          cookie:
#            name:
#            ttl:
#            path: 
          connection_properties:
            source_ip: true
#          query_parameter:
#            name:
#          filter_state:
          # 第一個條件比對時終止hash_policy
          terminal: true

clusters:
- name: mycluster
  connect_timeout: 1s
  lb_policy: RING_HASH
  ring_hash_lb_config:
    maximum_ring_size: 65535
    minimum_ring_szie: 512
  type: STATIC
  load_assignment:
    cluster_name: mycluster
    endpoints:
    - lb_endpoints:
      - endpoint:
          address: 
            socket_address:
              address: 127.0.0.1
              port_value: 80
        load_balacing_weight: 10
    - lb_endpoints:
      - endpoint:
          address: 
            socket_address:
              address: 127.0.0.1
              port_value: 8080
        load_balacing_weight: 90
           
  • maglev
  • random

基于位置權重

static_resources:
  clusters:
    name: mycluster
	connect_timeout: 1s
	lb_policy: ROUND_ROBIN
	type: STATIC
	load_assignment:
	  cluster_name: mycluster
	  endpoints:
	  - locality:
	      region: cn-north-01
		load_balancing_weight: 1
        lb_endpoints:
        - endpoint:
            address:
              socket_address: { address: 172.4.88.2, port_value: 80 }
        - endpoint:
            address:
              socket_address: { address: 172.4.88.3, port_value: 80 }
	  - locality:
	      region: cn-north-02
		load_balancing_weight: 2
        lb_endpoints:
        - endpoint:
            address:
              socket_address: { address: 172.4.88.4, port_value: 80 }
        - endpoint:
            address:
              socket_address: { address: 172.4.88.5, port_value: 80 }
           

基于位置priority

clusters:
  name: mycluster
  connect_timeout: 1s
  lb_policy: ROUND_ROBIN
  type: STATIC
  load_assignment:
    cluster_name: mycluster
    endpoints:
    - locality:
        region: cn-north-01
      priority: 0 # 0 表示最進階别
      lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address:
              port_value:
    - locality:
        region: cn-north-02
      priority: 1 # 預設不會向這個節點排程
      lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address:
              port_value:
           

超配因子

static_resources:
  clusters:
    name: mycluster
	connect_timeout: 1s
	lb_policy: ROUND_ROBIN
	type: STATIC
	load_assignment:
	  cluster_name: mycluster
	  
	  #######################################################
	  policy:
	     overprovisioning_factor: 140 # 預設值 140
	  #######################################################
	  endpoints:
	  - locality:
	      region: cn-north-01
		priority: 0
		load_balancing_weight: 1
        lb_endpoints:
        - endpoint:
            address:
              socket_address: { address: 172.4.88.2, port_value: 80 }
        - endpoint:
            address:
              socket_address: { address: 172.4.88.3, port_value: 80 }
	  - locality:
	      region: cn-north-02
		priority: 1
		load_balancing_weight: 2
        lb_endpoints:
        - endpoint:
            address:
              socket_address: { address: 172.4.88.4, port_value: 80 }
        - endpoint:
            address:
              socket_address: { address: 172.4.88.5, port_value: 80 }
           

叢集子集

clusters:
  name: mycluster
  connect_timeout: 1s
  lb_policy: LEAST_REQUEST
  type: STATIC
  least_request_lb_config:
    choice_count: 2
  load_assignment:
    cluster_name: mycluster
    policy:
      overprovisioning_factor: 140
    endpoints:
    - locality:
        region: cn-north-01
      priority: 0

      lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address: 127.0.0.1
              port_value: 80
          metadata:
            filter_metadata:
              envoy.lb:
                version: "1.0"
                stag: "dev"
      lb_subset_config:
        fallback_policy: DEFAULT_SUBSET
        default_subset:
          version: "1.0"
          stag: "dev"
        subset_selectors:
          - keys: ["stage", "version"]
          - keys: ["stage"]
          - keys: ["version"]          
           

主動健康檢查和異常值檢測

clusters:
- name: mycluster
  connect_timeout: 1s
  lb_policy: ROUND_ROBIN
  type: STATIC # strict_dns  logical_dns  ends
  load_assignment:
    cluster_name: mycluster
    endpoints:
    - lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address: 0.0.0.0
              port_value: 80
    health_checks:
    - timeout: 1s
      interval: 5s
      health_threshold: 2
      unhealth_threshold: 2
      http_health_check:	# tcp_health_check: {} 空負載的tcp檢測
        path: /
        expected_statuses:
          start: 200
          end: 399
           

outlier_detection

clusters:
- name: mycluster
  connect_timeout: 1s
  lb_policy: ROUND_ROBIN
  type: STATIC # strict_dns  logical_dns  ends
  load_assignment:
    cluster_name: mycluster
    endpoints:
    - lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address: 0.0.0.0
              port_value: 80
        outlier_detection:
          ....
           

斷路器

clusters:
  circuit_breakers:
  - thresholds:
      max_connectons: 1
      max_pending_requests: 1
      max_retires: 3
           

tls

# The following self-signed certificate pair is generated using:
# $ openssl req -x509 -newkey rsa:2048 -keyout front-proxy.key -out front-proxy.crt -days 3650 -nodes -subj '/CN=www.magedu.com'
transport_socket:
  name: envoy.transport_sockets.tls
  typed_config: 
    "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
    common_tls_context:
      tls_certificates:
      - certificate_chain:
          filename: "/etc/envoy/certs/front-proxy.crt"
        private_key:
          filename: "/etc/envoy/certs/front-proxy.key“
           

日志

# 日志
access_log:
  name: envoy.access_loggers.file
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.access_loggers.v3.FileAccessLog
	path: "/dev/stdout"
	log_format:
	  json_format: {"start": "[%START_TIME%] ", "method": "%REQ(:METHOD)%", "url": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%", "protocol": "%PROTOCOL%", "status": "%RESPONSE_CODE%", "respflags": "%RESPONSE_FLAGS%", "bytes-received": "%BYTES_RECEIVED%", "bytes-sent": "%BYTES_SENT%", "duration": "%DURATION%", "upstream-service-time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%", "x-forwarded-for": "%REQ(X-FORWARDED-FOR)%", "user-agent": "%REQ(USER-AGENT)%", "request-id": "%REQ(X-REQUEST-ID)%", "authority": "%REQ(:AUTHORITY)%", "upstream-host": "%UPSTREAM_HOST%", "remote-ip": "%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%"}
           

産生的日志格式

{
    "respflags":"-",
    "start":"[2022-08-16T06:22:14.549Z] ",
    "request-id":"94f1f61e-906e-4025-aea1-8e59f11bbf0f",
    "authority":"101.43.43.9:5000",
    "upstream-host":"172.31.4.3:5000",
    "method":"GET",
    "upstream-service-time":"1",
    "remote-ip":"113.97.31.62",
    "status":200,
    "bytes-received":0,
    "x-forwarded-for":null,
    "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.81 Safari/537.36 Edg/104.0.1293.47",
    "url":"/",
    "duration":2,
    "bytes-sent":113,
    "protocol":"HTTP/1.1"
}
           
上一篇: tracing
下一篇: 監控ceph