用Kong搭建一个微服务API网关

从微服务到API网关

近年来微服务受到越来越多国内企业的青睐。当企业现有系统的复杂度、维护和扩展成本成为业务发展瓶颈时,微服务可以帮助企业拆分、解耦现有的系统,从而提高系统的可维护和可扩展性。Airbnb、Dropbox、Twitter等互联网公司,在使用微服务架构之后,功能发布周期减少了75%。1

微服务生态圈涉及到从软件发布到系统监控的各个方面:

微服务的核心在于根据业务和具体粒度划分API,那么如何管理API就显得尤为重要。

关于API的管理,这边文章要讲的是Kong, 它是个可扩展的开源API网关2,起初是用来管理 Mashape 公司15000个微服务的,后来在2015年开源,现在已经在很多创业公司、大型企业和政府机构中广泛使用。

Kong解决的问题,优势适用场景

微服务上层会有许多消费者(网站、移动端、甚至物联网设备),而这些消费者可能会依赖一些共同的基础服务,kong可以作为API网关提供一些插件来实现这些基础功能,比如登录,权限认证等。

相比其他的API管理平台,Kong有以下优点:3

  • 开源:企业可以免费使用
  • 基于Nginx内核:代理性能高
  • 可定制:可以编写自定义插件
  • 数据私有:数据存储在用户自己的数据库
  • 易扩展:kong的节点无状态
  • 可集成:很多插件可以和第三方的服务集成

kong可以链接系统内部之间的微服务,可以接入第三方的API服务,当然也可以开放公有API

用homebrew在mac环境上搭建Kong

安装openssl
$ brew install openssl
$ brew link --force openssl
安装kong4
$ brew tap mashape/kong
$ brew install kong
安装 postgres

kong0.8.3 只支持两种数据库PostgreSQL 9.4+ 和 Cassandra 2.2.x, 本文用postgres

$ brew install postgres
启动 postgres
$ brew tap homebrew/services
$ brew services start postgres
创建数据库 kong
在mac上用当前用户,在linux上可以通过adduser创建指定用户
$ createdb -h localhost -p 5432 -U "`users`" kong
创建kong的配置文件kong.yml
$ cd /etc && mkdir kong && sudo chmod 666 kong
$ cd kong && sudo curl -O "https://raw.githubusercontent.com/Mashape/kong/master/kong.yml"
$ sudo chmod 666 kong.yml
根据创建好的数据修改kong.yml以下配置:
database: postgres
postgres:
  host: "127.0.0.1"
  port: 5432
  database: kong
  user: <USER>
  password: ""
启动 kong
$ kong start # 返回[OK] Started,说明启动成功

kong会默认会监听两个端口:

  • :8000 - API请求代理端口
  • :8001 - API配置端口 (RESTful Admin API)
$ curl 127.0.0.1:8001 # 或者通过浏览器访问 http://127.0.0.1:8001
如何使用kong
  • 给kong注册一个api(或网址)
$ curl -i -X POST \
  --url http://localhost:8001/apis/ \
  --data 'name=yichicloud' \
  --data 'upstream_url=http://yichicloud.com/' \
  --data 'request_host=yichicloud.com'
  • 确认api注册成功
HTTP/1.1 201 Created
...
{
  "request_host": "yichicloud.com",
  "upstream_url": "http://yichicloud.com/",
  "id": "2eec1cb2-7093-411a-c14e-42e67142d2c4",
  "created_at": 1428456369000,
  "name": "yichicloud"
}
  • 通过kong转发请求
$ curl -i -X GET \
  --url http://localhost:8000/ \
  --header 'Host: yichicloud.com'
  • 为指定api安装plugin (key-auth plugin)
$ curl -i -X POST \
  --url http://localhost:8001/apis/yichicloud/plugins/ \
  --data 'name=key-auth'
  • 安装成功返回
HTTP/1.1 201 Created
...
{"api_id":"5d88e0cd-8af9-441e-9b37-e3ce0a0391c3","id":"bbb17b96-dbb2-4f21-bcaa-10cd4c15d68f","created_at":1469679790000,"enabled":true,"name":"key-auth","config":{"key_names":["apikey"],"hide_credentials":false}}
  • 通过kong转发需要key-auth的请求
$ curl -i -X GET \
  --url http://localhost:8000/ \
  --header 'Host: yichicloud.com'
  • 返回403结果
HTTP/1.1 403 Forbidden 
...

{"message": "Your authentication credentials are invalid"
  • 为key-auth获取一个apikey
注册一个用户

$ curl -i -X POST \
  --url http://localhost:8001/consumers/ \
  --data "username=张大伟"
注册成功

HTTP/1.1 201 Created
...
{
"username": "张大伟",
  "created_at": 1428555626000,
  "id
 ": "bbdf1c48-19dc-4ab7-cae0-ff4f59d87dc9"
}
  • 给用户分配一个apikey
$ curl -i -X POST \
  --url http://localhost:8001/consumers/张大
  伟/key-auth/ \
  --data 'key=this_is_an_api_key'
  
  • 分配成功
HTTP/1.1 201 Created
...
{"created_at":1469680292000,"consumer_id":"bbdf1c48-19dc-4ab7-cae0-ff4f59d87dc9","key":"t
  his_is_an_api_key","id":"02818a81-508f-49f2-a78e-e8cd10bf5bed"}
  • 通过kong转发需要key-auth的请求
$ curl -i -X GET \
  --url http://localhost:8000 \
  --header "Host: yichicloud.com" \
  --header "apikey: this_is_an_api_key"
返回 HTTP/1.1 200 OK

以上

  1. https://www.sequoiacap.com/article/build-us-microservices/ 

  2. http://microservices.io/patterns/apigateway.html 

  3. https://getkong.org/about/advantages/ 

  4. https://github.com/Mashape/homebrew-kong