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