Kong
Mar 18, 2020 16:00 · 1396 words · 3 minute read
Kong 是什么?
Kong 是一款可伸缩的开源 API 网关。Kong 运行在业务 RESTful API 之前并且支持通过插件来扩展。
Kong 的优势
- 可扩展:只需添加机器即可实现水平伸缩以应对任何负载,同时保持较低的延迟。
- 模块化:通过添加插件来扩展,可以通过 RESTful 管理 API 轻松配置。
- 通吃任何基础架构:随处可运行,无论公有云还是本地环境。
Kong 基于 NGINX 和 Apache Cassandra 或 PostgreSQL 打造,并提供了简单易用的 RESTful API 来配置系统。
请求流程
一旦 Kong 运行,所有 API 请求会先到达 Kong 并被代理至上游 API,Kong 就是每个 API 请求的入口。
Kong 使用指南(CentOS)
1. 部署数据中间件
Kong 需要 Apache Cassandra 或 PostgreSQL 作为数据库:
$ docker run -d --name kong-database \
-p 5432:5432 \
-e "POSTGRES_USER=kong" \
-e "POSTGRES_DB=kong" \
-e "POSTGRES_PASSWORD=kong" \
postgres:9.6
2. 安装 Kong
Kong 支持任何环境的部署,请参考 https://konghq.com/install/?itm_source=website&itm_medium=nav/
$ wget https://bintray.com/kong/kong-rpm/rpm -O bintray-kong-kong-rpm.repo
$ export major_version=`grep -oE '[0-9]+\.[0-9]+' /etc/redhat-release | cut -d "." -f1`
$ sed -i -e 's/baseurl.*/&\/centos\/'$major_version''/ bintray-kong-kong-rpm.repo
$ sudo mv bintray-kong-kong-rpm.repo /etc/yum.repos.d/
$ sudo yum update -y
$ sudo yum install -y kong
3. 初始化数据库
首先将 Kong 默认的配置文件 /etc/kong/kong.conf.default 去掉 .default 后缀,并修改数据库相关配置:
# When not using a database, Kong is said to be in "DB-less mode": it will keep
# its entities in memory, and each node needs to have this data entered via a
# declarative configuration file, which can be specified through the
# `declarative_config` property, or via the Admin API using the `/config`
# endpoint.
database = postgres # Determines which of PostgreSQL or Cassandra
# this node will use as its datastore.
# Accepted values are `postgres`,
# `cassandra`, and `off`.
pg_host = 127.0.0.1 # Host of the Postgres server.
pg_port = 5432 # Port of the Postgres server.
pg_timeout = 5000 # Defines the timeout (in ms), for connecting,
# reading and writing.
pg_user = kong # Postgres user.
pg_password = kong # Postgres user's password.
pg_database = kong # The database name to connect to.
执行 Kong 迁移命令:
$ kong migrations bootstrap -c /etc/kong/kong.conf
Bootstrapping database...
migrating core on database 'kong'...
core migrated up to: 000_base (executed)
core migrated up to: 003_100_to_110 (executed)
core migrated up to: 004_110_to_120 (executed)
core migrated up to: 005_120_to_130 (executed)
core migrated up to: 006_130_to_140 (executed)
core migrated up to: 007_140_to_150 (executed)
core migrated up to: 008_150_to_200 (executed)
migrating hmac-auth on database 'kong'...
hmac-auth migrated up to: 000_base_hmac_auth (executed)
hmac-auth migrated up to: 002_130_to_140 (executed)
migrating oauth2 on database 'kong'...
oauth2 migrated up to: 000_base_oauth2 (executed)
oauth2 migrated up to: 003_130_to_140 (executed)
migrating jwt on database 'kong'...
jwt migrated up to: 000_base_jwt (executed)
jwt migrated up to: 002_130_to_140 (executed)
migrating basic-auth on database 'kong'...
basic-auth migrated up to: 000_base_basic_auth (executed)
basic-auth migrated up to: 002_130_to_140 (executed)
migrating key-auth on database 'kong'...
key-auth migrated up to: 000_base_key_auth (executed)
key-auth migrated up to: 002_130_to_140 (executed)
migrating rate-limiting on database 'kong'...
rate-limiting migrated up to: 000_base_rate_limiting (executed)
rate-limiting migrated up to: 003_10_to_112 (executed)
migrating acl on database 'kong'...
acl migrated up to: 000_base_acl (executed)
acl migrated up to: 002_130_to_140 (executed)
migrating acme on database 'kong'...
acme migrated up to: 000_base_acme (executed)
migrating response-ratelimiting on database 'kong'...
response-ratelimiting migrated up to: 000_base_response_rate_limiting (executed)
migrating session on database 'kong'...
session migrated up to: 000_base_session (executed)
24 migrations processed
24 executed
Database is up-to-date
4. 启动 Kong
$ kong start -c /etc/kong/kong.conf
2020/03/18 15:43:13 [warn] ulimit is currently set to "1024". For better performance set it to at least "4096" using "ulimit -n"
Kong started
$ netstat -ltupn | grep nginx
tcp 0 0 0.0.0.0:8443 0.0.0.0:* LISTEN 15227/nginx: master
tcp 0 0 127.0.0.1:8444 0.0.0.0:* LISTEN 15227/nginx: master
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 15227/nginx: master
tcp 0 0 127.0.0.1:8001 0.0.0.0:* LISTEN 15227/nginx: master
- :8000 - Kong 用户业务 HTTP API
- :8443 - Kong 用户业务 HTTPS API
- :8001 - Kong 管理 HTTP API
- :8444 - Kong 管理 HTTPS API
使用
kong stop
命令即可停止 Kong。
5. 配置上游服务
5.1 启动一个 flask app 作为上游
$ docker run -d --name flask-app \
-p 5000:5000 \
jcdemo/flaskapp:latest
$ curl -X GET http://127.0.0.1:5000
<html><head><title>Docker + Flask Demo</title></head><body><table><tr><td> Start Time </td> <td>2020-Mar-18 03:25:05</td> </tr><tr><td> Hostname </td> <td>d04f1dddbae4</td> </tr><tr><td> Local Address </td> <td>172.18.0.4</td> </tr><tr><td> Remote Address </td> <td>172.18.0.1</td> </tr><tr><td> Server Hit </td> <td>5</td> </tr></table></body></html>#
5.2 调用 Kong 管理 API 添加服务
$ curl -i -X POST http://127.0.0.1:8001/services/ \
--data 'name=flask-app' \
--data 'url=http://127.0.0.1:5000'
HTTP/1.1 201 Created
Date: Wed, 18 Mar 2020 07:57:37 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Server: kong/2.0.2
Content-Length: 290
X-Kong-Admin-Latency: 110
{"host":"127.0.0.1","created_at":1584518257,"connect_timeout":60000,"id":"7f597887-a38c-4fa3-be7b-cbd4c0abf604","protocol":"http","name":"flask-app","read_timeout":60000,"port":5000,"path":null,"updated_at":1584518257,"retries":5,"write_timeout":60000,"tags":null,"client_certificate":null}
5.3 调用 Kong API 添加路由
$ curl -i -X POST http://127.0.0.1:8001/services/flask-app/routes \
--data 'hosts[]=foo.bar.baz'
HTTP/1.1 201 Created
Date: Wed, 18 Mar 2020 08:01:25 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Server: kong/2.0.2
Content-Length: 429
X-Kong-Admin-Latency: 116
{"id":"33a0c14d-a030-4d82-bf23-624db029f76f","path_handling":"v0","paths":null,"destinations":null,"headers":null,"protocols":["http","https"],"methods":null,"snis":null,"service":{"id":"7f597887-a38c-4fa3-be7b-cbd4c0abf604"},"name":null,"strip_path":true,"preserve_host":false,"regex_priority":0,"updated_at":1584518485,"sources":null,"hosts":["foo.bar.baz"],"https_redirect_status_code":426,"tags":null,"created_at":1584518485}#
5.4 测试通过 Kong 来转发请求
$ curl -i -X GET http://127.0.0.1:8000/ \
--header 'Host: foo.bar.baz'
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 351
Connection: keep-alive
Server: Werkzeug/0.14.1 Python/3.7.1
Date: Wed, 18 Mar 2020 08:03:21 GMT
X-Kong-Upstream-Latency: 3
X-Kong-Proxy-Latency: 0
Via: kong/2.0.2
<html><head><title>Docker + Flask Demo</title></head><body><table><tr><td> Start Time </td> <td>2020-Mar-18 03:25:05</td> </tr><tr><td> Hostname </td> <td>d04f1dddbae4</td> </tr><tr><td> Local Address </td> <td>172.18.0.4</td> </tr><tr><td> Remote Address </td> <td>172.18.0.1</td> </tr><tr><td> Server Hit </td> <td>6</td> </tr></table></body></html>#
可以看到 Kong 成功将请求转发至了 #5.2 中通过 url
参数配置的 flask app,Kong 通过 HTTP 请求头中的 Host
来决定转发路径。
6. 使能插件
6.1 配置 key-auth 插件
curl -i -X GET http://127.0.0.1:8001/services/flask-app/plugins/ \
--data 'name=key-auth'
HTTP/1.1 201 Created
Date: Wed, 18 Mar 2020 08:17:49 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Server: kong/2.0.2
Content-Length: 363
X-Kong-Admin-Latency: 6
{"created_at":1584519469,"config":{"key_names":["apikey"],"run_on_preflight":true,"anonymous":null,"hide_credentials":false,"key_in_body":false},"id":"7747d48d-1142-47d1-ba2d-799cf5678201","service":{"id":"7f597887-a38c-4fa3-be7b-cbd4c0abf604"},"enabled":true,"protocols":["grpc","grpcs","http","https"],"name":"key-auth","consumer":null,"route":null,"tags":null}#
6.2 测试插件生效
$ curl -i -X GET http://127.0.0.1:8000/ \
--header 'Host: foo.bar.baz'
HTTP/1.1 401 Unauthorized
Date: Wed, 18 Mar 2020 08:25:22 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
WWW-Authenticate: Key realm="kong"
Content-Length: 41
X-Kong-Response-Latency: 2
Server: kong/2.0.2
{"message":"No API key found in request"}#
因为暂时还未指定 apikey
HTTP 请求头或参数。
7. 添加消费者
7.1 调用 Kong API 创建消费者
$ curl -i -X POST http://127.0.0.1:8001/consumers/ \
--data 'username=crazytaxii'
HTTP/1.1 201 Created
Date: Wed, 18 Mar 2020 08:31:26 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Server: kong/2.0.2
Content-Length: 122
X-Kong-Admin-Latency: 2
{"custom_id":null,"created_at":1584520286,"id":"55b21259-c76c-458f-b7e6-8d4116b2c839","tags":null,"username":"crazytaxii"}#
7.2 为消费者配置凭证
$ curl -i -X POST http://127.0.0.1:8001/consumers/crazytaxii/key-auth \
--data 'key=shamballa'
HTTP/1.1 201 Created
Date: Wed, 18 Mar 2020 08:34:26 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Server: kong/2.0.2
Content-Length: 167
X-Kong-Admin-Latency: 4
{"created_at":1584520466,"consumer":{"id":"55b21259-c76c-458f-b7e6-8d4116b2c839"},"id":"c522bc31-aa5f-455e-89b5-add819941c9d","tags":null,"ttl":null,"key":"shamballa"}#
7.3 测试消费者凭证是否有效
$ curl -i -X GET http://127.0.0.1:8000/ \
--header 'Host: foo.bar.baz' \
--header 'apikey: shamballa'
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 351
Connection: keep-alive
Server: Werkzeug/0.14.1 Python/3.7.1
Date: Wed, 18 Mar 2020 08:35:58 GMT
X-Kong-Upstream-Latency: 3
X-Kong-Proxy-Latency: 2
Via: kong/2.0.2
<html><head><title>Docker + Flask Demo</title></head><body><table><tr><td> Start Time </td> <td>2020-Mar-18 03:25:05</td> </tr><tr><td> Hostname </td> <td>d04f1dddbae4</td> </tr><tr><td> Local Address </td> <td>172.18.0.4</td> </tr><tr><td> Remote Address </td> <td>172.18.0.1</td> </tr><tr><td> Server Hit </td> <td>7</td> </tr></table></body></html>#