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: |
| 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: / |
| route: |
| cluster: mycluster |
路由规则定义
- 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: "/" |
| headers: |
| name: User-Agent |
| exact_macth: "chrome" |
| route: |
| cluster: version1.0 |
- route_config.routes[0].match.request_parameters
| routes: |
| - match: |
| prefix: "/" |
| request_parameters: |
| name: name |
| exact: "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" |
| |
| |
流量迁移
| 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 |
| 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 |
| 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 |
限速
超时和重试
| route_config: |
| name: local_route |
| vitual_hosts: |
| - name: local_service |
| domains: ["*"] |
| routes: |
| - match: |
| prefix: "/" |
| route: |
| cluster: version1.0 |
| timeout: 1s |
| retry_policy: |
| retry_on: "5xx" |
| num_retries: 3 |
cluster
| clusters: |
| - name: mycluster |
| alt_stat_name: mycluster |
| connect_timeout: 1s |
| lb_policy: ROUND_ROBIN |
| type: STATIC |
| load_assignment: |
| cluster_name: mycluster |
| endpoints: |
| - lb_endpoints: |
| - endpoint: |
| address: |
| socket_address: |
| address: 0.0.0.0 |
| port_value: 80 |
调度策略
| 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 |
| 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 |
| route_config: |
| name: local_route |
| virtual_hosts: |
| - name: local_server |
| domains: ["*"] |
| routes: |
| - match: |
| prefix: "/" |
| route: |
| cluster: mycluster |
| hash_policy: |
| header: |
| header_name: User-Agent |
| |
| |
| |
| |
| connection_properties: |
| source_ip: true |
| |
| |
| |
| |
| 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 |
基于位置权重
| 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 |
| 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 |
| |
| 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 |
| 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: |
| path: / |
| expected_statuses: |
| start: 200 |
| end: 399 |
outlier_detection
| 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: 0.0.0.0 |
| port_value: 80 |
| outlier_detection: |
| .... |
断路器
| clusters: |
| circuit_breakers: |
| - thresholds: |
| max_connectons: 1 |
| max_pending_requests: 1 |
| max_retires: 3 |
tls
- 客户端验证服务端证书
- 客户端验证服务端证书,服务端验证客户端证书
| |
| |
| |
| 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" |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