我的项目背景
2019 年底,因为公司在业务研发的过程中,遇到了一些业务痛点,比方:公司的开发技术栈是 Java 相干的,而运维工程师善于的则是 Shell 和 Python 脚本,无奈间接对接;公司自身正处于疾速增长期,开发工程师人力不足,无奈声援日常的运维工作及运维平台的开发;在现有的运维平台中,应用了多种开源工具,而且没有整合,较难治理。因而我发动了自动化运维平台的我的项目,心愿通过该运维平台实现疾速上手的开发模型,能够实现运维工程师本人开发业务,并进行疾速的迭代服务。
为什么抉择 Apache APISIX
在进行网关选型时,咱们进行了理论的测试。绝对于其余网关,APISIX 基本上能够达到 NGINX 90% 的性能,并且反对了多种负载平衡策略以及反对多语言插件的机制,同时反对了软 WAF,能够笼罩咱们 95% 的平安业务场景。作为云原生 API 网关,APISIX 也提供了弱小的日志性能,反对自定义日志格局,因而能够间接让 access log 对接 ELK。因为 APISIX 也反对自定义插件的开发,能够依据咱们的需要灵便扩大。得益于 APISIX 的根底性能和弱小的插件体系,能够无效升高开发成本。
自动化运维平台架构
自动化运维平台整体架构图如下:
- 存储层:外围是 CMDB,次要性能是记录和治理组织业务和 IT 资源的属性,以及其它们之间的关系。岂但负责所有业务变更的起始状态查问,而且所有的业务资源的变更都要反馈记录在其中,实现业务标准规范的管控。存储层也蕴含一些权限治理的数据、业务工单的流转数据以及监控告警的时序数据;
- 公共根底服务层:提供原子业务的 API,也能够认为是根底中台,复用了大量的开源工具;
- 业务编排层:须要依据理论业务进行设计,工程师的工作就是把原子业务 API 按需要进行报文适配、流程组合、数据读写,并打包成为接口供前端调用;
- 网关层:APISIX 所在的层,是后盾服务的业务边界,负责负载平衡、服务注册与发现、用户鉴权、根底网络报文数据转码、内外交互日志的对立记录、局部平安管控等等。与业务无关并且通用的服务对立搁置到本层;
- 展现层:从用户角度登程,设计便当的交互界面。此处应用了一个开源的前端全响应式 admin 网页模板,即便开发者(运维)不相熟 JavaScript,也能够本人实现根本的表单和报表。
平台应用的组件
- 外围网关 Apache APISIX:次要负责日志记录、网络安全以及负载平衡。另外咱们岂但通过自定义插件实现了高级业务网关的局部性能,而且还通过 API 能不便的和其余服务整合,疾速实现各种指定性能,无效升高开发成本;
- API 管理工具 YAPI:负责对接口的标准定义,测试用例编写和作为 ACL 的数据源;
- 访问控制组件 Casbin:轻量级、多模式、强范式的跨语言开源访问控制框架,咱们应用的是基于 RESTful 的 PyCasbin;
- 数据存储:MySQL 5.7;
- 自研 Web 框架 mug-skeleton:应用自研的 Web 框架,次要是为了更深层次的技术控制能力。
-
对接的第三方平台相干组件
- CMDB(自研):在开源的 CMDBuild 外包了一层 RESTful 的 API,不便交互;
- OpenLDAP:用于用户的账号验证,不负责鉴权;
- 工作流 Activiti:应用官网的 RestAPI 服务,因为是处于在网关前方,因而不须要思考平安问题。
业务场景
用户登录及权限验证
对于所有的 Web 框架,用户登录是一个必选项,接下来我将为大家介绍此场景。
首先,咱们须要理解下场景中,咱们的应用的相干组件,第一个就是拜访的前端,这个是在网关之外的,其次应用 APISIX 云原生 API 网关作为业务边界。再之后的 Auth 服务,它是自定义开发的微服务,作用是校验前端的 URL 申请和用户登录申请,并对通过认证的用户发放 Token。LDAP 中寄存的是公司外部的明码信息。CMDB 存储的是一些业务的相干信息,包含组织构造,能够拜访的权限的一些组织信息,最初是前端须要拜访的页面。
理解完以上组件后,接下来,为大家介绍整体流程:
用户登录的时候,首先须要通过网关查问,拜访的页面是否在白名单中。因为局部页面是不须要权限验证的,比方:默认页面或者一些谬误页面。如果拜访的页面是须要验证登录的,那么这些申请就会通过相干插件,转发到权限认证服务。
在权限认证中,鉴权服务会依据传入的“用户名”和“明码”,从 LDAP 中查问账号是否正确。如果正确,就会通过 CMDB 查问该用户是属于哪个组织、能够查看哪些功能模块;失去后果后,应用 APISIX 的 JWT 插件,依据用户信息生成一个 Token,并增加过期工夫,返回给前端;用户通过 Cookie 的形式进行 Token 存储。该用户后续如果持续拜访,网关会从 Cookie 中把之前存储的 Token 调进去,验证以后用户是否能够持续拜访前面的页面。
在这里,咱们应用了 APISIX 的 consumer-restriction
插件,上述所讲的权限认证,实际上就是通过 consumer-restriction
插件来实现的,不须要咱们在后盾屡次重复认证。
通过上述的形容,置信大家曾经对失常的申请流程有了肯定的了解,接下来将为大家介绍下如何判断这些用户权限有余的场景。在运维平台中,如果有波及到数据变更的操作,必须要携带 Token,当这个 Token 被 ACL 的接口验证无权拜访后,就会间接返回一个禁止拜访的页面,让前端进行解决。以下是用户登录及权限验证场景的具体流程和其中更应用的相干组件。
新业务微服务接入
在日常工作,咱们常常会上线一些微服务,那么如何让这个微服务接入自动化运维平台呢?
咱们外部会规定无论工程师应用哪种语言开发微服务,都须要应用 YAPI 对 API 进行定义。因而 YAPI 对咱们所有可拜访的那些 URL 进行管控,对立一个入口在这边。因为 YAPI 反对定义各种环境,所以咱们在 YAPI 中定义了不同运行环境。最典型的示例就是:在生产环境中,咱们会应用域名拜访;而在开发环境,就间接应用 127.0.0.1
进行拜访。实现 YAPI 的定义后,它就能够通过 mock 的形式,生成一系列申请用例,十分有利于后续进行生产环境的测试。所有的微服务接口,都能够通过 HTTP 申请的形式进行 mock 调用。
接下来,就是权限治理服务,这里所有的操作都是主动的:它会从 YAPI 中读取 API 的定义,而后生成一系列的 ACL 规定。对于权限的治理,咱们在平台中应用了一个治理页面:管理员能够通过该页面治理 URL 的拜访规定,设置实现后,表单数据就会变更为一系列的 ACL 权限定义,存入数据库中。在服务启动的过程中,平台应用的 cachebin 的拜访模型就会间接从数据库中,把这些规定加载到内存里,而后生成一系列 APISIX 的 Consumer 的定义及路由表,写入 APISIX 的 etcd 中。实现上述操作后,当用户拜访的时候,平台就能够间接通过 APISIX 进行一个权限治理。
该模型岂但实用于自动化运维平台,也同样实用于各种中小型业务体系。
技术细节
通过上述的场景形容,置信大家曾经对整套体系有了大略的意识,接下来为大家介绍下局部技术细节。
因为 APISIX 是基于 NGINX + Lua 实现的,所以局部性能须要通过 NGINX 的库来实现。从上图中,咱们能够看到各种 Lua 脚本能够在哪些点切入到 NGINX 当中。在本文中,次要是为大家介绍 Rewrite/Access 以及 Content 阶段能够进行的操作。
因为在 Rewrite/Access 阶段,报文还没有转给 Upstream,所以能够在该阶段进行各种各样的数据预处理。从上图中咱们能够看到有个 access_by_lua
,在该阶段,能够应用 deny 命令进行权限的治理,包含接口权限以及 IP 准入白名单都能够在该阶段实现。后文所介绍的 acl_plugin.lua
的插件就是在该阶段实现的。
其次在 hard_filet_by_lua
这个阶段,罕用于在申请拜访时,额定的在 HTTP 申请头插入一些 key:value
,供后续应用。例如,当须要咱们线上灰度公布时,就能够在用户的申请头中退出标记位,通过这些标记位,就能够管制这些申请转发哪些后端服务,从而实现灰度公布。当然咱们也能够应用 APISIX 的 traffic-split
插件实现灰度公布。
最初就是 log_by_lua
阶段,在该阶段,咱们能够把一些 trace 信息或者一些故障信息能够间接输出到 log 文件中。同样的,针对 Loggers
,APISIX 也提供了十分多的插件,包含 skywalking-lo
`gger`、`kafka-lo
gger、
rocketmq-logger` 等等。
自定义插件 acl-plugin.lua
acl-plugin.lua
插件的实现非常简单。首先当用户在申请的过程中,咱们会给用户增加相干的 JWT token 存储在 cookie 外面,之后该用户会从拜访的 cookie 中提取 JWT token,而后对该 token 进行解码并获取用户信息。
在 Rewrite 阶段,通过应用用户 ID、method 及 URI,向后盾 ACL 接口发动申请进行权限验证。如果通过了,就会把相干信息记录到 log 中,供当前的平安认证应用。如果失败了,就间接返回一个谬误状态码并记录到 error log 中。
在 APISIX 1.1 版本中,过后 cors
插件还没有公布,因而对于跨域申请,咱们也是通过该插件进行实现,当申请应用 GET 和 POST 的申请办法时,会进行相干的解决。如果是其余申请,则会间接通过,而当初能够间接应用 APISIX 的 cors
插件实现。APISIX 当初也能够应用多种语言进行插件的开发,不仅仅是 Lua,详细信息可参考:https://apisix.apache.org/zh/…。
Auth 服务
Auth 服务是与 acl-plugin.lua
插件配套的认证服务。该服务实现的性能非常简单,次要是读取申请报文中的信息,而后解码出所需的认证元素,之后再把它转发到相干的服务接口中。服务接口会依据认证信息返回相应的后果,APISIX 会依据后果回绝或通过该申请。
Auth 服务中最外围的性能就是从数据库中把 ACL 规定加载到内存外面。次要性能分为两局部:
- 首先
account
接口。该接口次要作用就是:用户拜访的时候,如果须要权限认证,则会通过向 LDAP 服务发送用户的相干信息,进行认证。如果认证通过,则会从 CMDB 中查问出用户可拜访的相干信息,而后和用户角色、过期工夫等元素,一起组成 JWT Token,并生成一个 Cookie 返回给用户,并且同时把该用户信息在 APISIX 中注册一个 Consumer。该接口还实现了一个acl_check
的性能,负责对用户认证信息验证,判断该认证是胜利还是失败。 - 其次是
yapi
接口。该接口的次要作用是与 YAPI 进行交互。因为 YAPI 中有一个是供我的项目拜访的 token,带着这个 token,就能够读取到这个我的项目所有的 API 定义。因而该接口的次要性能,就是从 YAPI 中读取 API 的 HTTP 接口定义,存储到数据库中,而后和权限治理的页面进行一个表单交互,组合成 ACL 表,最初生成一系列 Casbin 的规定存到数据库中。
总结
以上就是同程数科基于 Apache APISIX 的自动化运维平台的架构及局部场景的介绍。当初,APISIX 的性能越来越弱小,曾经反对应用 Wasm 和 Python 进行插件开发。Apache APISIX 的生态也十分弱小,如果大家有任何问题欢送到社区中进行交换探讨。