Nacos 2.1.0发布,支持特性定制插件
——杨翊
Alibaba Nacos PMC;Apache ShardingSphere PMC
一、Nacos2.1简介
Nacos 全称为 Dynamic Naming and Configuration Service,其目标是更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos 诞生于阿里巴巴2008 年的五彩石项目,在阿里十年双 11 中成长,帮助业务解决微服务的扩展性和高可用问题。
2018 年,在解决了百万实例的扩展性问题之后,阿里决定将 Nacos 开源输出,通过阿里 10 年关于微服务发现和配置管理的能力沉淀,推动整个微服务行业的发展,加速企业数字化转型。
随着Nacos 开源社区的发展,用户越来越多,用户规模越来越大,Nacos 1.0 的 HTTP 架构开始暴露出性能问题,于是我们新增了关于使用 gRPC 作为更高效通信方式的优化,同时也对内核架构进行了大量重构和更新,最终将性能提升了 10 倍。同时, Nacos 也在考虑进行插件化改造,使架构更易于扩展更新,更易用,更能满足不同用户的不同需求。
二、鉴权插件
没有插件化之前,Nacos如何做鉴权?
Nacos 1.2 版本之后加入了简易的账号密码体系,提供给社区进行简单的请求鉴权。如上图所示,客户端通过gRPC或HTTP 发送请求到服务端。用户开启鉴权功能后,在发送请求前,需要在请求中设置如用户名、密码或生成的临时 token,用于标记请求的身份信息。服务端从请求获取到对应的身份信息后,先进行身份验证,比如用户名、密码或 token 验证等,通过之后再进行权限校验,比如是否有读权限或写权限,全部通过后才会进行请求的正式处理。
未插件化之前的鉴权会侵入到所有请求的主流程中,而且其信息非常固定,只支持用户名、密码以及对应生成的 token ,无法满足用户实际使用的需要。同时服务端实现的校验逻辑过于简单,安全性不够。
因此很多用户都有升级的诉求,比如很多公司有自己的员工账号体系或安全系统,需要对 Nacos 源代码进行修改后才能接入他们的安全系统。而 Nacos 社区处于高速发展期,代码变更非常频繁,对于广大用户或运维、开发者而言,维护成本非常高,需要频繁合并社区代码,并且需要解决过程中遇到的冲突问题。
那么,在 2.1 版本添加鉴权插件之后,发生了什么样的改变?
如图所示,请求主链路不变,客户端仍然通过 gRPC 和 HTTP 发送请求到服务端。不同的是,原先为固定的用户名、密码信息作为身份信息注入到请求中,而现在被替换成identity 的抽象,由鉴权插件提供。
客户端在发送请求之前,会有鉴权插件管理器将请求中的资源信息比如配置 ID、服务名提取出来,然后传递到鉴权插件中。鉴权插件的实现可以根据初始化时的配置信息,比如用户名或请求的资源信息,来计算其实际身份信息。身份信息完全由插件定义,可以是不依赖资源的用户密码,也可以是依赖资源的签名信息等。
鉴权插件管理器最后会获取到 identity 信息,之后将这部分信息注入到请求中。服务端收到请求之后,先由鉴权插件管理器读取这部分信息,然后选择对应的插件进行鉴权。鉴权的具体逻辑也由鉴权插件自由实现,Nacos 不再关注鉴权过程,只关注鉴权结果,只要返回的鉴权结果是成功的,请求就会被正常处理。
插件具体实现的注入依赖 Java SPI 机制。插件开发者只需实现对应的插件接口,并且按照 SPI 标准打包放入到对应的 classpath 中,JVM 即可自动将插件注入。
使用插件化后的鉴权,解耦了注入信息行为和生成信息行为,使得Nacos 无需关注信息内容,只需关注注入过程。用户可以根据实际需要来开发对应的鉴权插件和逻辑。这种扩展机制使得用户不需要修改源代码,只需维护插件代码本身,可在 API 不改变的情况下进行 Nacos 升级,不需要改动鉴权相关的代码,极大减少了维护成本。
下面以阿里云 MSE 微服引擎的鉴权插件实现为例,介绍插件化后的鉴权使用。
如上图所示,主链路仍是用户发起请求,客户端通过 gRPC 或 HTTP 的方式发送到服务端。在发送请求之前,鉴权插件管理器从请求中读取到资源信息,传递给鉴权插件——此处为 MSE 实现的阿里云插件。
插件从参数中提取 accessKey 和 secretKey ,再根据这两个 key 和它请求的resource 共同计算带有时效性的签名。而后在 identity 信息中返回 accessKey 和签名,不返回 secretKey。鉴权插件管理器获取到accessKey 和签名之后,将两个信息注入到请求中,请求随即带上了身份信息。
服务端获取到身份信息后提取信息及其资源信息,再选择阿里云服务端的鉴权插件实现,最终调用阿里云AK 服务进行身份验证即可,主要验证accessKey 与签名是否对应,以及签名是否在时效内。之后,调用阿里云的 RAM 服务进行鉴权,看 AK 是否对 resource有操作权限。如果两者都通过,则会对请求进行真正的处理;如果有一个不通过,则请求会被拒绝。
三、配置加密插件
Nacos 2.1 版本之前不支持配置进行加密,传输和存储都是明文。部分对安全性要求很高的用户通常会在发布配置前自行进行加密,获取配置之后再自行进行解密,而这对业务的侵入性很高。
实现加密插件之后,2.1 版本的客户端可以接受用户发布明文配置,然后在客户端中调用插件进行加密。将加密之后的密文配置传输给服务端,服务端再将密文存储到 MySQL 中,即实现了密文发布。客户端读取时会获取到密文,之后再调用插件进行解密,最后返回给用户的应用。
对于使用默认控制台和一些旧版本 SDK 的用户而言,其传输无法进行加密,但是在服务端可以使用加密插件的管理器以及加密插件对配置进行加密,然后进行密文的存储。
同样,因为使用 SPI 机制,用户无需修改源代码,只需管理自己的插件实现。只要插件的 API 没有被修改,就可以平滑地进行 Nacos 升级,无需改变其插件代码,维护成本很低。
以阿里云 MSE 微服引擎的配置加密插件为例,介绍插件化后的配置加密使用。
使用新版本客户端的阿里云配置加密,即可实现用户发布明文,并在客户端中进行加密。本例中,调用阿里云 KMS 服务进行加密以及密文传输、密文存储。然后,客户端调用 KMS 服务进行解密,最后返回给应用。
阿里云MSE 控制台同样也带上了阿里云加密插件。用户的浏览器和MSE 控制台之间通过 HTTPS 协议进行加密传输,在MSE 控制台侧调用阿里云实现的插件 KMS 服务进行加密,再传输到服务端进行存储。两条链路都进行密文传输和密文存储,极大保证了安全性。
四、更多插件支持
未来,我们将在Nacos 2.2.0 版本支持另一个社区呼声很高的多数据源类型插件以支持更多数据源,支持寻址插件以帮助用户动态搭建 Nacos 集群,支持配置操作插件以实现修改配置后可以做一些用户期望的操作,比如白名单、用户配置格式的校验、 webhook 的回调等。
除此之外,更多插件将在Nacos2.3 版本实现。