微服务架构中的 API 问题
根据 Gartner 对微服务的定义:“微服务是范围狭窄、封装紧密、松散耦合、可独立部署且可独立伸缩的应用程序组件。”
与将模块高度耦合并部署为一个大的应用程序相比,微服务的目标是将应用程序充分分解或者解耦为松散耦合的许多微服务或者模块,这样做对下面几点有很大帮助:
- 每个微服务都可以独立于应用程序中的同级服务进行部署、升级、扩展、维护和重新启动。
- 通过自治的跨职能团队进行敏捷开发和敏捷部署。
- 运用技术时具备灵活性和可扩展性。
在微服务架构中,我们根据各自的特定需求部署不同的松耦合服务,其中每个服务都有其更细粒度的 API 模型,用以服务于不同的客户端(Web,移动和第三方 API)。
在考虑客户端与每个已部署的微服务直接通信的问题时,应考虑以下挑战:
- 如果微服务向客户端公开了细粒度的 API,则客户端应向每个微服务发出请求。在典型的单页中,可能需要进行多次服务器往返,才能满足请求。对于较差的网络条件下运行的设备(例如:移动设备),这可能会更糟。
- 微服务中存在的多种通信协议(例如:gRpc、thrift、REST、AMQP 等)使客户端很难轻松采用所有这些协议。
- 必须在每个微服务中实现通用网关功能(例如:身份验证、授权、日志记录)。
- 在不中断客户端连接的情况下,很难在微服务中进行更改。例如:在合并或划分微服务时,可能需要重新编写客户端部分代码。
为了解决上述挑战,人们引入了一个 API 网关层,位于客户端和服务器之间,充当从客户端到服务器的反向代理路由请求。与面向对象设计的模式相似,它为封装底层系统架构的 API 提供了一个单一的入口,称为 API 网关。随着微服务架构概念的提出,APIGW 成为了微服务架构的一个标配组件。
APIGW,顾名思义,是出现在系统边界上的一个面向 API 的、串行集中式的强管控服务,这里的边界是企业 IT 系统的边界,可以理解为企业级应用防火墙,主要起到隔离外部访问与内部系统的作用。APIGW 是系统对外的唯一入口,封装了系统内部架构,为每个客户端提供定制的 API。所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有非业务功能。
-
单节点网关
-
多节点网关
简而言之,APIGW 的行为就像 API 管理员一样,但重要的是:不要将 API 管理与 API Gateway 混为一谈。
APIGW 的功能清单- 路由:动态路由规则,网关封装了底层系统并与客户端分离,为客户端提供了与微服务系统进行通信的单个入口点。
- 安全:IAM 权限认证、鉴权、授权、脱敏,流量清洗,后端签名(保证全链路可信调用),IP 黑白名单(非法调用的限制)。
- 缓存:缓存响应结果。
- 监控:记录请求响应数据,API 耗时分析,性能监控。
- 限流:流量控制,错峰流控,可以定义多种限流规则。
- 高可用:API 高可用,负载均衡,容错机制。
- 服务发现。
- 重试策略、熔断。
- 日志、链路追踪。
APIGW 具有以下优势:
- 易于监控:可在微服务网关收集监控数据并将其推送到外部系统进行分析。
- 易于认证:可在微服务网关上进行认证,然后再将请求转发到后端的微服务,从而无需在每个微服务中进行认证。
- 减少了客户端与各个微服务之间的交互次数。
APIGW 实现的注意事项:
- 可能产生的单点故障或者瓶颈。
- 由于通过 APIGW 进行了额外的网络跳转以及复杂性风险,意味着响应时间增长了。
APIGW 中的一些 API 请求直接映射到单个服务的 API 上,可以通过将请求路由到相应的微服务来提供服务。但是,在需要从多个微服务获得结果的复杂 API 操作的情况下,可以通过 API 组合/聚合来提供服务。在需要同步通信的情况下,如果服务彼此依赖,则必须遵循链式组合模式。组合层必须支持很大一部分的集成功能,例如:转换、编排、弹性和稳定性模式。
微服务架构软件系统必须配备特殊的分发器和聚合器功能(或微服务)。分发者负责分解成细粒度的任务,并将这些任务分发给微服务实例。聚合器负责聚合业务工作流从组合微服务中得出的结果。
具备复杂功能的网关会增大测试和部署的难度。强烈建议大家避免在 APIGW 中进行聚合和数据转换。领域专属的功能更应该遵循软件开发实践的定义,在应用程序的代码中完成。Netflix API Gateway Zuul 2 从他们在 Zuul 到原始系统的网关中,删除了许多业务逻辑。
零信任网关近两年安全领域里很火的概念就是零信任(Zero Trust)。在传统的安全领域里面,我们认为边界防护非常重要,所以会用防火墙对进来的流量做一层校验,这个校验其实是命中规则的校验,如果是黑的就把它拒绝掉。那么这个时候就会有一个问题:如果一些规则更新不及时,它就可以穿越防火墙,以前的安全更多是基于边界的防护,过了边界内网是可以畅通无阻的。
但是零信任网关可以彻底解决这个问题,它认为所有的流量都是不安全的,以前的边界防护是非黑即白。现在的零信任安全网关则是非白即黑,你不是白的,那么你就是黑的,所以它是完全基于身份来认证的。一个 API 的请求过来会到身份认证的服务器,第三方的身份认证厂商比如 Author0、OKTA 的身份认证服务器认证你的身份,身份认证过了,请求才可以通过,不然就直接拒绝掉,这是是安全领域的一个趋势。
因为微服务与微服务之间需要有网络通讯,需要有安全可信的认证。传统做法就是把微服务放到一个可信网络环境中,假设网络环境中所有通讯、执行的应用或微服务都是受信的,它们可以自由通讯或交流,可能有一些轻量级的鉴权与授权进行一定的安全防护措施。
但这个模型会带来一种风险,当有微服务入侵到这个可信网络之中,它会对整个微服务体系造成极大的安全隐患,因为可信网络中的内部防范一定程度上是比较欠缺的。
另外,经常会有可信网络与可信网络之间的微服务互相调用或鉴权的问题,常见解决方法是通过 VPC Peering 或者通过 Gateway 网络的网关打通。利用一个可信通道保证微服务与微服务之间的网络层面可信的调用。但同样引出一种问题,比如在另外一个可信网络中被入侵,便可以攻击到其它相连的可信网络,也增大了受攻击的可能性。
在微服务时代,我们不去假设网络是完全可信的环境。因此,提出了一个叫做微服务或应用可信安全,也就是微服务与微服务或者机密文件之间的每一次通讯,都基于身份体系。微服务会提供给它所沟通、协同的目标对象一个身份认证。就好比我们通过浏览器访问 HTTPS 网站,这些网站需要提供证书,我们的微服务也需要提供一个自身的身份认证,这样接收方就可以通过平台进行认证且查看授权。只有这些认证都通过,才会和开始微服务的通讯。
实际上,利用平台的特点在网络层面内部以应用为中心,又建设起一套基于统一身份认证授权的体系。
但这个体系还是比较难构建的,相当于要在不完全受信的网络中,需要有一个可以信任的平台层或中间层,也就类似 PKI 中的 CA 机制。在 HTTPS 上,比如说我们要信任一个 CA,可能需要提前讲证书预置在操作系统中,从安装时就要预置好,才能提供一个更为安全的端到端的可信,否则是无法构建好这个信任链的。
同样的,在云环境中也需要这个机制。云本身是一个可控平台,通过从云最底层的硬件机制,到云上运行的 OS 上,再到最终向上部署微服务的平台层,我们都要建立起来了一个可证的授信链,最终给每一个微服务提供自身的身份 ID 以及授权可证的授权信息,这样微服务才能提供统一可验证、可证实的身份。也就是说在云原生时代,通过平台思维能够给微服务安全提供更大的价值。
另外在平台与平台之间或网络与网络之间,也可以通过平台级别的可信授信来建立关联的关系,让不同平台之间的微服务也能产生信任关系。为了打通不同的平台,有一个开源项目叫做 Spiffe,它提供了统一的标准身份 ID 以及如何统一标准地进行授权信息的可证和授权信息的认证。