2 分钟把握 Envoy 的脉络,适应新场景的 envoy 有哪些不同?能做什么?

作者:李佶澳  更新时间:2019-09-08T14:39:02+0800

  项目    envoy    刷新

本篇目录

说明

在梳理开源的 API 网关和 ServiceMesh 项目时,最常遇到的一个词是 Envoy,Ambassador、Contour、Gloo、Istio 等项目的数据平面都选用了 Envoy。Envoy 何德何能受到众多项目的青睐? 掌握 Envoy 的脉络只需 2 分钟。

响应了时代号召的 Envoy

Envoy 是一个具有反向代理和负载均衡功能的单机软件,和 Nginx、Haproxy 属于同一类软件。与 Nginx 和 Haproxy 相比,Envoy 有一个的重要特色是:自带配置 API

以 Nginx、Haproxy 为代表的负载均衡软件,在过去很多年的实际应用中,很少会在软件运行的时候更改配置,即使偶尔要修改配置文件,使用 reload 等命令重新加载就能满足需要。

以 Kubernetes 为代表的 PaaS 或者容器管理系统出现后,IT 系统沿着“分工专业化、更少的人做更多同质事情”的路线演进,在当前的演进过程中,反向代理与负载均衡的能力被集中管理、统一提供。

这一演进在 Kubernetes 中体现为作为集群出口的 ingress 代理集群内所有服务,在以 istio 为代表的 ServiceMesh 中体现为分散在各处的代理软件在同一个中心的控制下流转流量。 无论是作为 Kubernetes 的出口,还是作为 Mesh 中的一个节点,承担流量转发功能的组件都需要完成一个挑战: 在运行过程中频繁的更新配置

新场景中的更新的频率是每秒 N 次,远远超过以往的场景中以周、月乃至年为周期的更新频率。这种情形下,热加载配置文件的方式明显迟缓笨重,有一些项目通过开发一个带有 API 功能的组件,实现生成配置文件、触发热加载的功能,以此赋予 Nginx、Haproxy 等传统负载均衡软件高频更新配置的能力。

但是,如果有一个软件原生带有配置 API,且专注于数据平面,它作为可靠的第三方存在,能够让控制平面专心于规则管理,那么它是不是会很受欢迎呢?

Envoy 就是这样一款软件。注意,这里只是在交代背景,不为 envoy 吹票,nginx、haproxy 等都在更新演进以适应场景的变化。

Cluster、Listener 与 Filter

Envoy 的功能和使用细节繁杂,但只要搞清楚了 Cluster、Listener 和 Filter 的用途,就把握住了大方向。

Cluster 就是一组 IP,相当于 Nginx 中 upstream,负载均衡策略在 cluster 中设置,cluster 中可以是 IP 也可以是域名:

envoy的cluster

Listener 就是监听地址和转发规则:

envoy的listener

难啃的配置文件

Envoy 的配置文件是从零开始了解 Envoy 时遇到的最大困难,它的配置比较繁杂,而且缺少系统的介绍。

配置文件在 envoy 启动时,用 -c 指定,内容分为以下几个部分:

{
  "node": {
    "id": "...",
    "cluster": "...",
    "metadata": "{...}",
    "locality": "{...}",
    "build_version": "..."
  },
  "static_resources": {
    "listeners": [],
    "clusters": [],
    "secrets": []
  },
  "dynamic_resources": {
    "lds_config": "{...}",
    "cds_config": "{...}",
    "ads_config": "{...}"
  },
  "cluster_manager": {
    "local_cluster_name": "...",
    "outlier_detection": "{...}",
    "upstream_bind_config": "{...}",
    "load_stats_config": "{...}"
  },
  "hds_config": {
    "api_type": "...",
    "cluster_names": [],
    "grpc_services": [],
    "refresh_delay": "{...}",
    "request_timeout": "{...}",
    "rate_limit_settings": "{...}"
  },
  "flags_path": "...",
  "stats_sinks": [
    {
      "name": "...",
      "config": "{...}"
    }
  ],
  "stats_config": {
    "stats_tags": [],
    "use_all_default_tags": "{...}",
    "stats_matcher": "{...}"
  },
  "stats_flush_interval": "{...}",
  "watchdog": {
    "miss_timeout": "{...}",
    "megamiss_timeout": "{...}",
    "kill_timeout": "{...}",
    "multikill_timeout": "{...}"
  },
  "tracing": {
    "http": "{...}"
  },
  "rate_limit_service": {
    "grpc_service": "{...}"
  },
  "runtime": {
    "symlink_root": "...",
    "subdirectory": "...",
    "override_subdirectory": "..."
  },
  "admin": {
    "access_log_path": "...",
    "profile_path": "...",
    "address": "{...}"
  },
  "overload_manager": {
    "refresh_interval": "{...}",
    "resource_monitors": [],
    "actions": []
  }
}

