服务网格(Service Mesh)是微服务的基础架构,它是微服务的通信层。每个服务都有自己的Sidecar(代理服务),服务实例直接不会直接互相调用,每个往返于服务之间的请求都经过Sidecar。假如服务A要调用服务B,它不会直接调用目标服务,而是由服务A先将请求路由到本地代理,再由本地代理将请求路由到目标服务,所有的代理服务组合在一起,就形成了服务网格。
1
2
3
4
ProxyA---------->ProxyB
↑ ↑
| ↓
ServiceA ServiceB
Envoy可作为服务网格中边缘代理的一个选择,但不是唯一的选择,类似的产品还有nginx、Traefik等。
Envoy还提供了负载均衡、服务发现、限流、熔断、分布式追踪、认证等功能,可以避免将这些功能耦合到业务代码中,。
Envoy中的术语
- Host: 进行网络通信的实体。
- Downstream: 连接到Envoy的下游主机,发送请求并接收响应。
- Upstream:上游主机,接受来自Envoy的连接与请求并返回响应。
- Listener:可被下游客户端连接的网络,如端口、unix套接字。
- Cluster:Envoy连接的上游主机集群。
- XDS:即 * Discovery Service, 提供动态配置的API接口,如
- EDS(Endpoint Discovery Service) 发现upstream服务
- CDS(Cluster Discovery Service) 发现upstream cluster,可动态更新cluster
- RDS(Route Discovery Service) 发现路由规则
- VHDS(Virtual Host Discovery Service) 发现虚拟主机
- LDS(Listener Discovery Service) 发现动态的Listener配置,含所有filter配置
- SDS(Secret Discovery Service) 发现listener上配置的秘钥,如证书私钥等
- SRDS(Scoped Route Discovery Service) 将route table切分为几个小块。
- RTDS(RunTime Discovery Service)
- ECDS(Extension Config Discovery Service)
- ADS(Aggregated Discovery Service) 即将CDS/EDS/LDS/RDS等动态配置聚合为一个ADS
启动Envoy
Envoy 通过指定 -c 参数指定配置文件,Envoy的配置分为两种:静态配置和动态配置。
- 静态配置: 所有的信息都放在配置文件中,配置指定该Envoy进程属于哪个cluster,在启动时加载。
- 动态配置:配置XDS,然后通过一个Envoy的服务端动态提供Envoy需要的服务发现接口。
启动:
1
envoy -c envoy.yaml
静态配置
envoy-static.yaml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
admin: # 管理端
access_log_path: /var/log/envoy/envoy_admin_access.log
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }
static_resources: # 静态配置
listeners:
- name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 10000 } # 监听端口
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: ingress_http
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/" } # 路由匹配规则
route: { cluster: some_service } # 路由到的服务集群
http_filters:
- name: envoy.filters.http.router
clusters:
- name: some_service
connect_timeout: 0.25s
type: STATIC
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: some_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 172.16.10.13 # 直接指定后端服务
port_value: 3000
Envoy启动后,就可以通过Envoy的10000端口访问到后端 172.16.10.13:3000 提供的服务。
动态配置
动态配置是通过一个 EDS(Endpoint Dicovery Service) 服务动态提供服务发现。ADS则聚合了EDS、CDS、LDS等。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
node:
cluster: test-cluster
id: test-id
dynamic_resources: # 动态配置
ads_config: # ADS聚合
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
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicit_http_config:
http2_protocol_options: {}
name: xds_cluster
load_assignment:
cluster_name: xds_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 172.16.10.15 # EDS服务
port_value: 18000
admin:
access_log_path: /var/log/envoy/envoy_admin_access.log
address:
socket_address:
address: 0.0.0.0
port_value: 19000
然后再使用 go-control-plane 提供XDS服务。go-control-plane 是Envoy提供的开发库,基于它可以方便的实现基于gRPC协议的服务发现,XDS在协程中接收并处理来自Envoy的gRPC请求。这样XDS通过一系列的gRPC接口实现了为Envoy动态提供配置的功能。
代码有点多,就不帖这里了,可到github查看: Demo。