发现并应用一个性能卓越的、云原生、能适应至少未来五年架构趋势的 API 网关,现今已经成为基础架构团队的必做命题,否则整个基础设施架构可能是存在某些先天缺陷的,且维护成本相当之高。Envoy 正是在这种背景下走进大众视野,且非常契合各大技术团队的下一代网关“明星选手”。
Google、IBM、微软等跨国巨型企业对 Envoy 的使用已经相当深入,这种信任并非源于简单的,诸如“云原生”、“下一代”之类的噱头概念,而是可从其 TPS 表现获得更直观的印象。早在 2020 年,网易数帆云计算技术专家裴斐在接受 InfoQ 采访时,就给到了一组直观的对比数据:8 核部署的 Envoy TPS 可以达到 12W 左右,是同环境下基于 Java 的异步化 API 网关的 4.2 倍左右,是基于 Nginx 的 Kong 的 2.4 倍,是 APISIX 的 1.3 倍。同时,Envoy 和 Istio 的深度融合,在开源方面的成熟度,也在为其加码。
阻碍 Envoy 在国内取得广泛应用的主要顾虑是:Envoy 架构复杂。在设计之初,易用性并不是 Envoy 的一个考虑要素。且 Envoy 使用 C++ 开发,令国内以 Java 为主的技术团队望而却步。但语言以及所谓的架构复杂,真的能对各技术团队构成落地障碍吗?从网易的实践来看,未必如此。
带着与 Envoy 的选型考量、落地实施、扩展性改进相关的种种问题,InfoQ 再次采访了裴斐,他是网易大规模落地 Envoy 的亲历者,相信能为准备或者正在考虑 API 网关升级的你带来收获。
网易的选型考量
InfoQ:我们知道网易早在 2017 年就开始考虑基于 Istio 和 Envoy 实现服务网格平台及 API 网关。当时是基于什么样的背景,或者想要解决什么样的问题,因而开始了对这两个方向的探索?
裴斐:大背景是对网易集团内部业务的微服务基础设施的升级与统一。服务网格是针对微服务框架的升级,在此之前,网易内部存在着 Spring Cloud、Dubbo、自研 RPC 等多种微服务框架,不同技术栈造成研发和维护成本较高;API 网关是针对内部使用较多的 Zuul、Kong 以及自研网关的升级,老的网关在性能、扩展性、容器兼容性等多方面,或多或少都存在一些不足。
所以寻找一个能力全面、高性能、代表未来技术发展趋势,能把网易集团内部繁杂的微服务技术栈统一开发与维护起来,从基础设施层面牵引业务架构逐步升级演进的技术方案,是当时探索的主要出发点。
InfoQ:云原生时代,大家对网关的要求与从前相比有什么本质的区别吗?
裴斐:在云原生时代,我们对网关的要求更全面、严苛,简而言之就是“既要又要还要也要” —— 既要满足云原生环境的新需求(纳管容器环境出、入口流量),又要覆盖新、老应用多样的流量纳管功能需求,还要保证始终如一的高性能与稳定性,也要能够作为面向未来的统一网关纳管一切网络七层流量。Envoy 就是在云原生大背景下新设计的产物,相较于 HAProxy、Nginx 等传统网关代理软件,原生就具备了更丰富的功能、可观测、动态配置、扩展性,不需要特别的扩展编程即可满足绝大多数流量治理场景下对网关的功能与性能稳定性需求。
我们对 Envoy 的最初关注来自于对下一代微服务架构 —— 服务网格的选型。当时 Istio 是更有“巨星像” 的服务网格框架,在研究落地 Istio 过程中,我们发现了 Envoy 成为“下一代网关”的诸多特质,经过几个月技术可行性验证和业务实践后,我们决定选用 Envoy 来构建下一代网关。
InfoQ:能否分享一下详细的技术选型过程,你们做了哪些对比?
裴斐:一般来说,应用网关选型会倾向在以 Java 异步化做转发的网关和以 Nginx 为内核的网关之中作出选择。
Java 异步化网关的典型代表是 Spring Cloud 系列的 Zuul 2.x 和 Spring Cloud Gateway,我们的第一代网关就是自研实现的 Java 异步化网关,好处是基于 Java 语言开发,有 Spring Cloud 项目作为参考,自研实现、扩展、维护容易,适合以 Java 为核心语言栈的团队“折腾”,缺点是 Java 语言本身在异步效率、内存回收等性能方面难以与传统代理软件匹敌,在大规模流量场景下有明显的性能瓶颈。
以 Nginx 为内核的网关,当时比较成熟的选择是 Kong,网易内部多个核心产品线当时都在以 Kong 作为 API 网关,运行相对稳定,性能也比 Java 异步化网关好不少。当时业务面临着大规模云原生、容器化、服务网格化的架构升级,Kong 作为相对传统的 API 网关,直接作为容器化环境中的网关需要不少额外工作,包括对 Kubernetes 基于 ETCD 注册中心的纳管和稳定运行,为生产业务的架构升级带来不少额外的开发、维护负担。
Envoy 在服务网格 Istio 框架中作为边车(Sidecar)和网关(Gateway)的实现存在,其中网关实现可以原生作为容器化、服务网格环境的入口流量代理与治理,但还没有成体系 API 网关能力封装。当时国内围绕 Envoy 进行的企业级实践几乎是空白的,国外则有一些开源项目(如 Gloo、Ambassador )完成了初步探索。我们为此进行了专项的技术可行性调研,几个月时间完成了第一版基于 Envoy 的 API 网关的总体设计、主体功能开发与封装,初版发布就能满足网易云内部对 API 网关的功能要求,在性能方面也远好于 Java 异步化网关与以 Nginx 为内核的网关。至此,网易 Envoy API 网关开始扬帆起航。
InfoQ:其实直到今天,国内基于 Envoy 建设 API 网关的企业也很少,您认为是哪些原因造成了这样一种情况?
裴斐:主要还是领域认知度和技术栈熟悉度两方面原因。
在领域认知度方面,虽然 Envoy 在国外(Google,Lyft)最早就是作为网关代理在生产环境应用的,国内对 Envoy 的早期认知还只是其作为服务网格 Istio 的数据面组件,这就造成了熟悉并对服务网格有研究的企业很容易接纳 Envoy ,并以此作为下一代网关落地;反之,不熟悉服务网格或 Envoy 的企业会认为 Envoy 只具备云原生、服务网格等特定的场景能力(实际上完全不是的)。
在技术栈的熟悉度方面,Envoy 主体是基于 C++ 开发的,国内企业对 Java、Go 语言以及 Nginx 更为熟悉,选型方面也会从更利于自己掌控与“折腾”的角度出发,很容易忽视未来选型的正确性、长远性。我了解到包括很多国内的大厂团队和开发者在内,都因为 C++ 语言本身与其团队或个人的技术不匹配而被劝退。
我们在选型 Envoy 早期的确也有此顾虑,最终在上手难度与选型的正确性、长远性之间选择了后者。其实后来根据我们的实际开发经验,在突破前期的语言和原理认知瓶颈期后,Envoy 并不像想象中那么“可怕”,我们团队的 Envoy 开发者都是非常年轻的同学。
InfoQ:基于您的经验,什么样的公司或业务场景适合采用 Envoy 作为 API 网关?
裴斐:Envoy 是面向未来的网关选型,我认为如果业务符合如下情况,都可以采纳 Envoy 作为 API 网关选型:
已有 API 网关,在性能、稳定性、扩展性、可观测性等方面存在痛点,希望升级网关基础设施;
希望纳管包括容器化、服务网格等未来、多样业务流量的场景;
有计划将已有 Nginx、微服务 API 网关、负载均衡器、Kubernetes Ingress、Serverless 函数路由等网络七层流量代理设施合之为一、简化链路和组件的场景。
迁移、改造落地实践
InfoQ:旧网关迁移到新网关之前,开发人员需要做哪些准备工作?
裴斐:最主要的准备工作是梳理。
如按服务、接口、Path 等,后续需要基于基本信息上配置相同的路由信息,完成基本的网关配置准备;
如果涉及到特化的调用场景,需要梳理尽量细致、完整的特化用法,以此判断新网关能否适配特化用法;
部分功能新网关无法满足,可能需要以扩展插件的方式满足需求。
我们的 Envoy 网关提供了开源企业级 Lua 扩展框架 —— Rider,可以方便地支持用户以 Lua 语言扩展网关数据面能力。
InfoQ:落地基于 Envoy 的新网关之后,相比旧方案,业务方获得了哪些收益?
裴斐:业务方获得的最大收益是网关基础设施得到了长效的架构与能力保障。新网关方案原生亲和容器、服务网格、Serverless,同时也能接管以往由 Nginx、传统 API 网关代理的流量,真正意义上帮助业务实现了网关基础设施的平滑演进迁移。此外,Envoy 本身架构方式为业务也带来了如转发性能高、延时低、监控全、动态控制容易等诸多获益点,提供了更好的云原生基础设施体验。
InfoQ:据了解,到 2020 年网易就已经有不止一个核心业务落地了 Envoy Gateway,现在业务落地的最新情况如何?
裴斐:网易大部分互联网业务都已经落地了 Envoy Gateway,作为应用集群的入口网络基础设施,少部分由于历史原因无法完全迁移的业务也在部分新场景中落地。
InfoQ:根据你们的经验,落地 Envoy Gateway 有哪些主要的坑点或难点?你们是如何解决的?
裴斐:早期我们落地 Envoy Gateway 遇到比较大的坑点来自扩展性方面。原生 Envoy 提供了 Lua 插件机制,但不管从 API 库丰富程度,还是插件性能来看,都距离生产落地有不小的差距。让业务自行开发 Envoy,或者全部由我们完成扩展显然也不现实,于是便有了开发 Envoy 扩展插件机制的计划。我们借鉴了 OpenResty 与 Kong 在 Lua 扩展方面的优异设计,比较快的完成了 Envoy Lua 扩展插件框架—— Rider,目前这个项目已经开源,感兴趣的读者可以详细参考文章。
InfoQ:能否以一个业务场景为例(比如网易严选),介绍一下 API 网关的完整演进过程?
网易严选杨文超(原文链接):
总体演进历程如下图所示,主要可分为五大节点:
Service Mesh1.0:严选自研的基于 Consul+Nginx 的服务网格,解决了内部微服务之间的流量治理问题,统一了严选微服务体系。
API 网关 1.0:即严选 Ianus 网关,解决了外部对服务访问的流量治理问题,并经受住了多次大促流量的考验;
Service Mesh2.0:严选的服务网格进化为网易轻舟(下文简称轻舟)的基于 Istio 的服务网格架构,支持更丰富的流量管控能力;
边缘网关:在流量迁移到轻舟过程中,API 网关角色就转变为边缘网关,负责跨云的流量管控,这里也推进了云内边缘网关的建设;
API 网关 2.0:即轻舟 Envoy 网关,此时数据面抛弃了 API 网关 1.0 版本,与轻舟一起建设基于 Envoy 的云原生 API 网关。
总体演进历程
API 网关 1.0 部署架构
在 API 网关 1.0 阶段,严选团队初步达成:
统一严选的 API 访问入口,超过 90% 流量跑在严选 Ianus 网关之上。
统一流量治理,在控制面上与微服务达成统一。
提供标准的容灾能力,如频控、降级、静态化等,从而业务可以进行复用。
充分利用 LUA 的插件能力,满足业务个性化需求。
期间线上问题进行实时的总结归档,比如 Nginx 的配置使用问题,Kong 的版本跟踪问题,PostgreSQL 的优化等等。实际落地过程中,严选团队没有局限于网关,而是着眼于严选微服务体系的建设。
随着 ServiceMesh 从 1.0 向 2.0 演进,过渡期会存在 ServiceMesh1.0(严选 VM)与 ServiceMesh2.0(轻舟 Kubernetes)两种类型的 ServiceMesh 共存的情形,自然面临两个 ServiceMesh 间的流量调拨问题。这里用“云外”代表 ServiceMesh 1.0,“云内”代表 ServiceMesh 2.0。
在跨 ServiceMesh 访问的问题方面,严选团队在各个 ServiceMesh 之上,部署自建的边缘网关(Edge Gateway),与数据中心的基础设施集成。云内即推动轻舟将原有 Istio 服务网格中的 Ingress/Egress 进行替换,统一到轻舟 Envoy 网关(即下文的 API 网关 2.0)。云外采用严选 Ianus 网关进行部署,云内采用轻舟 Envoy 进行部署。
同时,已有跨环境访问,需要 SA 打通两两 IP 之间的防火墙。一方面,每次需要对应用服务器 IPtable 做专门的配置;另一方面,所有互访配置离散到各个应用服务器,无法做集中管控。这里将跨数据中心的访问流量,统一走到边缘网关,在网关上进行相应的认证鉴权(基于插件实现)。
跨 ServiceMesh 可以认为是东西向流量,而跨环境可以认为是南北向流量。最终支持了各大环境互访,统一业务访问方式,消除环境差异,并对流量进行集中式管控,方便统一运维。
在 API 网关 2.0 阶段,上云之初,严选 API 网关团队也调研对比了 Kong、Traefik、Ambassador、Gloo、Istio Gateway 等的特性,目标是构建一个云原生的 API 网关。
综合考虑后,决定将云内网关建设的任务交给网易数帆-轻舟网关团队负责,严选则从 API 网关的需求以及当前的工程建设规划出发,给出设计和建议。数据面部分,考虑了现有轻舟微服务体系的无缝融合以及主流的产品实现,选型采用了 Envoy 进行数据面的建设;控制面部分,考虑到严选需要复用现有管理平台的功能,则基于现有的 Istio 体系进行共建。
API 网关 2.0 整体分为控制面和数据面两部分。数据面由双方共建设计方案,落地交由轻舟负责;控制面严选跟轻舟共建,统一到已有严选 API 网关管理平台。而具体数据面集群的规划,沿用了严选 Ianus 网关的部署方式,在此不再赘述。
关于数据面、控制面、插件能力的建设与更详细的架构设计和演进内容,可以参考原文《网易严选的网关架构演进之路》,以及 InfoQ 此前的另一篇文章《云原生时代的流量入口:Envoy Gateway》。
InfoQ:基于网易数帆构建的实践,如果请您从中总结出最重要的三条经验,会是什么?对于想要探索基于 Envoy 建设 API 网关的技术团队,您有什么建议?
裴斐:
战略上藐视(新技术难度),战术上重视(适配与增强)。不管从最初的可行性调研正向推导,还是从现在大规模生产应用的结果倒推,选型 Envoy 作为下一代网关实现都是一次看上去冒险,实际上顺利的实践。选型前期千万不要因为被 Envoy 的架构和 C++ 语言吓到,而错失大量后期收益。另外,在不断实践摸索中,需要结合 API 网关传统能力和业务实际场景,进行谨慎的设计与渐进的适配增强,保证最终落地上技术的严谨性。
前置统一设计。早期我们构建 Envoy Gateway 还是以升级替代旧有网关能力为目标,在实践过程中我们发现 Envoy Gateway 的能量不仅如此 —— 我们基于 Envoy 还成功落地实现了七层负载均衡器(替代 Nginx ),也支持了 Serverless 网关场景,并可以作为 Kubernetes Ingress 使用。基于 Envoy 实现统一的网络七层流量网关在技术层面上完全可行,在前期即可考虑统一软件设计。这块工作也是我们今年的工作一大重点。
关注配置推送性能。Envoy 从设计初期就基于 xDS 协议实现服务发现与配置下发,这种设计可以比较方便的实现动态配置。在配置推送方面需要有比较高效、稳定的策略,避免过多、过频的配置推送,影响 Envoy 的动态性能。
对于想要探索基于 Envoy 建设 API 网关的技术团队,两点建议:
理解 Envoy 和 Istio 的核心原理。Envoy 和 Istio 技术有比较明显的云原生设计印记,与传统开发态框架在设计理念上有较大的不同,可以先期结合网上的官方文档、分享文章,理解 Envoy 与 Istio 交互控制原理,Envoy xDS 协议,Istio Virtual Service / Destination Rule CRD 等核心机制,会对后期 API 网关的构建提供不少帮助。
找现有开源项目加以理解与动手实践。实践是检验真理的唯一标准,这里推荐结合我们开源的云原生网关项目 Hango 作为参考,项目提供了相对简洁的架构和好用的页面控制台,方便国内技术同学了解上手,项目地址:https://github.com/hango-io/hango-gateway
二次开发与技术展望
InfoQ:网易数帆开源了基于 Envoy 的云原生 API 网关 Hango,它跟 Envoy 相比有哪些不同?你们基于 Envoy 做了哪些二次开发工作?
裴斐:准确来说 Envoy 是云原生 API 网关的数据面选型,完整的 API 网关平台一般会包括数据面(核心)、控制面、管理面等。相比 Envoy,Hango 项目主要有如下增强:
上层封装;为 Envoy 提供了上层控制面、管理面,可以方便对 Envoy 进行配置、管理、监控;
插件扩展;为 Envoy 构建了企业级 Lua 扩展插件机制,填补当前插件扩展 Envoy 无法生产落地的缺陷;
协议扩展;为以 Dubbo、gRPC、WebService、WebSocket 等为协议的业务服务提供协议转换与治理能力能力;
兼容适配:针对生产业务“非标”用法的一些兼容适配工作。
InfoQ:为什么没有考虑将这些工作直接贡献回 Envoy 社区,而是另外开源了一个新的项目?
裴斐:事实上,我们对 Envoy 部分的增强基本均已贡献社区,已经贡献了超过 10000 行代码,我们团队的王佰平同学因为这些贡献已经晋级为 Envoy Maintainer。开源 Hango 项目也是基于 Envoy 的完整、成熟的 API 网关项目很少,几乎没有好的开源项目可以给予那些想基于 Envoy 建设 API 网关的技术团队以指引。在 Hango 项目中的建设内容更多还是围绕 Envoy 建设 API 网关所需的其他能力,如插件扩展机制 Rider、网关管理控制台等等。
InfoQ:如今官方有了 Envoy Gateway 这个新的开源项目,会不会影响 Hango 未来的发展?接下来对于 Hango 的发展规划,以及 Hango 跟 Envoy、Envoy Gateway 这两个项目之间的关系,你们是怎么考虑的?
裴斐:官方 Envoy Gateway 刚刚启动,目前这块整体进展还没有特别多,我们也在比较早期就参与到社区 Envoy Gateway 的前期工作中了。Envoy Gateway 在构建思路上也在试图融合如 Emissary、Contour 等已有项目,形成统一的云原生网关标准,再进行真正意义上的构建落地。Hango 一方面还是会把网易 Envoy API 网关中一些通用、好用的能力持续通过版本释放出来;另一方面也会积极参与到社区 Envoy Gateway 的建设中,力争真正把云原生网关标准建设起来,助力业务的下一代网关选型。
InfoQ:当下,团队还希望 Envoy 增加哪些特性或者在哪方面做出优化?
裴斐:首先还是协议的多样性和扩展能力。
Envoy 社区提供最完整、稳定的协议是 HTTP 与 gRPC ,这与 Envoy 所处的国外互联网技术环境相关。在我们的实践中,存在不少国内的业务或者客户在采用国内相对流行的协议(如 Dubbo),还存在自研 RPC 协议的情况。基于任何代理软件实现完整的代理、治理、观测等能力都需要花费大量成本,所以社区原生如果能支持更多样的协议,或者提供更方便的协议扩展能力,会有效消除这些业务的使用门槛。我们团队也在这个方向上探索,争取能把沉淀能力贡献到社区。
然后就是 WebAssembly(WASM) 插件性能。WASM 技术已经在前端、边缘计算、IoT 等多个领域带来业务收益,Envoy 的下一代插件扩展能力基于 WASM 实现,使用多种语言可以扩展开发代理软件,极大方便了业务结合熟悉的语言栈自行扩展 Envoy。不过当前 Envoy 与 WASM 结合依然存在一些性能问题,开发出的插件较难达到生产级性能要求,依然需要 Envoy 社区与 WebAssembly 社区更好地融合。也正因为此,我们在 Envoy WASM 真正成熟之前构建了企业级 Lua 扩展插件 Rider,在多语言扩展插件的银弹落地前,让业务可以有生产级扩展插件的落地能力。
InfoQ:围绕 Envoy Gateway 这个方向,你们还有哪些正在做的事情和未来计划要做的事情?
裴斐:
作为通用的云原生网关,能够纳管一切七层网络流量。我们基于 Envoy Gateway 已经分别实现了微服务 API 网关、负载均衡器 LB (替代 Nginx)、Serverless 函数网关、Kubernetes Ingress 、Kubernetes Gateway API 等不同场景的落地,下一步我们计划把这些场景形态统一到一个网关(实例)上,业务不需要为不同场景部署不同的网关(实例),一套网关(实例)即可实现业务所有七层网络流量的代理与治理。
在 Hango 项目推进上,我们接下来会联合头部金融企业开源 V1.0 版本,带来更多生产好用的网关功能特性和金融场景特性。
InfoQ:当前行业内还有同样能满足云原生网关要求的开源项目或产品吗?您认为 Envoy 未来有可能成为云原生时代统一的 API 网关标准吗?为什么?
裴斐:真正能满足云原生网关的项目或产品还是偏少的。Envoy 最大的优势还是来自于其先进的设计与背书。Envoy 是一个年轻的项目,因为年轻,所以不像 HAProxy 或 Nginx 有众多“老粉”,目前的关注度和应用还是偏少。但也正因为年轻,Envoy 的设计更新、更有前瞻性,充分考虑了传统场景、云原生场景的需求,更能起到“继往开来”的作用,再加上有 Google、IBM、微软等行业巨头背书,Envoy 具备成为云原生时代统一的 API 网关标准的潜力。
查看专题《Envoy当道?云原生时代的下一代网关选型和实践》,阅读更多 Envoy Gateway 实践干货文章!
评论