一文搞懂微服务网关Kong

1 简介

1.1 为什么需要 API 网关?

当使用单体应用程序架构时,客户端(Web 或移动端)通过向后端应用程序发起一次 REST 调用来获取数据。负载均衡器将请求路由给 N 个相同的应用程序实例中的一个。然后应用程序会查询各种数据库表,并将响应返回给客户端。微服务架构下,单体应用被切割成多个微服务,如果将所有的微服务直接对外暴露,势必会出现安全方面的各种问题。

客户端可以直接向每个微服务发送请求,其问题主要如下:

  • 客户端需求和每个微服务暴露的细粒度API不匹配。
  • 部分服务使用的协议不是Web友好协议。可能使用Thrift二进制RPC,也可能使用AMQP消息传递协议。
  • 微服务难以重构。如果合并两个服务,或者将一个服务拆分成两个或更多服务,这类重构就非常困难了。

服务端的各个服务直接暴露给客户端调用势必会引起各种问题。同时,服务端的各个服务可扩展和伸缩性很差。API 网关是微服务架构中的基础组件,位于接入层之下和业务服务层之上,如前所述的这些功能适合在 API 网关实现。

1.2 什么是Kong?

当我们决定对应用进行微服务改造时,应用客户端如何与微服务交互的问题也随之而来,毕竟服务数量的增加会直接导致部署授权、负载均衡、通信管理、分析和改变的难度增加。

面对以上问题,API GATEWAY是一个不错的解决方案,其所提供的访问限制、安全、流量控制、分析监控、日志、请求转发、合成和协议转换功能,可以解放开发者去把精力集中在具体逻辑的代码,而不是把时间花费在考虑如何解决应用和其他微服务链接的问题上。

1.3 为什么使用Kong?

提供类似的API网关不止一家,Kong侧重于解决如下传统方式的四大痛点:

痛点 说明
重复多 在多个微服务中,共通的功能重复,比如认证或者日志相关共通模块
巨石化 单个服务仍然后变成尾大不掉的巨石应用的趋势
影响大 影响较大,很难做到扩展功能而能不影响其他服务
效率低 由于系统限制,导致生产性低下

1.4 Kong的基本架构

Kong 是 Mashape 开源的高性能高可用 API 网关和 API 服务管理层,一款基于 Nginx_Lua 模块写的高可用服务网关,由于 Kong 是基于 Nginx 的,所以可以水平扩展多个 Kong 服务器。通过前置的负载均衡配置把请求均匀地分发到各个 Server,来应对大批量的网络请求。

Kong 主要有三个组件:

  • Kong Server :基于Nginx的服务器,用来接收 API 请求。
  • Apache Cassandra/PostgreSQL:用来存储操作数据。
  • Kong dashboard:官方推荐 UI 管理工具,当然,也可以使用restfull方式管理 admin api。

Kong dashboard 支持的版本

Kong 采用插件机制进行功能定制,插件集(可以是 0 或 N 个)在 API 请求响应循环的生命周期中被执行。插件使用 Lua 编写,基础功能包括:HTTP 基本认证、密钥认证、CORS(Cross-Origin Resource Sharing,跨域资源共享)、TCP、UDP、文件日志、API 请求限流、请求转发以及 Nginx 监控等。

2 安装

2.1 本地部署

2.1.1 配置YUM仓库

1
2
3
4
5
6
sudo yum install -y wget
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 install -y kong

2.1.2 安装PostgreSQL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
yum install -y postgresql11 postgresql11-server

/usr/pgsql-11/bin/postgresql-11-setup initdb
systemctl enable postgresql-11
systemctl start postgresql-11
# 登录psql
sudo su postgres
psql

# 设置密码
postgres=# \password
Enter new password:
Enter it again:
postgres=#

# 创建数据库
CREATE USER kong with password 'kong';
CREATE DATABASE kong OWNER kong;
grant all privileges on database kong to kong;

# 修改安全配置
vim /var/lib/pgsql/11/data/pg_hba.conf
# 修改最下面几行
# "local" is for Unix domain socket connections only
local all all md5
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local replication all md5
host replication all 127.0.0.1/32 ident
host replication all ::1/128 ident

#重启Postgresql
systemctl restart postgresql-11

