共计 4937 个字符,预计需要花费 13 分钟才能阅读完成。
我的项目背景
什么是 Apache APISIX?
API 网关作为微服务架构中的重要组件,是流量的外围出入口,用于对立解决和业务相干的申请,可无效解决海量申请、歹意拜访等问题,保障业务安全性与稳定性。
作为开源的云原生 API 网关,Apache APISIX 兼具动静、实时、高性能三大劣势,可提供负载平衡、动静上游、灰度公布、服务熔断、鉴权认证、可观测性等丰盛的流量治理性能,帮忙企业疾速、平安地解决 API 和微服务流量,可利用于网关、Kubernetes Ingress 和服务网格等场景。
同时,Apache APISIX 已通过宽泛的生态单干建设起丰盛的社区生态。Apache APISIX 也反对高度定制化,反对 Wasm,可用 Java、Go、Python 等支流计算机语言编写插件。
Apache APISIX 技术架构
Apache APISIX 采纳了数据立体与管制立体拆散的架构形式,通过配置核心接管、下发配置,使得数据立体不会受到管制立体影响。
在此架构中,数据立体负责接管并解决调用方申请,应用 Lua 与 Nginx 动态控制申请流量,可用于治理 API 申请的全生命周期。管制立体则蕴含了 Manager API 和默认配置核心 etcd,可用于治理 API 网关。管理员在拜访并操作控制台时,控制台将调用 Manager API 下发配置到 etcd,借助 etcd watch 机制,配置将在网关中实时失效。
配置核心默认为 etcd,也反对 Consul、Nacos、Eureka 等。etcd 人造反对分布式、高可用,反对集群,并且在 K8s 等畛域有大量的利用实际,使得 APISIX 能够轻松反对毫秒级配置更新、撑持数千网关节点,且网关节点无状态,可任意扩缩容。
etcd 的局限性
1. 本身架构问题
首先,etcd 基于 BoltDB,容量具备下限。etcd 的默认存储下限为 2 GB,如果下限要求超过 2 GB,则能够通过 --quota-backend-bytes
标记配置存储,最大可调整至 8 GB。一个 etcd 集群如果有 8 GB 的存储量,则足以服务一个网关,但如果同时服务 N 个 APISIX 集群,容量可能不够用,有可能会带来一些麻烦。
其次,etcd 实质上是一个 CP 零碎,无 法承载 大量的客户端连贯。因为 etcd 是通过 Raft 来实现分布式共识,所有的读写申请都会经由 Raft 的 Leader 进行解决,大量的客户端连贯可能会导致整个集群的负载偏高,有可能会影响到调用者。
2. 场景配合问题
在 Ingress 和 Service Mesh 等场景,应用 etcd 相对来说有点过重,有些 用户不心愿部署除管制 面和数据 面以外的组件。比方 NGINX Ingress Controller 只需一个镜像就能够跑起来,但 APISIX Ingress Controller 除了 Ingress Controller 管制面和 APISIX 数据面,还有一个 etcd。对用户来说,这种技术架构的部署老本更高,还要保障 etcd 的运维。
而且实质上,etcd 是一个冗余组件,齐全能够去掉。K8s 自身反对存储服务,所有的配置信息、存储在 APISIX 后端的 Endpoints 信息都能够从 K8s 的 API Server 获取。在这种场景应用 etcd 会造成整个选型更加轻便。
服务网格也是同理。在服务网格场景应用 APISIX,如果还要部署 etcd,整个选型就会并重。而且在服务网格场景,Pod 的数量可能成千盈百甚至上万,这种状况很常见。如果上万个 Pod 全副连到 etcd,etcd 会成为整个服务的瓶颈。
3. 老本问题
第一,etcd 的运维老本较高,有些公司没有专门的 etcd 运维工程师。部署 etcd 至多须要 3 个或 5 个实例,etcd 胜利运行后,还须要定期做数据备份,创立快照。为了监控 etcd 的运行状况,实时理解 etcd 的健康状况,还须要搭建可观测性零碎,提供必要的告警反对。如果一个公司没有专门的 etcd 运维工程师,可能无奈做好 etcd 的运维工作。
第二,有些公司或组织有长期应用的中间件或基础设施,切换配置核心会带来肯定的老本。对这些公司或组织来说,他们往往更心愿复⽤已有的中间件或基础设施作为 APISIX 的配置中⼼,⽐如 TiDB、Consul、Apache ZooKeeper,从而收敛技术栈,防止带来额定的老本。
我的项目动机
基于以上思考,咱们决定钻研新的计划,扭转当初过重的技术架构,为 Apache APISIX 的用户提供更灵便的抉择,不被 etcd 绑定,缓解现有用户的 etcd 运维压力,升高运维老本,同时冀望给到用户更多、更优的抉择,冲破 etcd 的本身瓶颈。
解除 APISIX 和 etcd 的强关联,让用户领有更多、更灵便的抉择,其实也是开源的魅力所在。如果可能解除这一层限度,不限度用户如何用,用户可能会发明出更多惊喜。
我的项目介绍
方案设计
如何解耦 APISIX 和 etcd?
方案设计之初,咱们思考的第一个问题是如何实现 APISIX 与 etcd 的解耦,因为 APISIX 的核⼼代码、数据结构与 etcd 关系密切。负责操作配置的 Admin API 通常会在返回值里带上 etcd 的元数据,比方 etcd v3 的 Revision、etcd v2 的 createdIndex
、modifiedIndex
,甚至在 APISIX 的外围逻辑里,某个路由或者某个 Upstream 对象也会带上这些元数据。
如果从根本上革新 APISIX,老本会过⾼。在如此外围的中央进行革新可能也会影响 APISIX 现有的稳定性,因而间接批改 APISIX 可能并不是一个很好的计划。
破局:引入额定的中间层
如果间接革新老本太高且危险太大,那么咱们是不是能够思考引入一层额定的中间层?在计算机界有一句名言——“没有什么问题是加一层解决不了的”。如果要退出一层,这一层具体要负责什么事件?做什么事件?总结下来,这一层须要实现两个比拟重要的事件。
第一,这个额定的中间层需 提供 etcd v3 API 并⽀持 etcd gRPC Gateway。目前,APISIX 只反对 etcd v3。对 APISIX 来说,这个中间层仍然是一个 etcd,它必须提供 etcd v3 的 API。除了提供 v3 的 API,它还要反对 etcd 的 gRPC Gateway,因为 APISIX 当初还是通过 HTTP 协定和 etcd 交互,而 etcd v3 API 是基于 gRPC,咱们须要 etcd 的 gRPC Gateway 把 HTTP 的申请转成 gRPC 申请,从而使得整个交互可能顺利进行上来。
第二,这个额定的中间层能 对接各种不同的存储计划。咱们要想分明如何反对 TiDB、PostgreSQL,SQLite,甚至是 Consul、Apachce ZooKeeper 这些不同的计划。
只有做到了这两点,这个中间层能力对接不同的存储计划,从而给 APISIX 带来残缺的配置核心的性能。
计划施行
站在伟人的肩膀上集成 TiDB
有了这个中间层后,咱们要怎么集成 TiDB 呢?其实咱们有一个相似的我的项目能够参考。尽管 K8s 原生反对应用 etcd 作为存储计划,但 Rancher 的 K3s 我的项目并没用 etcd,可能是因为如果 K3s 部署在某些嵌入式环境中,etcd 的一些限度使其没有方法很好地运维。于是,Rancher 通过 Kine 这个我的项目,反对了一些额定的组件,比方 PostgreSQL、MySQL、SQLite、Dqlite,使得 K3s 的用户能够灵便抉择其余存储计划。概括来说,Kine 这个我的项目有以下几点值得咱们借鉴。
第一,TiDB 兼容 MySQL,而 Kine 我的项目自身又反对 MySQL。咱们能够借鉴或者参考 Kine 的一些实现,从而帮忙咱们这个我的项目更好地反对和对接 TiDB。
第二,Kine 残缺地实现了 etcd 须要反对的 watch 性能。因为 APISIX 是基于推模式来感知配置的变更,配置变更的时延通常在毫秒级别,时延非常低。而 watch 性能正好波及到配置的推送,所以 watch 机制相当重要。
第三,Kine 还模仿了 etcd 的 MVCC 个性,反对 Compact。每一次的变更、写入、更新或者删除在 Kine 或 TiDB 里就是一行数据。每行数据的主键就是 etcd 的 Revision,也就是计数器,记录最新变更的次数。通过这种形式,Kine 实现了多版本的反对。
通过引入相似架构,Apache APISIX 不必和真正的存储核心进行交互,而是和这个中间层进行交互。如上图,APISIX 和 etcd adapter 中间层会走 etcd 的 KV API 和 Watch API,etcd adapter 会轮询 TiDB,感知配置的写入,实现 watch 操作,从而把数据推给 APISIX。
计划成果
etcd adapter 的诞生
有了这些思考以及 Kine 这个我的项目的参考,咱们站在伟人的肩膀上开发出了 etcd adapter 我的项目。
首先,这个我的项目 反对了 TiDB、MySQL 以及 In-Memory B-Tree 等多种配置核心,不久后,也会反对 SQLite 和 PostgreSQL。其中,In-Memory B 树和 APISIX Ingress Controller 架构过重无关。如果抉择 In-Memory 的 B 树选型,用户能够间接把 etcd adapter 内嵌到目标程序外面。这种形式少了一个组件,能够进一步晋升整体的用户体验。
其次,这个我的项目 反对了 etcd v3 的 API。目前,这个我的项目只反对了 APISIX 所需的 API 子集,比方 KV API 和 Watch API。至于其余类型的 API,比方 Lease、偏认证类的 API 还没有全副实现。
最初,这个我的项目 ⽀持了 gRPC Gateway。它会把对应的 gRPC 接口翻译成对应的 Restful 接口,供 APISIX 调用。
尽管咱们把 etcd adapter 放在了管制面,但咱们也能够把它放在每个 APISIX 边上,作为一个边车存在。两种计划各有益处,大家能够依据本人的理论状况灵便抉择。
将来打算
对于这个我的项目的后续打算和将来方向,咱们有以下几点想法分享给大家。
为 Apache APISIX 的⽤户提供更多的配置中⼼抉择
咱们心愿 etcd adapter 我的项目能让 Apache APISIX 的用户有更多的配置核心抉择,不被 etcd 锁定,用户能够依据本人的理论状况抉择解决方案。如果公司的运维、开发的技术栈更偏差于 Consul,就能够应用 Consul。Consul KV 也是基于 Raft,可用性很高。除此以外,也能够思考比拟支流的 Apollo 或者和 etcd 对标的 Apache ZooKeeper,还有 PostgreSQL 或者其余备选计划。
为 Apache APISIX Ingress Controller 的架构改进助⼒
咱们心愿 etcd adapter 我的项目能为 APISIX Ingress Controller 的架构改进助力。etcd adapter 反对了 In-Memory B-Tree,In-Memory B-Tree 能够把数据嵌入到内存里,而不须要理论地存储。
如此一来,etcd adapter 能够成为 APISIX Ingress Controller 的一部分,Apache Ingress Controller 只需保留 Ingress Controller 管制面和 APISIX 数据面两个组件。因为没有了 etcd,APISIX 甚至能够和 Ingress Controller 间接交互,获取配置变更数据。
除此以外,咱们还能够把 Ingress Controller 管制面和 APISIX 数据面放在同一个镜像里,实现管制⾯与数据⾯的⼀体化部署。最终只须要一条命令、一个镜像,就能够在 K8s 指标集群中把 APISIX Ingress Controller 跑起来。如果管制面、数据面放在一起,大家就不必再额定部署一个 etcd 和一个管制面,相当于间接少了两个组件,能够极大地晋升用户体验。
捐献给 Apache 基金会,作为 Apache APISIX 的⼦项⽬进⾏孵化
目前,这个我的项目的地址是 https://github.com/api7/etcd-…,放在 API7.ai 仓库里。将来,咱们冀望继续打磨这个我的项目,待我的项目迭代地比较完善后,会把它捐献给 Apache 软件基金会,作为 Apache APISIX 的子项目进行孵化,从而吸引到更多社区的有志之士,和咱们一起欠缺这个我的项目,让 Apache APISIX 的生态更加宏大。