服务网格(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。