红联Linux门户
Linux帮助

使用Kong来管理业务侧restful api

发布时间:2016-11-07 15:39:27来源:linux网站作者:PingLee
导言
Kong是一个集成了Nginx的工具,其专为保护,管理和扩展自己业务侧API而设计。Kong可以充当任何HTTP资源的门户,作为代理服务器或网关,同时通过插件提供了日志记录,身份认证,流量控制等功能。
建议已提前了解过以下技术点和知识
1,正向代理和反向代理的概念
2,Linux系列的系统的命令及其简单操作
3,Nginx的简单运用
4,Lua语言简单语法 
5,CA--证书认证机构
6,restful API的特点
7,Http 基本认证
8,PostgreSQL的简单使用
9,OpenSSL,https协议与http协议的联系,区别
 
一、以Ubuntu Linux 为例子,安装Kong
(1)打开Kong的官网:
https://getkong.org/
点击“Quick Start”,开始进入安装简介页面。
使用Kong来管理业务侧restful api
可以看出,目前Kong能够安装在Linux阵营的系统或者docker等容器内。所以本文档就以UBUNTU为例,讲述Kong的安装特别是Kong的使用和管理Api等内容。
(2)在安装简介页面点击你想安装在哪一种系统或容器中,本文档已ubuntu为例,进行安装:点击Ubuntu图标,进入一个安装包下载页面,选择好自己Ubuntu系统的版本号对应的安装包下载即可。 
使用Kong来管理业务侧restful api
(3)对下载好的安装包,进行安装,可以参考官方提供的以下3句命令:
$ sudo apt-get update  
$ sudo apt-get install netcat openssl libpcre3 dnsmasq procps perl  
$ sudo dpkg -i kong-0.9.3.*.deb  
(4)由于Kong作为一个工具,有部分自己的信息需要数据库进行存储,这样才能正常进行,而目前Kong支持的数据库官方给出的内容是:“Kong supports both PostgreSQL 9.4+ and Cassandra 2.2.x ”,即至少要安装PostgreSQL或者Cassandra两种数据库的其中一种。本文档以PostgreSQL为例子,与Kong进行配置集成。PostgreSQL具体可以参考:
http://www.cnblogs.com/sparkdev/p/5678874.html
(5)安装好PostgreSQL后,需要为Kong创建一个数据库并且需要一个名字为kong的数据库管理员。使用PostgreSQL创建用户和数据库,可以参考下面的代码:
CREATE USER kong; CREATE DATABASE kong OWNER kong;
(6)建立好账号后,需要对Kong进行数据库配置。找到Kong的配置文件kong.conf ,进行连接项修改:
使用Kong来管理业务侧restful api
(7)前面的步骤如果完成了,不出意外,就可以启动Kong了。命令:
sudo kong start --conf /etc/kong/kong.conf
使用Kong来管理业务侧restful api
 
二、将自己的Restful Api加入到Kong中,进行管理
(1)首先,要将自己的restful api服务部署好并启动。例如,我们在172.31.31.128机器上面部署了一套restful API,如下图所示。这套api将作为我们要加入到kong中的一个demo
使用Kong来管理业务侧restful api
(2)查阅Kong的5分钟快速启动指南,或者Kong自身的API文档,准备好使用kong的自身API对自己业务侧的restful API的管控。参考文档的地址如下: 
《Kong-快速加入你的API》: https://getkong.org/docs/0.9.x/getting-started/adding-your-api/
《Kong-Add API》: https://getkong.org/docs/0.9.x/admin-api/#add-api
使用Kong来管理业务侧restful api
由文档中,可以看出,该kong自身的Api中,Post方法的/apis/地址接口,对应的是增加一个(一组)业务侧的api。在列出的6个参数中,其中有几个重要的参数:name,requestpath, upstreamurl
(3)如果Kong成功启动了,那么使用Kong自身的API的话,默认是8001端口。例如上面所说的Kong自身的Post /apis/ 接口,Kong部署到192.168.26.128,则使用它的时候,url为: http://192.168.26.128:8001/apis/ 或者 http://localhost:8001/apis/。
(4)将之前已经部署好的业务侧的API加入到Kong中:
命令:
curl -i -X POST --url http://localhost:8001/apis/ --data 'name=message_api' --data 'upstream_url=https://172.31.31.128:8183/' --data 'request_path=/'  
使用Kong来管理业务侧restful api
这里的upstreamurl 即上游地址,指向之前部署好的业务侧接口API,其中"requestpath=/"代表的是该部署好的服务器下的所有API都被放入kong中受控。name=message_api该参数时给Kong自身的API使用的,相当于一个id。例如调用删除接口或者认证接口的时候需要在url中指定该值作为参数,让Kong一一对应找到它所包含的业务侧API进行相关操作。这样,就相当于kong已经代理好了我们之前在172.31.31.128部署好的业务侧的API。 
(5)通过Kong的反向代理,对业务侧的API进行访问。这个时候,我们只需要在url中填写Kong服务器所在的地址即可:
使用Kong来管理业务侧restful api
由上图可以看出,我们这次url上面的地址是kong的服务器IP地址192.168.26.128 。但实际上访问它的时候,已经可以去到部署到172.31.31.128的业务侧API。这是因为Kong做了反向代理。API的调用方客户可以完全不知道经历了这一个过程。
 