2.1.3 配置 Kong

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 这里需要提前配置kong配置文件,默认/etc/kong/kong.conf.default
cp /etc/kong/kong.conf.default /etc/kong/kong.conf

# 修改里面的数据库配置,写入用户、密码、数据库、端口等信息
vim /etc/kong/kong.conf

[root@master /]# egrep -v "^#|^$|^[[:space:]]+#" /etc/kong/kong.conf
database = postgres # Determines which of PostgreSQL or Cassandra
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,
pg_user = kong # Postgres user.
pg_password = kong # Postgres user's password.
pg_database = kong # The database name to connect to.

2.1.4 执行 Migration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
[root@master ~]# 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: 001_14_to_15 (executed)
core migrated up to: 002_15_to_1 (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_200 (executed)
migrating hmac-auth on database 'kong'...
hmac-auth migrated up to: 000_base_hmac_auth (executed)
hmac-auth migrated up to: 001_14_to_15 (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: 001_14_to_15 (executed)
oauth2 migrated up to: 002_15_to_10 (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: 001_14_to_15 (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: 001_14_to_15 (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: 001_14_to_15 (executed)
key-auth migrated up to: 002_130_to_140 (executed)
migrating acl on database 'kong'...
acl migrated up to: 000_base_acl (executed)
acl migrated up to: 001_14_to_15 (executed)
acl migrated up to: 002_130_to_140 (executed)
migrating session on database 'kong'...
session migrated up to: 000_base_session (executed)
migrating response-ratelimiting on database 'kong'...
response-ratelimiting migrated up to: 000_base_response_rate_limiting (executed)
response-ratelimiting migrated up to: 001_14_to_15 (executed)
response-ratelimiting migrated up to: 002_15_to_10 (executed)
migrating rate-limiting on database 'kong'...
rate-limiting migrated up to: 000_base_rate_limiting (executed)
rate-limiting migrated up to: 001_14_to_15 (executed)
rate-limiting migrated up to: 002_15_to_10 (executed)
rate-limiting migrated up to: 003_10_to_112 (executed)
35 migrations processed
35 executed
Database is up-to-date

2.1.5 启动

1
2
3
4
5
6
7
8
9
10
11
修改配置文件kong.conf

vim /etc/kong/kong.conf

database=off
[root@master ~]# kong start -c /etc/kong/kong.conf
Kong started
[root@master ~]# kong health
nginx.......running

Kong is healthy at /usr/local/kong

微服务API网关

2.1.6 测试使用

  • 创建一个Service

如我们在术语部分的介绍,服务是上游服务的抽象,可以是一个应用,或者具体某个接口。Kong 提供了管理接口,我们可以通过请求 8001 管理接口直接创建,也可以通过安装的管理界面,实现的效果是一样的。

1
2
3
4
curl -i -X POST \
--url http://139.196.189.67:8001/services/ \
--data 'name=baidu-service' \
--data 'url=https://www.baidu.com/'
  • 创建一个routes

创建好服务之后,我们需要创建具体的 API 路由。路由是请求的转发规则,根据 Hostname 和 PATH,将请求转发。

1
2
3
4
curl -ik -X POST \
--url http://139.196.189.67:8001/services/baidu-service/routes \
--data 'hosts[]=baidu.com' \
--data 'paths[]=/api/baidu'
  • 访问测试
1
curl -k http://139.196.189.67:8000/api/baidu --header 'Host: baidu.com'

2.2 容器部署

2.2.1 部署 PostgreSQL

2.2.1.1 创建网络

1
docker network create kong-net

2.2.1.2 创建数据卷

1
docker volume create pgsql docker volume create kong konga

2.2.1.3 部署 Postgres:

1
2
3
4
5
6
7
➜ docker run -d --name kong-database \ 
--network=kong-net \
-p 54432:5432 \
-e "POSTGRES_PASSWORD=pgsql" \
-v /$your_path/pgsql/data:/var/lib/postgresql/data \
-v /$your_path/pgsql/etc:/etc/postgresql \
postgres:9.6

2.2.1.4 添加数据库信息

1
2
3
4
5
6
7
8
9
10
11
12
docker exec -it kong-database bash 
> su postgres
> psql -h localhost --password
# 输入密码
# 通过一下语句创建账户和数据库
CREATE USER kong password 'kong';
CREATE DATABASE kong OWNER kong;
grant all privileges on database kong to kong;

CREATE USER konga password 'konga';
CREATE DATABASE konga OWNER konga;
grant all privileges on database konga to konga;

2.2.2 部署 Kong

2.2.2.1 准备数据

1
2
3
4
5
6
7
8
➜ docker run --rm \ 
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_PG_USER=kong" \
-e "KONG_PG_PASSWORD=kong" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
kong:latest kong migrations bootstrap

2.2.2.2 启动 Kong

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
➜ docker run -d --name kong \ 
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_PG_USER=kong" \
-e "KONG_PG_PASSWORD=kong" \
-e "KONG_CASSANDRA_CONTACT_POINTS=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

3 代理

3.1 基本信息

8000:此端口是Kong用来监听来自客户端的HTTP请求的,并将此请求转发到您的上游服务。这也是本教程中最主要用到的端口。

8443:此端口是Kong监听HTTP的请求的端口。该端口具有与8000端口类似的行为,但是它只监听HTTPS的请求,并不会产生转发行为。可以通过配置文件来禁用此端口。

8001:用于管理员对KONG进行配置的端口。

8444:用于管理员监听HTTPS请求的端口。

3.2 配置简单代理

3.2.1 创建一个Service

1
2
3
4
curl -i -X POST \
--url http://172.16.60.8:8001/services/ \
--data 'name=example-service' \
--data 'url=https://www.baidu.com'

3.2.2 添加路由

1
2
3
4
curl -i -X POST \
--url http://172.16.60.8:8001/services/example-service/routes \
--data 'hosts[]=baidu.com' \
--data 'paths[]=/proxy/baidu'

image-20201229094749721

3.2.3 访问测试

image-20201229094844287

4 Konga 安装

4.1 准备数据库

1
docker run --network=kong-net --rm pantsel/konga -c prepare -a postgres -u postgresql://konga:konga@kong-database/konga

4.2 部署

4.2.1 容器部署

1
2
3
4
5
6
7
8
9
10
11
docker run -d -p 1337:1337 --name kong-konga \ 
--network=kong-net \
-e "TOKEN_SECRET=${自己随机生成一个}" \
-e "DB_ADAPTER=postgres" \
-e "DB_HOST=kong-database" \
-e "DB_PORT=5432" \
-e "DB_USER=konga" \
-e "DB_PASSWORD=konga" \
-e "DB_DATABASE=konga" \
-e "NODE_ENV=development" \
pantsel/konga

4.2.2 本地部署

1
2
3
4
5
6
7
$ git clone https://github.com/pantsel/konga.git
$ cd konga
$ npm i

# 配置连接文件
.env_example
npm run production

4.3 Konga 连接 Kong

5 身份验证

5.1 什么是身份验证?

API网关身份验证是控制允许使用您的API传输的数据的重要方法。基本上,它使用一组预定义的凭据来检查特定使用者是否有权访问API。

Kong Gateway有一个插件库,这些插件提供了实现API网关身份验证的最广为人知和使用最广泛的方法的简单方法。以下是一些常用的:

  • 基本认证
  • 密钥认证
  • OAuth 2.0身份验证
  • LDAP认证高级
  • OpenID连接

5.2 为什么要使用API网关身份验证?

启用身份验证后,除非客户端首先成功进行身份验证,否则Kong Gateway不会代理请求。

这意味着上游(API)不需要对客户端请求进行身份验证,也不会浪费用于验证凭据的关键资源。

Kong Gateway可以查看所有身份验证尝试(成功,失败等等),从而可以对这些事件进行分类和控制,以证明适当的控制措施已经存在并实现合规性。身份验证还使您有机会确定如何处理失败的请求。这可能意味着仅阻止请求并返回错误代码,或者在某些情况下,您可能仍希望提供有限的访问权限。

5.3 密钥认证(key-auth)

5.3.1 开启密钥认证

在端口上调用Admin API 8001并配置插件以启用密钥身份验证。对于此示例,将插件应用于您创建的b0db420a-d3c3-45ee-8b25-11f3fd8ca283路由。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
curl -X POST http://172.16.60.8:8001/routes/b0db420a-d3c3-45ee-8b25-11f3fd8ca283/plugins --data name="key-auth"

{
"created_at": 1609208272,
"id": "81382fb7-1b7f-478b-848e-965863f36165",
"tags": null,
"enabled": true,
"protocols": ["grpc", "grpcs", "http", "https"],
"name": "key-auth",
"consumer": null,
"service": null,
"route": {
"id": "b0db420a-d3c3-45ee-8b25-11f3fd8ca283"
},
"config": {
"key_names": ["apikey"],
"run_on_preflight": true,
"anonymous": null,
"hide_credentials": false,
"key_in_body": false
}
}

5.3.2 尝试访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
curl -i http://172.16.60.8:8000/api/oss/

HTTP/1.1 401 Unauthorized
Date: Tue, 29 Dec 2020 02:20:20 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
WWW-Authenticate: Key realm="kong"
Content-Length: 45
X-Kong-Response-Latency: 30
Server: kong/2.2.1

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

在Kong代理请求此路由之前,它需要一个API密钥。对于此示例,由于安装了密钥身份验证插件,因此需要首先创建具有关联密钥的使用者。

5.3.3 创建用户

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
curl -i -X POST \
--url http://172.16.60.8:8001/consumers/ \
--data "username=Apiuser"


HTTP/1.1 201 Created
Date: Tue, 29 Dec 2020 02:26:39 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Content-Length: 119
X-Kong-Admin-Latency: 12
Server: kong/2.2.1

{
"custom_id": null,
"created_at": 1609208799,
"id": "c469d8ad-723c-4c95-bbb1-f3a06ba74555",
"tags": null,
"username": "Apiuser"
}

5.3.4 为用户创建密钥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
curl -i -X POST \
--url http://172.16.60.8:8001/consumers/Apiuser/key-auth/ \
--data 'key=xxzx@789'

HTTP/1.1 201 Created
Date: Tue, 29 Dec 2020 02:28:08 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Content-Length: 166
X-Kong-Admin-Latency: 11
Server: kong/2.2.1

{
"created_at": 1609208888,
"id": "315e4864-74a3-4fb9-910a-4b48909371f8",
"tags": null,
"ttl": null,
"key": "xxzx@789",
"consumer": {
"id": "c469d8ad-723c-4c95-bbb1-f3a06ba74555"
}
}

5.3.5 使用密钥访问测试

成功获取到数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
curl -i http://172.16.60.8:8000/api/oss/ -H 'apikey:xxzx@789'
HTTP/1.1 201 Created
Content-Type: application/json; charset=UTF-8
Content-Length: 299
Connection: keep-alive
Server: TornadoServer/5.1.1
Date: Tue, 29 Dec 2020 02:30:00 GMT
Access-Control-Allow-Methods: POST
Access-Control-Allow-Origin: *
X-Kong-Upstream-Latency: 5
X-Kong-Proxy-Latency: 18
Via: kong/2.2.1

{
"requestId": "c00313f2-497d-11eb-a0c9-e6fb0f2261ab",
"timestamp": "2020-12-29T10:30:00.609927",
"status": 201,
"data": "Welcome to use Go2cloud API OSS server. If you want to know about\n more detail of API content. pls can connect our staff worker.\n Thanks!\n ",
"path": "/"
}

5.4 Basic验证(basic-auth)

5.4.1 CLI配置

1、通过以下请求在服务上配置这个插件:

1
2
3
$ curl -X POST http://kong:8001/services/{service}/plugins \
--data "name=basic-auth" \
--data "config.hide_credentials=true"

2、在路由上启用插件:

1
2
3
$ curl -X POST http://kong:8001/routes/{route_id}/plugins \
--data "name=basic-auth" \
--data "config.hide_credentials=true"

5.4.2 Konga管理平台配置

5.4.2.1 为路由添加basic-auth插件

image-20201229104412251

5.4.2.2 创建用户,并设置凭证

image-20201229103436492

image-20201229103450316

5.4.3 通过postman测试

image-20201229104427484

6 安全

6.1 ACL鉴权

6.1.1 启用插件

在服务上启用插件

1
2
3
4
$ curl -X POST http://kong:8001/services/{service}/plugins \
--data "name=acl" \
--data "config.whitelist=group1, group2" \
--data "config.hide_groups_header=true"

在路由上启用插件

1
2
3
4
$ curl -X POST http://kong:8001/routes/{route_id}/plugins \
--data "name=acl" \
--data "config.whitelist=group1, group2" \
--data "config.hide_groups_header=true"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
curl -X POST http://localhost:8001/routes/b0db420a-d3c3-45ee-8b25-11f3fd8ca283/plugins \
--data "name=acl" \
--data "config.whitelist=devops" \
--data "config.hide_groups_header=true"

{
"created_at": 1609210608,
"id": "c0256ae6-271c-44d8-bee3-f11d36e05abb",
"tags": null,
"enabled": true,
"protocols": ["grpc", "grpcs", "http", "https"],
"name": "acl",
"consumer": null,
"service": null,
"route": {
"id": "b0db420a-d3c3-45ee-8b25-11f3fd8ca283"
},
"config": {
"allow": ["devops"],
"hide_groups_header": true,
"deny": null
}
}

6.1.2 访问测试

由于开启ACL鉴权,用户无法再访问该服务

image-20201229110119948

6.1.3 将用户加入授权的devops组

1
2
3
4
5
6
7
8
9
10
11
curl -X POST http://127.0.0.1:8001/consumers/basic/acls --data "group=devops"

{
"created_at": 1609210724,
"id": "6e066cff-b8ea-4d6e-b412-e3d39509c342",
"group": "devops",
"tags": null,
"consumer": {
"id": "7e9ac7ce-5a8e-4bce-8baa-cf09a7aa5c47"
}
}

image-20201229110212389

6.2 IP限制

6.2.1 启用IP限制插件

1、在服务上启用插件

1
2
3
$ curl -X POST http://kong:8001/services/{service}/plugins \
--data "name=ip-restriction" \
--data "config.whitelist=54.13.21.1, 143.1.0.0/24"

2、在路由上启用插件

1
2
3
$ curl -X POST http://kong:8001/routes/{route_id}/plugins \
--data "name=ip-restriction" \
--data "config.whitelist=54.13.21.1, 143.1.0.0/24"

config.whitelist :白名单,逗号分隔的IPs或CIDR范围。
config.blacklist :白名单,逗号分隔的IPs或CIDR范围。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
curl -X POST http://127.0.0.1:8001/routes/b0db420a-d3c3-45ee-8b25-11f3fd8ca283/plugins \
--data "name=ip-restriction" \
--data "config.whitelist=172.16.60.9"

{
"created_at": 1609211384,
"id": "e6ad04af-6484-482c-aea7-2c70243ef835",
"tags": null,
"enabled": true,
"protocols": ["grpc", "grpcs", "http", "https"],
"name": "ip-restriction",
"consumer": null,
"service": null,
"route": {
"id": "b0db420a-d3c3-45ee-8b25-11f3fd8ca283"
},
"config": {
"allow": ["172.16.60.9"],
"deny": null
}
}

6.2.2 测试访问

当前本机器IP地址为: 172.24.107.55

image-20201229111114082

6.2.3 将IP加入白名单

image-20201229111257500

6.2.4 再次测试访问

image-20201229111315203

6.3 爬虫控制

6.3.1 启用爬虫控制插件

1、在服务上启用插件

1
2
$ curl -X POST http://kong:8001/services/{service}/plugins \
--data "name=bot-detection"

2、在路由上启用插件

1
2
$ curl -X POST http://kong:8001/routes/{route_id}/plugins \
--data "name=bot-detection"

config.whitelist :白名单,逗号分隔的正则表达式数组。正则表达式是根据 User-Agent 头部匹配的。
config.blacklist :黑名单,逗号分隔的正则表达式数组。正则表达式是根据 User-Agent 头部匹配的。

7 流量控制

7.1 请求大小限制

阻止输入的请求,其主体大于特定大小的兆字节

7.1.1 启用大小限制

1、在服务上启用插件

1
2
3
$ curl -X POST http://kong:8001/services/{service}/plugins \
--data "name=request-size-limiting" \
--data "config.allowed_payload_size=128"

2、在路由上启用插件

1
2
3
$ curl -X POST http://kong:8001/routes/{route_id}/plugins \
--data "name=request-size-limiting" \
--data "config.allowed_payload_size=128"

3、在消费者中启用插件

1
2
3
4
$ curl -X POST http://kong:8001/plugins \
--data "name=request-size-limiting" \
--data "consumer_id={consumer_id}" \
--data "config.allowed_payload_size=128"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
curl -X POST http://172.16.60.8:8001/routes/b0db420a-d3c3-45ee-8b25-11f3fd8ca283/plugins \
--data "name=request-size-limiting" \
--data "config.allowed_payload_size=-20"

{
"created_at": 1609212809,
"id": "08112606-e023-4d1b-ba76-853832585feb",
"tags": null,
"enabled": true,
"protocols": ["grpc", "grpcs", "http", "https"],
"name": "request-size-limiting",
"consumer": null,
"service": null,
"route": {
"id": "b0db420a-d3c3-45ee-8b25-11f3fd8ca283"
},
"config": {
"size_unit": "megabytes",
"allowed_payload_size": -20
}
}

7.1.2 访问测试

image-20201229113653517

7.2 请求速率限制

速率限制开发人员在给定的时间、分钟、小时、日、月或年的时间内可以发出多少HTTP请求

7.2.1 启用速率限制

1、在服务上启用插件

1
2
3
4
$ curl -X POST http://kong:8001/services/{service}/plugins \
--data "name=rate-limiting" \
--data "config.second=5" \
--data "config.hour=10000"

2、在路由上启用插件

1
2
3
4
$ curl -X POST http://kong:8001/routes/{route_id}/plugins \
--data "name=rate-limiting" \
--data "config.second=5" \
--data "config.hour=10000"

3、在消费者中启用插件

1
2
3
4
5
$ curl -X POST http://kong:8001/plugins \
--data "name=rate-limiting" \
--data "consumer_id={consumer_id}" \
--data "config.second=5" \
--data "config.hour=10000"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
curl -X POST http://172.16.60.8:8001/routes/b0db420a-d3c3-45ee-8b25-11f3fd8ca283/plugins \
--data "name=rate-limiting" \
--data "config.second=2" \
--data "config.hour=10000"

{
"created_at": 1609213117,
"id": "0329fd21-3844-4a84-b325-68282577c78a",
"tags": null,
"enabled": true,
"protocols": ["grpc", "grpcs", "http", "https"],
"name": "rate-limiting",
"consumer": null,
"service": null,
"route": {
"id": "b0db420a-d3c3-45ee-8b25-11f3fd8ca283"
},
"config": {
"minute": null,
"redis_host": null,
"redis_timeout": 2000,
"limit_by": "consumer",
"hour": 10000,
"policy": "cluster",
"month": null,
"redis_password": null,
"second": 2,
"day": null,
"hide_client_headers": false,
"path": null,
"redis_database": 0,
"year": null,
"redis_port": 6379,
"header_name": null,
"fault_tolerant": true
}
}

7.2.2 访问测试

image-20201229114005501

7.3 请求终止

这个插件使用指定的状态码和消息终止传入的请求。这允许(暂时)停止服务或路由(或废弃的API实体)上的通信,甚至阻塞用户

7.3.1 启用请求终止插件

1、在服务上启用插件

1
2
3
4
$ curl -X POST http://kong:8001/services/{service}/plugins \
--data "name=request-termination" \
--data "config.status_code=403" \
--data "config.message=So long and thanks for all the fish!"

2、在路由上启用插件

1
2
3
4
$ curl -X POST http://kong:8001/routes/{route_id}/plugins \
--data "name=request-termination" \
--data "config.status_code=403" \
--data "config.message=So long and thanks for all the fish!"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
curl -X POST http://172.16.60.8:8001/routes/b0db420a-d3c3-45ee-8b25-11f3fd8ca283/plugins \
--data "name=request-termination" \
--data "config.status_code=403" \
--data "config.message=The service is under maintenance"

{
"created_at": 1609213373,
"id": "77c99041-0a99-4388-b4fa-9378791c3839",
"tags": null,
"enabled": true,
"protocols": ["grpc", "grpcs", "http", "https"],
"name": "request-termination",
"consumer": null,
"service": null,
"route": {
"id": "b0db420a-d3c3-45ee-8b25-11f3fd8ca283"
},
"config": {
"status_code": 403,
"content_type": null,
"body": null,
"message": "The service is under maintenance"
}
}

7.3.2 访问测试

image-20201229114344488

7.3.3 备注

  • config.status_code :要发送的响应代码。
  • config.message :如果使用默认响应生成器,则发送的消息。
  • config.body : 要发送的raw响应体,跟config.message相互排斥
  • config.content_type : 为config.body配置raw响应的内容类型,默认:application/json; charset=utf-8

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!