查看 envoy 容器中的默认配置文件,有助于建立感性认识,内容如下:

admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
      protocol: TCP
      address: 127.0.0.1
      port_value: 9901
static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        protocol: TCP
        address: 0.0.0.0
        port_value: 10000
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                route:
                  host_rewrite: www.google.com
                  cluster: service_google
          http_filters:
          - name: envoy.router
  clusters:
  - name: service_google
    connect_timeout: 0.25s
    type: LOGICAL_DNS
    # Comment out the following line to test on v6 networks
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: service_google
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: www.google.com
                port_value: 443
    tls_context:
      sni: www.google.com

掌握 envoy 的配置文件,是把握住这款软件的关键一步,如何才能掌握 envoy 的配置呢?把它所有的配置细节记住当然算是掌握了,但是大多数时候我们并不需要如此,只需要知道实时反应配置文件全部细节的文档在哪里就足够了,剩下的交给时间和好奇心:

envoy的配置文件详解

挑大梁的 filter

几乎可以这样说,在实际应用中最常提及的 envoy 功能都是 filter 提供的, filter 是流量在 envoy 内流转时经历的一个又一个处理环节,每个环节都会解读一些信息、作出一些判断,影响下一个环节的处理。

Cluster 和 Listener 中都有 filter 的位置,有的 filter 比较复杂还实现了 子 filter,例如专门处理 http 协议的 HttpConnectionManager。 Filter 的数量实在太多,知道到哪里找到所有 filter 的说明和配置方法比记住个别 filter 的用法更重要:

envoy listener filter

envoy network filter

这些 filter 的名称很好的展示了 envoy 能够做的事情,http、thrift、dubbo、zookeeper、mysql、mongo、redis,看起来是不是挺诱人的?

动态配置到底怎么回事?

envoy 的一大卖点就是自带配置 API,但要把它自带的 API 用起来还挺周折。envoy 率先提出使用统一的 data-plane-api ,定义了一套 API 标准,并期待能够得到广泛的认同和采纳,从新起的 Api 网关和 ServiceMesh 开源项目的选择来看,这一策略是有效的。

date-plane-api

go-controller-plane 是 envoy 提出的 data-plane-api 的 go 语言实现,可以用它向 envoy 下发配置,这个库的使用方法三言两语说不清楚,先弄清楚下面三个项目的关系: envoy 就是单机软件 envoy,data-plane-api 是 API 接口标准,go-control-plane 是 API 接口标准的实现。

envoy network filter

动手实践一下

自带配置 API 支持动态更新,Cluster、Listener、Filter 构成了 Envoy 的功能骨架,如果看完上面的介绍,依旧感觉朦朦胧胧如雾里看花,想要看的更清楚一些,没有比照敲一遍 Envoy 使用手册 中的操作更快捷的方法了:

点击查看Envoy 使用手册

envoy 使用手册

参考

  1. 李佶澳的博客
  2. Envoy 使用手册

站长微信(朋友圈有精华,一般不闲聊)

推荐阅读

Copyright @2011-2019 All rights reserved. 转载请添加原文连接,合作请加微信lijiaocn或者发送邮件: [email protected],备注网站合作

友情链接:  李佶澳的博客  小鸟笔记  软件手册  编程手册  运营手册  爱马影视  网络课程  奇技淫巧  课程文档  精选文章  发现知识星球  百度搜索 谷歌搜索