三、将接入到Kong中的业务侧API加上认证管理
(1)使用Kong自带的“key-auth”插件对刚才加入的业务侧API进行认证受控。 命令:
curl -i -X POST --url http://localhost:8001/apis/message_api/plugins --data 'name=key-auth'  
使用Kong来管理业务侧restful api
这个时候如果再次访问上面例子中的GET /users接口的话,就会被禁止,并且提示401说未认证访问的提示。
使用Kong来管理业务侧restful api
(2)同步业务侧的认证数据到kong,让kong去进行api的认证工作。例如业务侧的数据库有appKey和appSecret两个fields作为合法性认证的值。则可以参考使用下面的语句进行同步到kong的配置信息数据库PostgreSQL中:
命令:
curl -i -X POST --url http://localhost:8001/consumers/ --data "username=APPKEY_01"
curl -i -X POST --url http://localhost:8001/consumers/APPKEY_01/key-auth/ --data 'key=BASE64_APPKEY_01_APPSECRET_01'    
我这里只是用了APPKEY01,APPSECRET01这样指代的值,实际操作中,应该填入真实的数据库值信息。并且BASE64_APPKEY01APPSECRET01是指代使用Base64或者其加密的方法得到的一种密文。
(3)对于受控的业务侧API的访问,需要在请求的Header中加入apiKey的参数和之前已经同步给Kong的密文。例如下面这样,填入后,就可以访问了:
使用Kong来管理业务侧restful api
 
四、Kong目前版本及其插件,还不能满足我们Api的一些需求
(1)上面第三节中,我们已经把部署在172.31.31.128服务器的业务侧restful API加入到Kong进行接口的身份认证,这也是我们想要的效果。但同时,这样也意味着,对于这一套业务侧的API的每一个接口,调用方的客户在调用的时候都需要在请求的Header中加入apiKey的参数和之前已经同步给Kong。身份认证通过了,才能够真正访问得到API并返回数据。例如我们的业务侧的API有以下这样的一些典型的restful风格的API:
使用Kong来管理业务侧restful api
像这列表中的一系列的接口,都会被加入到Kong中,通过身份认证后才能访问。
(2)有时候,一些系统中,总会有一些不需要认证就可以直接使用的接口,例如一些系统的注册接口等,因为用户还没有注册,即还没有自己的账号,所以是不需要进行身份认证的。restful 风格的API有一个显著的特点就是,请求的方法不同,代表的接口也是不同的。例如 POST /applications 接口与GET /applications 接口,虽然表面看url是一样的,但实际上却是两个接口。
目前Kong的版本好似只有对一个URL地址下的API进行认证,即只达到路径这一粒度的,还没有做到路径上面还区分不同的方法例如POST、DELETE、GET等区别对待的认证,即“路径+方法”这一粒度的。
例如:
使用Kong来管理业务侧restful api
这样的典型restful api中,目前所有的接口都已经在kong中做了认证受控。但如果对于applications资源,我只希望POST方法这一条api进行特别处理,即不需要认证受控,则目前Kong以及它自带的插好似做不了。
 
