高性能API网关Kong介绍(下)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高性能API网关Kong介绍(下)相关的知识,希望对你有一定的参考价值。

本文关键词:高性能、API网关、Kong、微服务


4.API Management

在本地配置Kong完毕后,我们来感受一下Kong强大的特性。首先我们有一个简单的API服务,之前已经写好的一个flavors的增删改查,以flavors的查询为例,我们将GET /flavors/detail添加到Kong中。

我们的API server地址是​http://127.0.0.1:8080/flavors/detail​,于是我们有:

· route path: /flavors/detail

· service host: ​http://127.0.0.1:8080

4.1 Add a service

curl -i -X POST \\

  --url http://localhost:8001/services/ \\   --data name=example-flavors\\   --data url=http://127.0.0.1:8080/flavors/detail

得到的响应:

HTTP/1.1 201 Created

Date: Wed, 27 Feb 2019 06:08:25 GMT

Content-Type: application/json; charset=utf-8

Connection: keep-alive

Access-Control-Allow-Origin: *

Server: kong/1.0.3

Content-Length: 273


"host": "127.0.0.1", "created_at": 1551247705, "connect_timeout": 60000, "id": "abba6d52-b239-4b8f-ad11-1e7389d4cf71", "protocol": "http", "name": "example-flavors", "read_timeout": 60000, "port": 8080, "path": "/flavors/detail", "updated_at": 1551247705, "retries": 5, "write_timeout": 60000 

4.2 List current services

curl -i -X GET \\

  --url http://localhost:8001/services/

得到的响应:

HTTP/1.1 200 OK

Date: Wed, 27 Feb 2019 06:11:07 GMT

Content-Type: application/json; charset=utf-8

Connection: keep-alive

Access-Control-Allow-Origin: *

Server: kong/1.0.3

Content-Length: 296


"next": null, "data": [ "host": "127.0.0.1", "created_at": 1551247705, "connect_timeout": 60000, "id": "abba6d52-b239-4b8f-ad11-1e7389d4cf71", "protocol": "http", "name": "example-flavors", "read_timeout": 60000, "port": 8080, "path": "/flavors/detail", "updated_at": 1551247705, "retries": 5, "write_timeout": 60000  ]

可以看到目前就我们前面添加的一个。

4.3 Add a route to service

有了服务之后,我们为服务填一个转发路由:

curl -i -X POST \\

  --url http://localhost:8001/services/example-flavors/routes \\   --data hosts[]=hb.ctyun.com \\   --data paths[]=/flavors/detail \\   --data name=flavor-detail 

得到的响应是:

HTTP/1.1 201 Created

Date: Wed, 27 Feb 2019 06:24:00 GMT

Content-Type: application/json; charset=utf-8

Connection: keep-alive

Access-Control-Allow-Origin: *

Server: kong/1.0.3

Content-Length: 377


"created_at": 1551248640, "methods": null, "id": "11dbb4a1-7452-4d40-a45a-de3f3cad5275", "service": "id": "abba6d52-b239-4b8f-ad11-1e7389d4cf71" , "name": "flavor-detail", "hosts": [ "hb.ctyun.com" ], "updated_at": 1551248640, "preserve_host": false, "regex_priority": 0, "paths": [ "/flavors/detail" ], "sources": null, "destinations": null, "snis": null, "protocols": [ "http", "https" ], "strip_path": true 

原先获取flavors列表,我们是通过:

curl -X GET http://localhost:8080/flavors/detail

而我们现在可以直接通过Kong进行访问,注意,我们必须修改Header,添加指定的Host信息:

curl -X GET http://localhost:8000/flavors/detail -H Host:hb.ctyun.com

结果遇到了报错,提示:

172.18.0.1 - - [27/Feb/2019:06:43:17 +0000] "GET /flavors/detail HTTP/1.1" 502 69 "-" "curl/7.54.0"

2019/02/27 06:43:17 [error] 36#0: *35879 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: kong, request: "GET /flavors/detail HTTP/1.1", upstream: "http://127.0.0.1:8080/flavors/detail", host: "hb.ctyun.com"

可以看到能够按照路由规则进行转发,但是由于网络问题(kong部署在了docker容器中),所以没有办法进行访问。

我们重新创建service、route,并使用​kennethreitz/httpbin​来验证:

# 运行一个容器,将本地的8080的请求转发到容器的80端口

docker run -d --name simple-web-server \\

    --network kong-net \\

    -p 8080:80 kennethreitz/httpbin


# 创建名为demo的service

curl -i -X POST \\

  --url http://localhost:8001/services/ \\

  --data name=demo\\

  --data url=http://simple-web-server/get


HTTP/1.1 201 Created

Date: Wed, 27 Feb 2019 07:51:45 GMT

