envoy

Envoy

envoy:是一个7层代理和L3/L4的服务总线,使用c++编写,envoy 单进程,多线程。

envoy 提供了服务网格的数据平面,istio 使用了envoy作为数据平面【istio-proxy】,自身又实现了服务网格的控制平面。

配置文件语法测试

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
flowchart LR subgraph routes subgraph redirect AA[schema_redirect] BB[host_redirect] CC[port_redirect] DD[path_redirect] EE[prefix_redirect] end subgraph direct_response FF[status & body] end subgraph route GG[cluster] HH[weighted_cluser] II[cluster_head] JJ[timeout] KK[retry_policy] LL[rate_limits] MM[prefix_rewrite] NN[host_rewirte] end end subgraph match subgraph A[prefix] B[path] C[safe_regex] end subgraph D[headers] E[request_parameters] end end match ==> redirect match ==> direct_response match ==> 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"  #请求必须完全匹配 http://127.0.0.1/static
  route:
    cluster: version1.0
  • route_config.routes[0].match.safe_regex
routes:
- match:
    safe_regex:
      goole_re2: {}
      regex: "^list/[0-9]{,2}$" # http://127.0.0.1/list/1
  route:
    cluster: version1.0
  • route_config.routes[0].match.headers
routes:
- match:
    prefix: "/"
    headers:
      name: User-Agent
      exact_macth: "chrome"  # curl -H "User-Agent: Chrome" http://127.0.0.1
  route:
    cluster: version1.0
  • route_config.routes[0].match.request_parameters
routes:
- match:
    prefix: "/"
    request_parameters:
      name: name
      exact: "AAA"  # curl http://127.0.0.1/search?name=AAA
  route:
    cluster: version1.0
路由规则匹配
  • route_config.routes[0].route.cluster
routes:
- match:
    prefix: "/"
  route:
    cluster: version1.0
  • route_config.routes[0].route.weighted_clusters
routes:
- match:
    prefix: "/"
  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: "/"
  redirect:
    https_redirect: true
    port_redirect: 443
    host_redirect: "www.baidu.com"
    prefix_redirect: "/s?wd=news"
  • route_config.routes[0].response
routes:
- match:
    prefix: "/"
  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

  1. 客户端验证服务端证书
  2. 客户端验证服务端证书,服务端验证客户端证书
# 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=test.wed.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"
}
posted @ 2022-07-26 18:41  mingtian是吧  阅读(456)  评论(0编辑  收藏  举报