Envoy 基础教程:入门篇


在你的笔记本上运行 Envoy

Envoy 基础教程:入门篇

在你的笔记本上运行 Envoy

  • Kubernetes 知识图谱
  • 云原生导航
  • 谷歌搜索
  • Raft 协议动画演示
  • 搬瓦工

    1. 前言


    过去一年中,Kubernetes 已经赢得了容器编排大战,如果说 2017 年是 Kubernetes 的元年,那么 2018 将会是 Service Mesh(服务网格) 的元年,在未来两年中,Service Mesh 将迎来爆发式增长,成为下一代的微服务架构。

    Istio 作为 Service Mesh 新秀,初出茅庐便声势浩荡,前有 Google,IBM 和 Lyft 倾情奉献,后有业界大佬俯首膜拜。作为一名斜杠青年,如果再不停下脚步认真审视一下这位后起之秀,未免显得太不符合潮流了。

    Istio 这个大家庭的家庭成员很多,为了能够顺利打入 Istio 内部,我们先从它的核心家庭成员 Envoy 入手。

    从今天起,我将带领大家从零开始学习和使用 Envoy,着重于经验分享和总结,同时也会有相关的概念解析,希望能够帮助大家少走弯路,能不采坑尽量不采坑。

    本篇是 Envoy 系列教程的第一篇,介绍如何在笔记本电脑上运行 Envoy、测试代理配置并观察结果,让我们开始吧!

    2. 前提


    你可以选择从源代码构建 Envoy,但最简单的办法是通过 Docker 容器来运行。所以在开始之前,你需要安装并配置以下工具:

    我们使用 Docker 和 Docker Compose 来编排和运行 Envoy 的示例服务,使用 curl 来访问 Envoy 示例服务。

    3. 部署 Envoy


    Envoy 官方提供了一组 Envoy 的用例,我们将要使用的用例是前端代理,它会将流量发送到两个服务后端。首先克隆 Envoy 的代码仓库并转到 examples/front-proxy 目录:

    $ git clone https://github.com/envoyproxy/envoy
    $ cd envoy/examples/front-proxy
    

    后端服务 是一个非常简单的 Flask 应用程序,在 service.py 中定义。其中 Envoy 作为一个边车(Sidecar)伴随每个服务一起运行在同一个容器中,所有的规则配置都通过 YAML 文件 service-envoy.yaml 来完成。最后 Dockerfile-service 创建一个在启动时同时运行服务和 Envoy 的容器。

    前端代理 比后端服务更简单,它使用配置文件 front-envoy.yaml 来运行 Envoy,使用 Dockerfile-frontenvoy 来构建容器镜像。

    docker-compose.yaml 文件描述了如何构建、打包和运行前端代理与服务。

    整体架构如下:

    https://jimmysong.io/kubernetes-handbook/images/envoyproxy-docker-compose.png

    使用 docker-compose 启动容器:

    $ docker-compose up --build -d
    $ docker-compose ps
    
              Name                        Command               State                      Ports
    ----------------------------------------------------------------------------------------------------------------
    frontproxy_front-envoy_1   /bin/sh -c /usr/local/bin/ ...   Up      0.0.0.0:8000->80/tcp, 0.0.0.0:8001->8001/tcp
    frontproxy_service1_1      /bin/sh -c /usr/local/bin/ ...   Up      80/tcp
    frontproxy_service2_1      /bin/sh -c /usr/local/bin/ ...   Up      80/tcp
    

    该命令将会启动一个前端代理和两个服务实例:service1 和 service2。

    3. 配置 Envoy


    为了达到演示的目的,本文采用的是 Envoy 的静态配置。后续教程将会告诉你们如何使用动态配置来发挥 Envoy 的强大功能。

    为了了解 Envoy 是如何配置的,先来看看 docker-compose.yaml 文件的前端代理部分的配置:

      front-envoy:
        build:
          context: ../
          dockerfile: front-proxy/Dockerfile-frontenvoy
        volumes:
          - ./front-envoy.yaml:/etc/front-envoy.yaml
        networks:
          - envoymesh
        expose:
          - "80"
          - "8001"
        ports:
          - "8000:80"
          - "8001:8001"
    

    从上到下做了这么几件事:

    1. 使用位于当前目录中的 Dockerfile-frontenvoy 构建镜像。
    2. front-envoy.yaml 文件作为 /etc/front-envoy.yaml 挂载到容器中的 /etc 目录。
    3. 为这个容器创建并使用名为 envoymesh 的 Docker 网络。
    4. 暴露 80 端口(用于一般通用流量)和 8001 端口(用于管理服务)。
    5. 将主机的 8000 端口和 8001 端口分别映射到容器的 80 端口和 8001 端口。

    前面已经了解到了前端代理使用 front-envoy.yaml 来配置 Envoy,下面来深入解析一下。该配置文件有两大配置项:static_resourcesadmin

    static_resources:
    admin:
    

    admin 配置项的内容非常简单:

    admin:
      access_log_path: "/dev/null"
      address:
        socket_address:
          address: 0.0.0.0
          port_value: 8001
    

    access_log_path 字段的值设置为 /dev/null,意味着 admin 服务的访问日志将会被丢弃,在测试或生产环境中,你最好将这个值修改为不同的目录。socket_address 字段告诉 Envoy 创建一个监听在 8001 端口的 admin 服务。

    static_resources 配置项定义了一组静态配置的集群(Cluster)和侦听器(Listener)。

    集群是 Envoy 连接到的一组逻辑上相似的上游主机。Envoy 通过服务发现发现集群中的成员。Envoy 可以通过主动运行状况检查来确定集群成员的健康状况。Envoy 如何将请求路由到集群成员由负载均衡策略确定。

    侦听器是服务(程序)监听者,就是真正干活的。 它是可以由下游客户端连接的命名网络位置(例如,端口、unix域套接字等)。

    Listener 配置

    该示例中的前端代理有一个监听在 80 端口的侦听器,并配置了一个监听器过滤器链(filter_chains),用来管理 HTTP 流量:

      listeners:
      - address:
          socket_address:
            address: 0.0.0.0
            port_value: 80
        filter_chains:
        - filters:
          - name: envoy.http_connection_manager
            config:
              codec_type: auto
              stat_prefix: ingress_http
              route_config:
                name: local_route
    

    在 HTTP 连接管理过滤器中,每一个虚拟主机都有单独的配置,并且都配置为接收所有域的流量:

                virtual_hosts:
                - name: backend
                  domains:
                  - "*"
                  routes:
                  - match:
                      prefix: "/service/1"
                    route:
                      cluster: service1
                  - match:
                      prefix: "/service/2" 
                    route:
                      cluster: service2
    

    HTTP 路由规则将 /service/1/service/1 的流量转发到各自的 Cluster。

    Cluster 配置

    接下来看一下静态 Cluster 的定义:

      clusters:
      - name: service1
        connect_timeout: 0.25s
        type: strict_dns
        lb_policy: round_robin
        http2_protocol_options: {}
        hosts:
        - socket_address:
            address: service1
            port_value: 80
      - name: service2
        connect_timeout: 0.25s
        type: strict_dns
        lb_policy: round_robin
        http2_protocol_options: {}
        hosts:
        - socket_address:
            address: service2
            port_value: 80
    

    在 Cluster 的配置中,你可以自定义超时、断路器和服务发现等。Cluster 由 Endpoint(端点)组成,其中 Endpoint 是一组可以为 Cluster 的请求提供服务的网络位置。本例中的 Endpoint 是通过 DNS 域名的方式定义的,Envoy 可以从域名中读取 Endpoint。Endpoint 也可以直接定义为 socket 地址,或者通过 EDS(Endpoint Discovery Service)动态读取。

    修改配置

    你可以通过修改配置文件重新构建镜像来进行测试。Listener filter(监听器过滤器)的作用是在不更改 Envoy 的核心功能的情况下添加更多的集成功能。例如,如果想要将访问日志添加到 HTTP 过滤器中,可以在 filter 的配置中添加 access_log 配置项:

        - filters:
          - name: envoy.http_connection_manager
            config:
              codec_type: auto
              stat_prefix: ingress_http
              access_log:
                - name: envoy.file_access_log
                  config:
                    path: "/var/log/access.log"
              route_config:
    

    然后停止服务,重新构建并运行容器:

    $ docker-compose down
    $ docker-compose up --build -d
    

    通过 curl 访问服务,然后通过 docker-compose exec front-envoy /bin/bash 命令进入容器的终端,你会看到 /var/log/access.log 文件记录着你的请求结果。

    Admin Server

    Envoy 的一大特色是内置的 Admin 服务,如果你在浏览器中访问 http://localhost:8001 ,可以看到 Envoy admin 提供以下管理 API 端点。

    命令 描述
    / Admin 主页
    /certs 打印机器上的 certs
    /clusters upstream cluster 状态
    /config_dump 输出当前的 Envoy 配置
    /cpuprofiler 开启/关闭 CPU profiler
    /healthcheck/fail 导致服务失败健康检查
    /healthcheck/ok 导致服务通过健康检查
    /help 打印管理命令的帮助信息
    /hot_restart_version 打印热重启兼容版本
    /listeners 打印 listener 地址
    /logging 查询/更改日志级别
    /quitquitquit 退出服务
    /reset_counters 将计数器重置为 1
    /runtime 打印运行时值
    /runtime_modify 修改运行时值
    /server_info 打印服务器版本/状态信息
    /stats 打印服务器状态统计信息
    /stats/prometheus 打印 prometheus 格式的服务器状态统计信息

    通过 API 管理端可以对 Envoy 进行动态配置,参考 v2 API reference

    4. 进一步探索


    如果你有兴趣探索 Envoy 的更多其他功能,Envoy 官方示例还有一些更复杂的拓扑结构,但这些示例仍然使用静态类型的服务发现。如果你还想了解有关如何在生产环境中使用 Envoy 的更多信息,请参阅 Integrating Service Discovery with Envoy 以了解将 Envoy 与现有环境集成的意义。如果你在测试 Envoy 的过程中遇到问题,请访问 Getting Help 页面以获取更多的帮助信息。

    5. 参考



    https://hugo-picture.oss-cn-beijing.aliyuncs.com/images/wechat.gif
    扫一扫关注微信公众号


    -------他日江湖相逢 再当杯酒言欢-------

    「真诚赞赏,手留余香」

    米开朗基杨

    真诚赞赏,手留余香

    使用微信扫描二维码完成支付

    envoy 

    相关推荐