Content-Type: application/json; charset=utf-8

Connection: keep-alive

Access-Control-Allow-Origin: *

Server: kong/1.0.3

Content-Length: 256


    "host": "simple-web-server",

    "created_at": 1551253905,

    "connect_timeout": 60000,

    "id": "978de8a6-6767-4741-baca-a25c9a131f9d",

    "protocol": "http",

    "name": "demo",

    "read_timeout": 60000,

    "port": 80,

    "path": "/get",

    "updated_at": 1551253905,

    "retries": 5,

    "write_timeout": 60000


# 为service demo配置route规则

curl -i -X POST \\

  --url http://localhost:8001/services/demo/routes \\

  --data hosts[]=api.ctyun.com \\

  --data paths[]=/get \\

  --data name=demo-get


HTTP/1.1 201 Created

Date: Wed, 27 Feb 2019 07:52:40 GMT

Content-Type: application/json; charset=utf-8

Connection: keep-alive

Access-Control-Allow-Origin: *

Server: kong/1.0.3

Content-Length: 361


    "created_at": 1551253960,

    "methods": null,

    "id": "06d6754e-a4ae-4be6-9b87-b64ccfe6c920",

    "service":

        "id": "978de8a6-6767-4741-baca-a25c9a131f9d"

    ,

    "name": "demo-get",

    "hosts": [

        "api.ctyun.com"

    ],

    "updated_at": 1551253960,

    "preserve_host": false,

    "regex_priority": 0,

    "paths": [

        "/get"

    ],

    "sources": null,

    "destinations": null,

    "snis": null,

    "protocols": [

        "http",

        "https"

    ],

    "strip_path": true

然后我们尝试通过访问kong,转发到httpbin:

curl -i -X GET http://localhost:8000/get -H Host:api.ctyun.com


HTTP/1.1 200 OK

Content-Type: application/json

Content-Length: 266

Connection: keep-alive

Server: gunicorn/19.9.0

Date: Wed, 27 Feb 2019 07:56:50 GMT

Access-Control-Allow-Origin: *

Access-Control-Allow-Credentials: true

X-Kong-Upstream-Latency: 9

X-Kong-Proxy-Latency: 84

Via: kong/1.0.3


  "args": ,

  "headers":

    "Accept": "*/*",

    "Connection": "keep-alive",

    "Host": "simple-web-server",

    "User-Agent": "curl/7.54.0",

    "X-Forwarded-Host": "api.ctyun.com"

  ,

  "origin": "172.18.0.1",

  "url": "http://api.ctyun.com/get"

至此,我们已经可以通过来源host、route将请求换发到指定的目标host,并且得到了返回值,这就算完成了基本API转发流程。

4.4 Plugins

Kong提供了非常丰富的插件,都可以在​Kong Hub​​找得到。这里我们简单为我们的服务配置一个​Key Authentication​的plugin。

在服务demo上启用key-auth的插件:

curl -X POST http://localhost:8001/services/demo/plugins \\

    --data "name=key-auth" 

    "created_at": 1551256029,

    "config":

        "key_names": [

            "apikey"

        ],

        "run_on_preflight": true,

        "anonymous": null,

        "hide_credentials": false,

        "key_in_body": false

    ,

    "id": "4eaa000f-0fa2-4b3e-8c13-2db4c6b7ce49",

    "service":

        "id": "978de8a6-6767-4741-baca-a25c9a131f9d"

    ,

    "enabled": true,

    "run_on": "first",

    "consumer": null,

    "route": null,

    "name": "key-auth"

也可以在具体的route上启用插件,比如:

curl -X POST http://<host>:8001/routes/route_id/plugins \\

   --data "name=key-auth" 

我们这里就不再赘述了。

开启插件后,再次访问前面的simple-web-server,则有:

curl -i -X GET http://localhost:8000/get -H Host:api.ctyun.com

HTTP/1.1 401 Unauthorized

Date: Wed, 27 Feb 2019 08:27:13 GMT

Content-Type: application/json; charset=utf-8

Connection: keep-alive

WWW-Authenticate: Key realm="kong"

Content-Length: 41

Server: kong/1.0.3


"message":"No API key found in request"

此时插件key-auth已经开启了,开启之后怎么用呢?要想使用鉴权插件,离不开Consumer。如何创建Consumer并使用指定的插件,我们放到4.5 Add Consumers中尽心更详细的介绍。

4.5 Add Consumers

添加一个consumer,username和custom_id指定任一即可:

curl -i -X POST \\

  --url http://localhost:8001/consumers/ \\   --data "username=<USERNAME>" \\   --data "custom_id=<CUSTOM_ID>"

如:

curl -i -X POST \\

  --url http://localhost:8001/consumers/ \\

  --data "username=elbarco"


