KONG是一个基于Nginx的API Gateway。提供了诸如身份认证,权限控制,流量控制,日志等一系列API相关的组件,可谓相当方便。KONG项目首页KONG入门KONG的Github地址KONG Admin API一览KONG插件列表
以Linux RedHat 6.2为例: 从此处下载对应二进制rpm包,按操作安装即可KONG RedHat Release 注意如果yum出现无法获取metalink的错误,sudo vi /etc/yum.repos.d/epel.repo 注释掉所有mirrorlist,取消所有baseurl的注释即可。
KONG是一个API Gateway,顾名思义,就是API的出口。 内部系统的API可以随意编写,但如果要对外服务,就一定需要各种权限控制。
首先,我们写一个Mock API,进行测试之用。
import tornado.ioloopimport tornado.webclass MainHandler(tornado.web.RequestHandler): call_cnt = 0 def get(self): MainHandler.call_cnt+= 1 self.write("GET / %s"%MainHandler.call_cnt) def post(self): MainHandler.call_cnt+= 1 self.write("POST / %s"%MainHandler.call_cnt)class TestHandler(tornado.web.RequestHandler): call_cnt = 0 def get(self): TestHandler.call_cnt += 1 self.write("GET /test %s"%TestHandler.call_cnt) def post(self): TestHandler.call_cnt += 1 self.write("POST /test %s"%TestHandler.call_cnt)def make_app(): return tornado.web.Application([ (r"/", MainHandler), (r"/test", TestHandler) ])if __name__ == "__main__": app = make_app() app.listen(8812) tornado.ioloop.IOLoop.current().start()这是一个用Tornado写的简易REST测试 API,用以下命令后台启动nohup python test_api.py 1>/dev/null 2>log &;
# 测试Endpoint:/curl -i -X GET http://localhost:8812/curl -i -X POST http://localhost:8812/curl -i -X DELETE http://localhost:8812/# 测试Endpoint:/testcurl -i -X GET http://localhost:8812/testcurl -i -X POST http://localhost:8812/testcurl -i -X DELETE http://localhost:8812/test现在我们已经有一个正常工作的REST API了。是时候使用KONG了。
KONG的使用基本和NGINX如出一辙。默认的工作目录是/usr/local/kong,默认的配置文件是/etc/kong/kong.yml。如果需要工作在1024以下的端口,则要求root权限。 KONG的启动命令很简单,就是kong start 但是启动之前需要编辑配置文件。 需要关注的主要是几个点: 发送匿名统计报告,(默认打开,一定要关闭) 后端数据库的配置,(默认Cassandra,建议Postgres) 内存缓存大小配置,(默认128M,建议1G) 出口端口(默认HTTP 8000,HTTPS 8443,建议直接改成80和443) 管理端口(默认8001,我改成8888比较吉利) 配置好之后,启动KONG即可。
KONG的配置完全通过REST API完成,Admin端口在配置文件中可以配置,下面全部使用http://localhost:8888/作为Admin EndPoint 使用什么语言的HTTP库都可以完成这个工作,这里直接使用Linux自带的curl。
第一步,我们需要先注册我们的API 假设我们想把上面那个API挂载到/test路径下, 即用户访问http://localhost/test/ 时,会返回GET / 用户访问http://localhost/test/test 时,会返回GET /test
执行
# 查看当前已经注册的APIcurl -X GET http://localhost:8888/apis/# 注册一个新的APIcurl -i -X POST http://localhost:8888/apis/ -d "name=testapi" -d "request_path=/test" -d "upstream_url=http://localhost:8812/" -d "strip_request_path=true"这里注册URL的几个参数意思是,这个API注册的名字叫testapi。它被挂载在网关的/test路径下,上游转发到http://localhost:8812去处理,转发的时候把前面的/test前缀给去掉。
{"upstream_url":"http:\/\/localhost:8812\/","request_path":"\/test","id":"a302c28c-eb8a-4e53-bac2-9acb68695f3b","created_at":1468379310000,"preserve_host":false,"strip_request_path":true,"name":"testapi"}返回结果表明API创建的结果。一般会返回一个API的ID。 这就表明API注册完成,我们可以测试一下:
curl -i -X GET http://localhost/testcurl -i -X POST https://localhost/test/test --insecure如同我们预期的一样返回正确的结果,说明API已经成功注册。
当然,仅仅把API注册了开放出去,其实也就是把多个API集成到一个EndPoint,实际意义并不大,下面我们来试一试高级一点的功能。
KONG自带插件目前可以分为以下几类: 身份认证,安全,流量控制,分析监控,格式转换,日志。KONG插件列表 有的API完全开放,不需要任何认证,有的API会涉及敏感数据,权限控制需要非常严格。有的API完全不在乎调用频次或者日志,有的则反过来。 值得高兴的是,KONG的插件独立作用于每一个API,不同的API可以使用完全不同的插件。提供了相当灵活的配置策略。
现在我们首先给这个测试API加上基本的权限验证。
curl -X POST http://localhost:8888/apis/testapi/plugins -d "name=key-auth"# 这个时候再去调用这个API就会返回401 Unauthorizedcurl -i -X GET http://localhost/test朴素的API可能压根没有严格的用户概念,端口大开,随便哪个阿猫阿狗都能进来扫一扫看一看。这可不行。 KONG有一个consumer的概念,consumer是全局共用的。 比如某个API启用了key-auth,那么没有身份的访问者就无法调用这个API了。 需要首先创建一个Consumer,然后在key-auth插件中为这个consumer生成一个key。 然后就可以使用这个key来透过权限验证访问API了。
同理,如果另外一个API也开通了key-auth插件,那么这个consumer也是可以通过key-auth验证访问这个API的,如果要控制这种情况,就需要ACL插件。 (认证与权限乃是两个不同的事物)
首先我们创建一个名为test_user的consumer
# 获取所有Consumer列表curl -X GET http://localhost:8888/consumers/# 创建一个新的Consumercurl -X POST http://localhost:8888/consumers/ -d "username=testuser"然后,我们在key-auth插件中为它创建一个key
curl -X POST http://localhost:8888/consumers/testuser/key-auth -d "key=testkey"这次加上apikey首部进行验证,成功调用
curl -i -X GET http://localhost/test --header "apikey: testkey"删除用户
curl -i -X DELETE http://localhost:8888/consumers/testuser删除插件
# 查询API拥有的插件IDcurl -i -X GET http://localhost:8888/apis/testapi/plugins/# 根据插件ID删除插件。curl -i -X DELETE http://localhost:8888/apis/testapi/plugins/e49a2b2e-4c36-4c6a-bd1a-b5b065e63bb8以上是基本的API,Consumer,Plugin的基本介绍。
设置ACL插件
# 给另外一个testapi加上权限验证插件,现在任何通过认证的用户都可以调用此API# 这不是我们所希望的,所以需要加入ACL控制curl -X POST http://localhost:8888/apis/testapi/plugins --data "name=key-auth"# 为用户overseas_test创建ACL群组:overseas_usercurl -X POST http://localhost:8888/consumers/overseas_test/acls \ --data "group=overseas_user"# 为用户overseas_test创建ACL群组:overseas_usercurl -X POST http://localhost:8888/consumers/overseas_test/acls \ --data "group=overseas_user" 相关资源:python入门教程(PDF版)