API 网关,即API Gateway,是大型分布式系统中,为了保护内部服务而设计的一道屏障,可以提供高性能、高可用的API托管服务,从而帮助服务的开发者便捷地对外提供服务,而不用考虑安全控制、流量控制、审计日志等问题,统一在网关层将安全认证,流量控制,审计日志,黑白名单等实现。网关的下一层,是内部服务,内部服务只需开发和关注具体业务相关的实现。网关可以提供API发布、管理、维护等主要功能。开发者只需要简单的配置操作即可把自己开发的服务发布出去,同时置于网关的保护之下
为什么需要API网关?
在微服务架构之下,服务被拆的非常零散,降低了耦合度的同时也给服务的统一管理增加了难度。如上图左所示,在旧的服务治理体系之下,鉴权,限流,日志,监控等通用功能需要在每个服务中单独实现,这使得系统维护者没有一个全局的视图来统一管理这些功能。API 网关致力于解决的问题便是为微服务纳管这些通用的功能,在此基础上提高系统的可扩展性。如右图所示,微服务搭配上 API 网关,可以使得服务本身更专注于自己的领域,很好地对服务调用者和服务提供者做了隔离
Kong 的插件机制是其高可扩展性的根源,Kong 可以很方便地为路由和服务提供各种插件,网关所需要的基本特性,Kong 都如数支持:
云原生 : 与平台无关,Kong 可以从裸机运行到 Kubernetes
动态路由 :Kong 的背后是 OpenResty+Lua,所以从 OpenResty 继承了动态路由的特性
熔断
健康检查
日志 : 可以记录通过 Kong 的 HTTP,TCP,UDP 请求和响应。
鉴权 : 权限控制,IP 黑白名单,同样是 OpenResty 的特性
SSL: Setup a Specific SSL Certificate for an underlying service or API.
监控 : Kong 提供了实时监控插件
认证 : 如数支持 HMAC, JWT, Basic, OAuth2.0 等常用协议
限流
REST API: 通过 Rest API 进行配置管理,从繁琐的配置文件中解放
可用性 : 天然支持分布式
高性能 : 背靠非阻塞通信的 nginx,性能自不用说
插件机制 : 提供众多开箱即用的插件,且有易于扩展的自定义插件接口,用户可以使用 Lua 自行开发插件
上面这些特性中,反复提及了 Kong 背后的 OpenResty,实际上,使用 Kong 之后,Nginx 可以完全摒弃,Kong 的功能是 Nginx 的父集
Kong 简单易用的背后,便是因为其所有的操作都是基于 HTTP Restful API 来进行的
Kong 提供一个admin-API 基于restful形式的Http请求
Kong 最大特点是可以动态发布服务,无需重载配置文件
Kong4大核心对象,1,upStream,2.targer,service,route
upStream 上游服务器的抽象,类似于nginx的 upStream,功能做负载用的
target 代表了一个物理服务,是 ip + port 的抽象
service 是抽象层面的服务,他可以直接映射到一个物理服务 (host 指向 ip + port),也可以指向一个 upstream 来做到负载均衡;
route 是路由的抽象,他负责将实际的 request 映射到 service
他们的关系如下
upstream 和 target :1 对 n
service 和 upstream :1 对 1 或 1 对 0 (service 也可以直接指向具体的 target,相当于不做负载均衡)
service 和 route:1 对 n
Kong不仅可以动态发布服务,还有一大特色就是可扩展性的插件机制
例如包括gateway需要的一些功能插件,Kong都已经支持(例如,鉴权,限流,日志,监控)等
例如配置一个最简单通过Kong代理的服务
新增一个upstream负载均衡实体
curl -X POST http://localhost:8001/upstreams --data "name=helloUpstream"
新增一个物理服务绑定在upstream实体下
curl -X POST http://localhost:8001/upstreams/{upstream host:port or id}/targets
target 目标服务地址 ip+port
新增一个服务实体绑定在upstream下
curl -X POST http://localhost:8001/services --data "name=hello"
可选参数为 protocol(协议),port (端口),path(转发服务的uri) host(地址)(可配置成Upstream名称)也可以不绑定Upstream直接配置成转发地址
url(简化配置)kong会把拆分成对应的host,protocol,port,path上
新增一个routes实体绑定在一个服务实体上
curl -X POST http://localhost:8001/routes --data "paths[]=/hello" --data "service.id=8695cc65-16c1-43b1-95a1-5d30d0a50409"
必须参数service.id 标识该路由实体转发哪个服务实体上
这一切的配置都不需要重启Kong服务,可以动态的注册发布服务
他们的转发关系如下:
client------>routes---->service---->目标服务
service可以绑定upstream也可以不绑定upstream
如果绑定stream就是通过upstream负载转发到目标服务(host)配置成Upstream的名称
如果不绑定upstream就直接转发目标服务(host)配置成目标地址
Kong 的安装
Kong的安装包含好多种方式如。docker,centos,以下只介绍这两种方式安装:
以docker的方式如下:
1.docker network create kong-net(创建kong 网络环境)
2.创建kong 所依赖的数据库(目前有两种,一是pg,二是Cassandra)以pg举例说明
docker run -d --name kong-database \ --network=kong-net \ -p 5432:5432 \ -e "POSTGRES_USER=kong" \ -e "POSTGRES_DB=kong" \ postgres:9.6
3.准备数据库
docker run --rm --network=kong-net -e "KONG_DATABASE=postgres" -e "KONG_PG_HOST=kong-database" kong:latest kong migrations bootstrap
4.启动kong服务
docker run -d --name kong --network=kong-net -e "KONG_DATABASE=postgres" -e "KONG_PG_HOST=kong-database" -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" -e "KONG_PROXY_ERROR_LOG=/dev/stderr" -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" -p 8000:8000 -p 8443:8443 -p 8001:8001 -p 8444:8444 kong:latest
8001(http),8444(https)是kong默认的管理API,8000(http),8443(https)默认kong发布服务的端口
CenterOS安装通过rpm安装
yum install epel-release
yum install kong-1.4.1.*.noarch.rpm
安装Kong所需要的数据库pg或者Cassandra
如果用pg
安装好数据库以后
CREATE USER kong; CREATE DATABASE kong OWNER kong;创建kong用户kong数据库
kong migrations bootstrap [-c /path/to/kong.conf] 数据库配置写入Kong的配置文件
启动Kong服务
kong start [-c /path/to/kong.conf] 配置文件随环境更改