五、使用Lua开发自己的Kong插件,过滤请求的Http协议动词
Kong作为一个开源产品,有一个非常吸引人的地方就是可以自由使用插件,并且还可以是使用自己写的插件,满足特定的业务需求。只要使用Lua语音,编写好逻辑,建立好符合Kong规范的lua文件架构,Kong就可以自动装载和识别这些控件,给需要的Api使用。
(1)Kong插件的文件架构
最简单的Kong插件开发,只需要完成handler.lua 和 schema.lua 这两个文件的编码即可。
其中handler.lua文件用于存放插件的需要完成的特定逻辑,而schema.lua相当于配置文件,用于存储一些handler.lua中可能需要用到的可配置变量的值。
(2)Kong的插件一般存放在以下系统目录下(以Ubuntu系统为例):/usr/local/share/lua/5.1/kong/plugins/ ,我们使用目录列表语句,可以查阅到该文件夹下到底有哪些Kong的插件:
使用Kong来管理业务侧restful api
Kong有自动检查插件的机制,只要我们在这个路径下,新建一个有一定含义来命名的文件夹,并将handler.lua 和 schema.lua放入该文件夹内,则Kong就会自动扫描到并添加这一个插件,而且插件的名称就是该文件夹的名称。例如该路径下有一个命名为“key-auth”的文件夹,其就是之前我们所用到的“key-auth”插件。
(3)仿造“kye-auth”插件,改写为满足自己需求的新插件。 Kong作为一个开源产品,它的内部的插件也是开放源代码的。我们可以直接查阅它们的逻辑代码甚至改写。首先,我们可以在Kong的插件路径下,新建一个“new-key-auth”的文件夹,然后将key-auth插件的所有的源码文件都copy到该文件夹下。
参考命令:
sudo mkdir new-key-auth 
sudo cp -a ./key-auth/* ./new-key-auth
由于key-auth插件只做到了路径这一级粒度的认证,没有做到路径+Http方法这一级粒度的认证,所有,我们就参考模仿它,然后把Http方法加上去!
首先在schema.lua中新增一些关于不需要认证的Http方法的配置: 参考代码:
local function default_key_names(t)
if not t.key_names then
return {"apikey"}
end
end
-- new default value function
local function default_not_need_auth_http_methods(t)
if not t.not_need_auth_http_methods then
return {"POST"}
end
end
return {
no_consumer = true,
fields = {
key_names = {required = true, type = "array", default = default_key_names},
hide_credentials = {type = "boolean", default = false},
-- new field
not_need_auth_http_methods = {required = true, type = "array", default = default_not_need_auth_http_methods}
}
}
这里我们新增了一个default_not_need_auth_http_methods(t)方法,以及一个not_need_auth_http_methods的配置。我们这里默认"POST"的Http方法不需要认证
接着,我们在handler.lua中,找到function KeyAuthHandler:access(conf)这一方法,将这些配置加入到逻辑判断中:
参考代码:
function KeyAuthHandler:access(conf)
KeyAuthHandler.super.access(self)
local request_method = string.upper(ngx.req.get_method())
local need_auth_flag = true
for k, val in ipairs(conf.not_need_auth_http_methods) do
if string.upper(val) == request_method then 
need_auth_flag = false
end
end
if need_auth_flag == true then
if type(conf.key_names) ~= "table" then
ngx.log(ngx.ERR, "[key-auth] no conf.key_names set, aborting plugin execution")
return
end
.......
set_header(constants.HEADERS.CONSUMER_ID, consumer.id)
set_header(constants.HEADERS.CONSUMER_CUSTOM_ID, consumer.custom_id)
set_header(constants.HEADERS.CONSUMER_USERNAME, consumer.username)
ngx.ctx.authenticated_credential = credential
ngx.ctx.authenticated_consumer = consumer
end
end
return KeyAuthHandler
这里有一行代码是 local requestmethod = string.upper(ngx.req.getmethod()) 其中ngx.req.getmethod() 这一方法是使用了lua-nginx-module API 的函数,能获取到该次请求的Http动词方法。然后拿这一方法的值与配置的值想比较,看看是否需要身份认证才能往下执行业务侧的API。
保存好handler.lua 和 schema.lua这两个文件,去kong的配置文件中,找到customplugins一栏,将该控件设为可用:
使用Kong来管理业务侧restful api
然后我们为之前方法为http POST时候不需要认证的Api加入该新的插件:
参考代码:
curl -i -X DELETE --url http://localhost:8001/apis/message_not_need_auth_api  
curl -i -X POST --url http://localhost:8001/apis/ --data 'name=message_applications_api' --data 'upstream_url=https://172.31.31.128:8183/' --data 'request_path=/applications'  
curl -i -X POST --url http://localhost:8001/apis/message_applications_api/plugins --data 'name=new-key-auth'  
这样,我们就为/applications 这一路径的restful Api加入了自己的认证逻辑,即POST /applications 这一注册应用的接口不需要身份认证,其他的例如DELETE /applications 等接口,需要进行身份认证。
使用Kong来管理业务侧restful api
 
六、使用Kong自带的插件进行Api请求的流控管理
许多需要对外开放的Api,都需要进行流控设置。Kong提供的插件中,就有这样的帮助restful Api进行流控功能的插件。kong的流控插件有分为调用次数限制的Rate Limiting插件和请求流量限制的Request Size Limiting插件。这里我们介绍调用次数限制的Rate Limiting插件。
(1)Rate Limiting插件简介
Rate Limiting是对Http请求的次数,按照年,月,日,时,分,秒的粒度进行设置,可以设置多个粒度,但至少要设置一个。例如,我们可以为一个API设置每分钟最多累计调用100次,每小时最多累计调用1000次,这样就需要设置config.minute=100 和 config.hour=1000。如果用户们1分钟内调用超过100次的时候,Kong则会返回Http 429调用过快的状态码,需要下一分钟才能调用。如果1小时累计超过1000次,则需要等待到下一小时(以该次调用的前999次的调用的时间差为准)
(2)为自己业务侧的restful Api加入Rate Limiting插件 选择需要进行流控限制的restful Api组,例如/applications,将其加上Rate Limiting插件。例如限制每分钟5000次调用:
参考命令:
curl -i -X POST --url http://localhost:8001/apis/message_applications_api/plugins/ --data "name=rate-limiting" --data "config.minute=5000"  
Kong的api返回类似下面这样的提示,则表示成功:
使用Kong来管理业务侧restful api
当请求api的次数过快的时候,Kong会返回HTTP 429状态码提示:
使用Kong来管理业务侧restful api
 
本文永久更新地址://m.ajphoenix.com/linux/25800.html