HTTP/1.1 201 Created

Date: Wed, 27 Feb 2019 08:47:50 GMT

Content-Type: application/json; charset=utf-8

Connection: keep-alive

Access-Control-Allow-Origin: *

Server: kong/1.0.3

Content-Length: 107


    "custom_id": null,

    "created_at": 1551257270,

    "username": "elbarco",

    "id": "738627ae-57e9-4b20-9d1d-fb12998d5296"

为用户提供一个key:

curl -i -X POST \\

  --url http://localhost:8001/consumers/elbarco/key-auth/ \\

  --data key=hola-elbarco


HTTP/1.1 201 Created

Date: Wed, 27 Feb 2019 09:12:12 GMT

Content-Type: application/json; charset=utf-8

Connection: keep-alive

Access-Control-Allow-Origin: *

Server: kong/1.0.3

Content-Length: 147


    "key": "hola-elbarco",

    "created_at": 1551258732,

    "consumer":

        "id": "738627ae-57e9-4b20-9d1d-fb12998d5296"

    ,

    "id": "b9cb021d-cb37-4841-b172-40ff2dcacb5e"

此时,我们就可以带着鉴权访问前面的simple-web-server了,有两种方式:

curl​​ http://kong:8000/​​proxy path?apikey=<some_key>


curl http://kong:8000/proxy path \\

    -H apikey: <some_key>

我们这里任选一种即可:

curl -i -X GET http://localhost:8000/get -H Host:api.ctyun.com -H apikey:hola-elbarco


HTTP/1.1 200 OK

Content-Type: application/json

Content-Length: 398

Connection: keep-alive

Server: gunicorn/19.9.0

Date: Wed, 27 Feb 2019 09:19:31 GMT

Access-Control-Allow-Origin: *

Access-Control-Allow-Credentials: true

X-Kong-Upstream-Latency: 68

X-Kong-Proxy-Latency: 26

Via: kong/1.0.3


  "args": ,

  "headers":

    "Accept": "*/*",

    "Apikey": "hola-elbarco",

    "Connection": "keep-alive",

    "Host": "simple-web-server",

    "User-Agent": "curl/7.54.0",

    "X-Consumer-Id": "738627ae-57e9-4b20-9d1d-fb12998d5296",

    "X-Consumer-Username": "elbarco",

    "X-Forwarded-Host": "api.ctyun.com"

  ,

  "origin": "172.18.0.1",

  "url": "http://api.ctyun.com/get"

4.6 Rate limiting

额外的,我们再看一下限流插件:​Rate Limiting​。

5.Advanced Features

5.1 Load balancing

Loadbalancing reference

6.Kong Dashboard (From community)

Kong的商业版中,提供了一个可视化界面工具,叫做Kong Manager,功能很是强大,比如:

试用需要申请,我们转而在社区中寻求替代工具,于是在Github上搜到了​Kong Dashboard​,提供了使用npm和docker安装两种方式,这里采用docker的方式安装一下,看看效果:

# Start Kong Dashboard

docker run --rm -p 9090:8080 pgbi/kong-dashboard start --kong-url http://locahost:8001

# Start Kong Dashboard on a custom port

docker run --rm -p [port]:8080 pgbi/kong-dashboard start --kong-url http://kong:8001

# Start Kong Dashboard with basic auth

docker run --rm -p 8080:8080 pgbi/kong-dashboard start \\ --kong-url http://kong:8001   --basic-auth user1=password1 user2=password2


# See full list of start options

docker run --rm -p 8080:8080 pgbi/kong-dashboard start --help 

docker run --rm --name kong-dashboard -p 9090:808i0 pgbi/kong-dashboard start --kong-url http://locahost:8001

docker run --rm  --network kong-net --name kong-dashboard -p 9090:8080 pgbi/kong-dashboard start --kong-url http://kong:8001

Connecting to Kong on http://kong:8001 ...

This version of Kong dashboard doesnt support Kong v0.15 and higher.

受限于Kong的版本:

docker container exec 999a5cf1db1a kong version

1.0.3

我们没办法接入kong-dashboard,后面再进行调研吧。

7.Summary

kong的模型比较清晰,从service、route、plugin到upstream、consumer,通用性比较强,因为插件的存在,功能扩展性也很高。从我们的实际业务触发,也可以参考借鉴这种模型方式,先从核心功能出发。

以上是关于高性能API网关Kong介绍(下)的主要内容,如果未能解决你的问题,请参考以下文章

选择Kong作为你的API网关

请选择Kong作为你的API网关吧!!!

技术干货 | API网关与服务安全最佳实践

Kong api 网关 安装简单应用

开源API网关Kong基本介绍和安装验证

易观API网关—Kong分享篇