共计 4511 个字符,预计需要花费 12 分钟才能阅读完成。
我的项目背景介绍
目前市面上可执行 Ingress 的产品我的项目逐步丰盛了起来,可抉择的范畴也扩充了很多。这些产品依照架构大略可分为两类,一类像 K8s Ingress、Apache APISIX Ingress,他们是基于 Nginx、OpenResty 等传统代理器,应用 K8s-Client 和 Golang 去做 Controller。还有一类新兴的用 Golang 语言去实现代理和控制器性能,比方 Traefik。
又拍云最开始包含当初的大部分业务仍在应用 Ingress-Nginx,整体架构如下。
上层为数据面 OpenResty。下层 Controller 次要是监听 APIServer 的资源变动,并生成 nginx.conf
配置文件,而后 Reload OpenResty。如果 POD IP 发生变化,可间接通过 HTTP 接口传输给 OpenResty Lua 代码去实现上游 Upstream node 替换。
Ingress-Nginx 的扩大能力次要通过 Annotations 去实现,配置文件自身的语法和路由规定都比较简单。能够依照需要进行相干指令配置,同时也反对可拓展 Lua 插件,进步了定制化性能的可操作性。
但 Ingress-Nginx 它也有一些毛病,比方:
- 开发插件时组件依赖简单,移植性差
- 语义能力弱
- 任何一条 Ingress 的批改都须要 Reload,对长链接不敌对
在保护现有逻辑时,上述问题造成了肯定水平的困扰,所以咱们开始寻找相干容器网关替代品。
调研阶段
在代替 Ingress-Nginx 的抉择中,咱们次要考量了 Traefik 和 Apache APISIX-Ingress。
Traefik 是云原生模式,配置文件极其简略,采纳分布式配置,同时反对多种主动配置发现。不仅反对 K8s、etcd,Golang 的生态语言反对比拟好,且开发成本较低,迭代和测试能力较好。然而在其余层面略显有余,比方:
- 扩大能力弱
- 不反对 Reload
- 性能和性能上不如 Nginx(尽管耗费也较低)
它不像 Nginx 有丰盛的插件和指令,通过减少一条指令即可解决一个问题,在线上部署时,可能还需在 Traefik 前搭配一个 Nginx。
综上所述,尽管在操作性上 Traefik 劣势尽显,但在扩大能力和运维效率上有所顾虑,最终没有抉择 Traefik。
为什么抉择 Apache APISIX Ingress
#### 外部起因
在公司外部的多个数据中心上目前都存有 Apache APISIX 的网关集群,这些是之前从 Kong 上替换过去的。起初基于 Apache APISIX 的插件零碎咱们开发了一些外部插件,比方外部权限零碎校验、精准速率限度等。
效率保护层面
同时咱们也有一些 K8s 集群,这些容器内的集群网关应用的是 Ingress Nginx。在之前不反对插件零碎时,咱们就在 Ingress Nginx 上定制了一些插件。所以在外部数据中心和容器的网关上,Apache APISIX 和 Nginx 的性能其实有一大部分都是重合的。
为了防止后续的反复开发和运维,咱们想把之前应用的 Ingress Nginx 容器内网关全副替换为 Apache APISIX Ingress,实现网关层面的组件对立。
基于 Apache APISIX Ingress 的调整更新
目前 Apache APISIX Ingress 在又拍云是处于初期(线上测试)阶段。因为 Apache APISIX Ingress 的疾速迭代,咱们目前还没有将其使用到一些重要业务上,只是在新集群中尝试应用。
架构调整
应用 Apache APISIX Ingress 之后,外部架构如下图所示。
跟后面提到的 Ingress-Nginx 架构不一样,底层数据面替换成了 Apache APISIX 集群。下层 Controller 监听 APIServer 变动,而后再通过 etcd 将配置资源散发到整个 Apache APISIX 集群的所有节点。
因为 Apache APISIX 是反对动静路由批改,与左边的 Ingress-Nginx 不同。在 Apache APISIX 中,当有业务流量进入时走的都是同一个 Location,而后在 Lua 代码中实现路由抉择,代码部署简洁易操作。而右侧 Ingress-Nginx 相比,其 nginx.conf
配置文件简单,每次 Ingress 变更都须要 Reload。
Apache APISIX Ingress Controller
Apache APISIX Ingress Controller 依赖于 Apache APISIX 的动静路由能力进行性能实现。它次要监控 APIServer 的资源变动,进行数据结构转换、数据校验和计算 DIFF,最初利用到 Apache APISIX Admin API 中。
同时 Apache APISIX Ingress Controller 也有高可用计划,间接通过 K8s 的 leader-election 机制实现,不须要再引入内部其余组件。
#### 申明式配置
目前 Apache APISIX Ingress Controller 反对两种申明式配置,Ingress Resource 和 CRD Resource。前者比拟适宜从 Ingress-Nginx 替换过去的网关控件,在转换老本上是最具性价比的。然而它的毛病也比拟显著,比方语义化能力太弱、没有特地粗疏的标准等,同时能力拓展也只能通过 Annotation 去实现。
又拍云外部抉择的是第二种申明配置——语义化更强的 CRD Resource。结构化数据通过这种形式配置的话,只有 Apache APISIX 反对的能力,都能够进行实现。
如果你想理解更多对于 Apache APISIX Ingress Controller 的细节干货,能够参考 Apache APISIX PMC 张超在 Meetup 上的分享视频:https://www.bilibili.com/vide…
性能晋升
#### 成果一:日志层面效率进步
目前咱们外部有多个 Apache APISIX 集群,包含数据中心网关和容器网关都对立开始应用了 Apache APISIX,这样在后续相干日志的解决 / 生产程序时能够对立到一套逻辑。
当然 Apache APISIX 的日志插件反对性能也十分丰盛。咱们外部应用的是 Kafka-Logger,它能够进行自定义日志格局。像下图中其余的日志插件可能有些因为应用人数的起因,还尚未反对自定义化格局,欢送有相干需要的小伙伴进行应用并提交 PR 来扩大以后的日志插件性能。
#### 成果二:欠缺监控与健康检查
在监控层面,Apache APISIX 也反对 Prometheus、SkyWalking 等,咱们外部应用的是 Prometheus。
Apache APISIX 作为一个根本代理器,能够实现 APP 状态码的监控和申请等需要。但 Apache APISIX 的本身健康检查力度不是很好管制。目前咱们采纳的是在 K8s 外面部署一个服务并生成多个 POD,将这个服务同时利用于 Apache APISIX Ingress,而后通过查看整个链路来确定 Apache APISIX 是否衰弱。
应用 Apache APISIX Ingress 实际解决方案
场景一:K8s 利用变更
在应用 K8s 搭配 Apache APISIX Ingress 的过程中,须要做到以下几点:
- 更新策略的选用倡议应用滚动更新,保障大部分 POD 可用,同时还须要思考稳固负载的问题
- 应答 POD 启动 K8s 外部健康检查,保障 POD 的业务可用性,防止申请过去后 POD 仍处于不能提供失常服务的状态
- 保障 Apache APISIX Upstream 里的大部分 Endpoint 可用
在实际过程中,咱们也遇到了传输延时的问题。POD 更新门路如下所示,POD Ready 后通过层层步骤顺次进行信息传递,两头某些链路就可能会呈现延时问题。失常状况下个别是 1 秒内同步实现,某些极其状况下局部链路工夫可能会减少几秒进而呈现 Endpoint 更新不及时的问题。
这种状况下的解决方案是,当更新时前一批 POD 变成 Ready 状态后,期待几秒钟再持续更新下一批。这样做的目标是保障 Apache APISIX Upstream 里的大部分 Endpoint 是可用的。
场景二:上游健康检查问题
因为 APIServer 面向状态的设计,在与 Apache APISIX 进行同步时也会呈现延时问题,可能会遇到更新过程中「502 谬误状态正告」。像这类问题,就须要在网关层面对 Upstream Endpoint 进行健康检查来解决。
首先 Upstream Endpoint 被动健康检查不太事实,因为 Endpoint 太耗时费劲。而 HTTP 层的监控查看因为不能确定状态码所以也不适宜进行相干操作。
最合适的办法就是在网关层面基于 TCP 做被动健康检查,比方你的网络连接超时不可达,就能够认为 POD 呈现了问题,须要做降级解决。这样只需在 TCP 层面进行查看,不须要涉及其余业务局部,可达到独立操控。
场景三:mTLS 连贯 etcd
因为 Apache APISIX 集群默认应用单向验证的机制,作为容器网关应用 Apache APISIX 时,可能会在与 K8s 连贯同一个 etcd 集群(K8s etcd 中应用双向验证)时默认开启双向认证,进而导致呈现如下证书问题:
Apache APISIX 不是通过 gRPC 间接连贯 etcd,而是通过 HTTP 协定先连贯到 etcd 外部的 gRPC-gateway,再去连贯真正的 gRPC Server。这两头多了一个组件,所以就会多一次双向验证。
gRPC-gateway 去连贯 gRPC Server 的时候须要一个客户端证书,etcd 没有提供这个证书的配置项,而是间接应用 gRPC server 的服务端证书。相当于一个证书同时作为客户端和服务端的校验。如果你的 gRPC server 服务端证书开启了扩大(表明这个证书只能用于服务端校验),那么须要去掉这个扩大,或者再加上也可用于客户端校验的扩大。
同时 OpenResty 底层是不反对 mTLS 的,当你须要通过 mTLS 连贯上游服务或 etcd 时,须要应用基于 apisix-nginx-module 去构建打过 patch 的 Openresty。apisix-build-tools 能够找到相干构建脚本。
将来冀望
尽管目前咱们还只是在测试阶段利用 Apache APISIX Ingress,但置信在不久之后,通过利用的迭代性能更新和外部架构迁徙调整,Apache APISIX Ingress 会对立利用到又拍云的所有容器网关内。
对于作者
作者陈卓,又拍云开发工程师,负责云存储、云解决和网关利用开发。
对于 Apache APISIX
Apache APISIX 是一个动静、实时、高性能的开源 API 网关,提供负载平衡、动静上游、灰度公布、服务熔断、身份认证、可观测性等丰盛的流量治理性能。Apache APISIX 能够帮忙企业疾速、平安地解决 API 和微服务流量,包含网关、Kubernetes Ingress 和服务网格等。
Apache APISIX 落地用户(仅局部)
- Apache APISIX GitHub:https://github.com/apache/apisix
- Apache APISIX 官网:https://apisix.apache.org/
- Apache APISIX 文档:https://apisix.apache.org/zh/…