什么是kong Mashape于2015年开源他们的API层:Kong
Kong 官网:https://getkong.org/ 插件介绍,帮助文档等。
Kong 源码:https://github.com/Mashape/kong
Kong是一个云原生、快速、可伸缩及高性能的API网关(在客户端和(微)服务间转发API通信的API网关,通过插件扩展功能)
Kong是一个在Nginx中运行的Lua应用程序,可以通过lua-nginx模块实现, Kong不是用这个模块编译Nginx,而是与OpenRestry一起发布,OpenRestry已经包含了lua-nginx-module,OpenRestry是Nginx的一组扩展功能模块
为什么是kong Kong是一个Api Gateway,通过插件的形式提供负载均衡、日志记录、Http基本认证、密钥认证、API请求限流、请求转换及Prometheus等功能。
Kong可以很轻松扩展功能,模块化,可以运行在任何基础设施上
术语 Route:是请求的转发规则,按照Hostname和PATH,将请求转发给Service Services:是多个Upstream的集合,是Route的转发目标 Consumer:是API的用户,里面记录用户的一些信息 Plugin:是插件,plugin可以是全局的,绑定到Service,绑定到Router,绑定到Consumer Certificate:是https证书 Sni:是域名与Certificate的绑定,指定了一个域名对应的https证书 Upstream:是负载均衡策略 Target:是最终处理请求的Backend服务
kong与 nginx.conf 对应关系
kong与 nginx.conf 对应关系 kong默认端口用途 端口 用途 8000 Kong用来监听来自客户端的HTTP流量,并将其转发到上游服务 8443 Kong用来监听传入的HTTPS流量。此端口具有和8000端口类似的行为,但它仅用于HTTPS流量。可以通过配置文件禁用此端口 8001 Admin API用于接收管理命令 8444 Admin API监听HTTPS流量
路由规则 Kong根据路由中配置的 hosts、paths、methods 等属性匹配请求,这三个属性都是可选的,但是必须指定其中一个,匹配路由的请求需要满足:
请求必须包含路由中配置的所有属性; 对于单个属性,至少匹配属性中的某一个值;
{ "hosts": ["example.com", "foo-service.com"], "paths": ["/foo", "/bar"], "methods": ["GET"] }
首先尝试匹配具有最多规则的路由 Host 匹配示例:GET / HTTP/1.1 Host: service.com -> GET / HTTP/1.1 Host: <my-service-host.com> Paths 匹配规则:最长路径规则,支持正则表达式, Method方法匹配:{ "methods": ["GET", "HEAD"], "service": { "id": "..." } } -> GET / HTTP/1.1 Host: ... HEAD /resource HTTP/1.1 Host:
请求中的 Host 头 基于 Host 头转发请求非常普遍,Kong配置路由的 hosts 属性非常简便,hosts 可传入多个值,使用,分隔,添加多个 hosts 时使用JSON格式:
curl -i -X POST http://localhost:8001/routes/ -H 'Content-Type: application/json' -d '{"hosts":["example.com", "foo-service.com"]}' HTTP/1.1 201 Created ...
现在也支持使用 [ ] 这种方式设置 hosts
curl -i -X POST http://localhost:8001/routes/ -d 'hosts[]=example.com' -d 'hosts[]=foo-service.com' HTTP/1.1 201 Created ...
使用通配符 hostname Kong允许用户在 hosts 属性中使用通配符来提高灵活性,但是不允许在最左侧或最右侧都使用通配符,通配符 hosts 示例:
{ "hosts": ["*.example.com", "service.com"] }
下面这些请求都可以匹配:
GET / HTTP/1.1
Host: an.example.com
GET / HTTP/1.1
Host: service.com
preserve_host 属性 Kong在代理过程中,默认会将上游服务中的 Host 头设置为服务中的 host,可以增加 preserve_host 属性来调整Kong的策略 下面这个示例中,路由中没有设置 preserve_host 属性:
{ "hosts": ["service.com"], "service": { "id": "..." } }
客户端发送请求:
GET / HTTP/1.1 Host: service.com
Kong会提取服务层的 hosts 属性塞入 Host 头,发送给 upstream:
GET / HTTP/1.1
Host: <my-service-host.com>
然而,如果设置了 preserve_host=true :
{ "hosts": ["service.com"], "preserve_host": true, "service": { "id": "..." } }
客户端发送相同的请求:
GET / HTTP/1.1
Host: service.com
Kong会保留客户端带入的 Host 头,发送给 upstream:
GET / HTTP/1.1
Host: service.com
请求路径 还有一种方式是通过请求路径匹配路由,匹配条件是客户端的请求路径的前缀必须满足 paths 属性值中的一个 示例路由如下:
{ "paths": ["/service", "/hello/world"] }
下面这些请求都可以匹配:
GET /service HTTP/1.1
Host: example.com
GET /service/resource?param=value HTTP/1.1
Host: example.com
GET /hello/world/resource HTTP/1.1
Host: anything.com
默认情况下,Kong在转发给 upstream stream 的时候不会更改URL路径,当路由匹配路径时,最长的路径前缀会优先匹配,比如用户可以在路由中定义两个路径:/service和/service/resource,并确保前者不会掩盖后者
在 paths 中使用正则表达式 Kong支持路径使用Perl形式的正则表达式,路径中可以同时包含正则表达式和前缀形式,示例路由如下:
{ "paths": ["/users/\d+/profile", "/following"] }
下面这些请求都可以匹配:
GET /following HTTP/1.1
Host: ...
GET /users/123/profile HTTP/1.1
Host: ...
评估顺序 如上所述,Kong会根据路径的长度做评估,最长前缀路径优先匹配,同时Kong会根据 regex_priority 属性从高到低评估正则表达式的优先级,如下所示这些路由:
[ { "paths": ["/status/\d+"], "regex_priority": 0 }, { "paths": ["/version/\d+/status/\d+"], "regex_priority": 6 }, { "paths": ["/version"], }, { "paths": ["/version/any/"], } ]
这种情况下,Kong会按以下顺序评估传入的URI:
/version/any/ /version /version/\d+/status/\d+ /status/\d+ 前缀路径总是比正则表达式优先评估,并且一个请求还需要同时匹配 hosts 和 methods,Kong会遍历用户配置的路径,找到匹配项最多的一个
kong组件 Kong主要有三个组件:
Kong Server :基于nginx的服务器,用来接收API请求。 Apache Cassandra/PostgreSQL :用来存储操作数据。 Konga:Kong 的一个开源的管理后台,当然,也可以使用 restfull 方式 管理admin api。 Kong采用插件机制进行功能定制,插件集(可以是0或n个)在API请求响应循环的生命周期中被执行。插件使用Lua编写,目前已有几个基础功能:HTTP基本认证、密钥认证、CORS( Cross-origin Resource Sharing,跨域资源共享)、TCP、UDP、文件日志、API请求限流、请求转发以及nginx监控。
不同API网关架构对比 kong认证 kong oauth2插件的使用 kong是不提供用户校验的,所以我们需要自己开发一个backend来做用户的信息校验
认证流程 图例:(线段是对应颜色节点的行为)
绿色client application: 客户端,前端项目 黄色kong: kong / kong dashboard(kong api的GUI项目) 蓝色webapp backend: 待开发的用户验证服务,需要连接用户数据库 紫色resource service: 资源服务 前端请求流程(即上图client application的三条线段): 用户注册也是访问backend服务
请求backend的域名,请求内容是username和password,获取到token及refresh token。 请求资源服务的域名,请求携带token,并获取到数据资源 token过期后,刷新token