背景介绍
Zadig 是基于 Kubernetes 打造的开源、企业级一体化云原生 DevOps 平台。它具备灵活易用的高并发工作流、面向开发者的云原生环境、高效协同的测试管理、强大免运维的模板库、客观精确的效能洞察以及发布编排工作流、客户中心等重要特性,为工程师提供统一的协作平面。
Zadig 网关层主要引入 Gloo Edge、认证和授权组件 OPA、身份认证组件 Dex,最终支持了业务所需的灵活的 RBAC、ABAC 权限管理、统一用户支持接入 LDAP(AD、OpenLDAP)、OAuth 2.0、GitHub 等能力,但不同应用场景有不同的诉求,本文仅将 Zadig 场景下的架构选型思考分享给社区供参考。
Zadig 使用 API Gateway 的必要性
面向企业级的研发场景,需要提供更为强大的系统级管理能力。同时 Zadig 的服务数量也在增加,企业级能力要求越来越高,势必对服务调用提出更高的要求:
-
1. 客户端维护负担需要降低,通过统一网关访问管理多个服务地址
-
2. 面对业务变化,接口重构时调用方不须了解接口本身的拆分和聚合
-
3. 客户端无须关心接口协议,内部可以使用多种不同的协议(http,rpc,amqp)
-
4. 统一身份认证,权限控制,接口请求访问日志统计等
-
5. 隔离内外部 API,以提升系统的健壮性和安全性
-
6. 通过服务动态注册,负载均衡,流量复制、染色等机制,实现灰度发布,服务调试等功能
Zadig 的访问入口有 Portal 和 IDE 插件 Toolkit 两种,出于以上的考虑,初步对网关架构做以下设想:
有哪些需求需要被实现?
除了满足当下的业务需要,同时需要考虑到未来的可扩展性和应用场景,对短期和中长期需求做了如下梳理,以确定我们后续的技术方向。
短期需求
-
• 反向代理:这个是核心需求,需要为所有访问后端 API 提供一个单一入口,同时隔离内外部的 API
-
• 认证:这个也是刚需场景,Zadig 是面向大型团队的工程师群体提供服务,认证中心需要提供多种认证方式以供统一登录,比如支持用户名密码,LDAP/AD,第三方 SSO,OAuth2,GitHub/GitLab/Google/... 等
-
• 授权:Zadig 面向开发者的资源主要是工作流和集成环境,需要满足不同项目下开发、测试、运维场景下的业务分离。所以需要通过可配置的策略提供多样化的权限控制。
-
• 缓存:如果能缓存频繁请求的数据,可以减少网络带宽和往返时间的消耗,提高性能,尤其是对于 GitHub 这种访问比较困难的资源
-
• API 聚合:面向特定的业务场景需要聚合某些 API 请求,减少请求数量,降低前后端的耦合,以提升开发和协作效率
-
• 请求 / 响应重写:支持请求 url,header,body 的修改和响应状态,header,body 的修改
-
• 操作 / 请求日志:系统需要审计日志功能,来记录所有对系统的更改,所有请求的参数,响应时间等
-
• 负载均衡:通过一个传入的 URL 路由到多个后端目的地,扩展应用程序以实现高可用性
-
• 支持 WebSocket:许多动态和实时功能可以通过 WebSockets 来解决,以减少频繁数据传输的多个 HTTP 调用的开销
-
• 支持 gRPC:gRPC 通过利用 HTTP/2 进一步降低负载,可以有效地用于服务之间的相互通信
中长期需求
-
• 子环境:暂时还不是刚需,但随着微服务的不断迭代,完整拉起一套系统会资源开销增大。子环境可以只部署需要开发或者调试的部分服务,其他服务可以直接使用父环境
-
• IP 列表:当未来提供公有服务时,为系统提供额外的安全层,当发现一组恶意地址试图通过使用 DDoS 类攻击时使应用程序免于瘫痪,允许或阻止某些 IP 地址通过。
-
• 速率限制:能够对 API 调用进行流控,例如只想允许所有使用者每分钟调用 10000 次,或者允许让某一特定使用者每月调用 1000 次
-
• 版本化:同时使用不同版本的 API ,或者提供金丝雀版本或蓝 / 绿部署、灰度发布能力
-
• 熔断器:提供在线服务时可避免服务中断,提供高可用的基础保障能力
选型调研
通过对需求的分析,我们找了一些资料做相应的对比选型,主要研究了 Zuul、Kong、APISIX、Tyk、Gloo、Emissary-Ingress 及 KrakenD,以下是对他们各自能力的简要分析:
Zuul
Zuul 是 Netflix 开源的微服务网关,Spring Cloud Netflix 全家桶之一。核心是一系列的过滤器,可以完成以下功能:身份认证与安全,审查与监控,动态路由,压力测试,负载分配等。
Kong
Kong 是一款基于 OpenResty(Nginx + Lua 模块)编写的高可用、易扩展的,由 Mashape 公司开源的 API Gateway 项目。Kong 通过插件(插件使用 Lua 编写)的形式提供负载均衡,日志记录,身份验证,速率限制,转换等功能。可以很轻松扩展功能,模块化,可以运行在任何基础设施上。
APISIX
APISIX 是一个基于 OpenResty 和 etcd 实现的云原生、高性能、可扩展的微服务 API 网关。APISIX 通过插件机制,提供动态负载平衡、身份验证、限流限速、配置和插件热更新等功能,并且支持你自己开发的插件(插件使用 Go/Python/Java 编写)。
Tyk
Tyk 是一款基于 Golang 和 Redis 构建的开源 API 网关,拥有丰富的功能集和漂亮的 Web-UI 仪表板,但是对商业用途不是很友好。
Gloo
Gloo 是一个基于 Envoy 的 Kubernetes 原生入口控制器和下一代 API 网关。Gloo 在函数级路由方面表现卓越,它支持传统应用程序、微服务与 Serverless(Gloo 被选为 Knative 项目的首选 ingress 项目)。Gloo 设计独特,可支持混合应用,其中的多种技术、架构、协议和云可以共存。
Emissary-Ingress (fka Ambassador API Gateway)
Emissary-Ingress 与 Gloo 类似,也是一个基于 Envoy 的 API 网关。
KrakenD
KrakenD 是一款基于 Golang 的高性能的开源 API 网关。它的核心功能是创建一个 API,该 API 充当许多微服务到单个端点的聚合器,为用户自动完成聚合,转换,过滤,解码,限制,身份验证等工作。
这些组件都有不同的应用场景和成熟度,我们得到一些初步的结论:
-
1. Zuul 适用于 Spring Cloud 生态
-
2. Kong 和 APISIX 特点类似,相比之下 APISIX 略胜一筹
-
3. Tyk 是纯 Golang 写的 API 网关,但是文档和用例比较少,对商业用途也不是很友好
-
4. Gloo 和 Emissary-Ingress 都是基于 Envoy 的 API 网关,相比 Gloo 资料更丰富一些
-
5. KrakenD 是另一个 Golang 写的 API 网关,API 聚合功能强大,但是比较小众
以上 API 网关都没有提供认证和鉴权或者功能支持的比较简单。认证基于 Dex 鉴权有两种方案:一种是基于 OPA 的 Envoy ,另一种是基于 RBAC 的 Casbin。APISIX 对 Casbin 的支持非常好。所以最终敲定了两套备选方案为 Gloo+Dex+OPA 或者 APISIX+Dex+Casbin。
同时我们考虑到 Gloo 是 Kubernetes Native 的方案,基于 CRD 实现,完全依赖于 API Server,无状态。同时支持微服务,Serverless 和传统服务,未来可以无缝对接 Serverless 和 Service mesh,支持本地服务的特性也为本地调试带来可行性。所以最终选定为 Gloo 方案。
通过引入网关组件,最终 Zadig 系统架构呈现如下。
关于 OPA、Dex 的详细技术实现:
参考链接
• https://www.bbva.com/en/api-gateways-kong-vs-tyk
• https://www.krakend.io/docs/overview/
• https://github.com/apache/apisix
• https://github.com/Netflix/zuul
• https://github.com/Kong/kong
• https://github.com/TykTechnologies/tyk
• https://zhuanlan.zhihu.com/p/103236688
• https://mahesh-mahadevan.medium.com/my-experiences-with-api-gateways-8a93ad17c4c4
Zadig,开放,链接,专业。