简介
安装
-
https://www.bilibili.com/video/BV1iS4y1p76t/?p=3&vd_source=928c39982102f8db90201a966f230931
-
https://docs.konghq.com/gateway/3.1.x/install/docker/
-
docker network create kong-net
-
kong
包括数据库、与kong容器
# 数据库
docker run -d --name kong-database \
--network=kong-net \
-p 5432:5432 \
-v ~/database/kong_postgresql_data:/var/lib/postgresql/data \
-e "POSTGRES_USER=kong" \
-e "POSTGRES_DB=kong" \
-e POSTGRES_PASSWORD=kong12358 \
postgres:9.6
# 初始化数据库
docker run -d --rm \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_PG_PASSWORD=kong12358" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
kong:latest kong migrations bootstrap
# 启动
docker run -d --name kong \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_PG_PASSWORD=kong12358" \
-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
-
通过http://localhost:8001查看是否成功
-
konga
konga是一个kong的图形化配置页面,方便展示,一定要熟悉kong本身的api,方便以后用脚本。
# 数据库
docker run -d --name konga-database \
--network=kong-net \
-p 5433:5432 \
-v ~/database/konga_postgresql_data:/var/lib/postgresql/data \
-e "POSTGRES_USER=konga" \
-e "POSTGRES_DB=konga" \
-e POSTGRES_PASSWORD=konga12358 \
postgres:9.6
# 初始化
docker run --rm --network=kong-net \
pantsel/konga:latest -c prepare -a postgres -u postgres://konga:konga12358@konga-database:5432/konga
# 启动konga
docker run -d --name konga \
--network=kong-net \
-p 1337:1337 \
-e "DB_ADAPTER=postgres" \
-e "DB_URI=postres://konga:konga12358@konga-database:5432/konga" \
-e "NODE_ENV=production" \
-e "DB_PASSWORD=konga12358" \
pantsel/konga:latest
-
通过http://localhost:1337进行访问,先注册,再创建Connection,将http://192.168.31.xxx/8001键入,点击激活即可。
基本概念
Kong的基本概念要从nginx上出发,先来看看nginx的配置的一段配置
upstream pms-app {
server 192.168.31.231 weight=100;
server 192.168.31.232 weight=100;
}
server {
listen 80;
server_name xxx.xxx.com;
location /pms/ {
proxy_pass http://pms-app;
}
}
这里包括upstream、server、location,下边看看kong的组件
kong组件 | 说明 |
service | service是一种对服务的抽象,一般1:1指向一个upstream,也可以1:1指向一个target |
route | route对应路由,将匹配实际的请求映射到service上 |
upstream | upstream对应一组api节点,实现负载均衡 |
target | target对应一个api节点 |
整个概念图如下:
flowchart TD
client--请求-->route
route --匹配转发N:1--> service
service --转发1:1--> upstream
upstream --负载均衡1:N--> targets
service --转发1:1--> target
路由
参考:https://www.cnblogs.com/jybky/p/11909880.html
基本用法
-
server配置时proxy_pass中/
的用法,带有/
会将location带到下一层。
-
创建upstream
curl -X POST http://localhost:8001/upstreams --data "name=vditor-upstream"
主要参数:
-
name(不能为空,service指向时使用),
-
algorithm(负载规则):默认round-robin。目前支持三种:round-robin, consistent-hashing
, or least-connections
-
healthchecks.active.type:检查目标服务器target的健康方式。一共三类tcp、http、https
-
healthchecks.active.http_path:使用http协议检查target服务是否健康时绑定的路径。该路径可以指向target服务的一个请求地址,用于检测
-
target:指向具体得服务地址或者其他中间件服务。可匹配多个target。在新增target时需设定weight(权重),用于负载。每个新建的target会有一个health指标,用于标记target是否联通健康。就是通过 healthchecks.active.type、healthchecks.active.http_path以及其他参数监测。
-
在upstream下创建target
curl -X POST http://localhost:8001/upstreams/vditor-upstream/targets --data "target=192.168.31.231:8080" --data "weight=100"
-
创建service
curl -X POST http://localhost:8001/services --data name="vditor" --data "host=vditor-upstream" --data "path=/"
host参数对应upstream的名字,一个servie对应一个upstream
主要参数:
-
name:可为空,创建后生成一个id。routes通过id绑定service
-
protocol:请求upstream的协议(http、https)。默认http
-
host:upstream name(一定要和upstream名称保持一致)
-
port:请求upstream的端口(虚拟端口,可自定义)。默认80
-
path:请求upstream的路径。
-
在service中创建route
curl -X POST http://localhost:8001/services/vditor/routes --data "name=vditor-route1" --data "paths[]=/vditor1"
curl -X POST http://localhost:8001/services/vditor/routes --data "name=vditor-route2" --data "paths[]=/vditor2"
主要参数:
-
name:route Name
-
protocols:允许访问该路由的协议;http\https。默认两个都允许
-
methods:匹配该路由的http方法,GET\POST
-
hosts: 匹配该路由的host地址,可以是ip也可以是域名。可以配置多个。如果是域名的话注意需要有域名解析
-
paths:匹配路由访问的路径
-
service.id:指向服务的ids
释疑
-
services中的path与route中的path的关系是什么?
route中的path针对的是client的访问,只有匹配上这个path,才转发给这个services;
services中的path针对的是upstream服务,在转发时,对原来的path进行修改,如:services中path是/
,表明route已匹配上的path不再转发,这也是我们一般的用法,即route中的path只用作对外路由用。如果route中的path也转发,需要将services的path也配置为route的Path。
修改的方法用PATCH:
curl -X PATCH http://localhost:8001/services/vditor --data "path=/"
-
对于Kong与SpringCloudGateway
SpringCloudGateway的基本概念包括:Route、Predicate、Filter。
Route 由路由 ID,转发 URI(服务的路径),一组 Predicate 以一组 Filter 构成;
Predicate表示路由的匹配条件,可以用来匹配请求的各种属性,如请求路径、方法、header 等;
Filter与SpringBoot的Filter类似,包括了处理请求和响应的逻辑;
对比来看,Kong中的Service与SpringCloudGateway中的Route概念相近,Kong中的Route与SpringCloudGateway的Predicate概念相近,Kong中Stream概念是SpringCloudGateway中Route的转发uri。Kong中的插件应该是基于Nginx的Http模块而来的,仅就这一层看,与SpringCloudGateway的Filter接近。
认证
Basic Auth的身份认证
与nginx类似,外围功能通过插件方式加载进系统,下边身份认证、流量控制等都是通过插件来进行,先来看看Basic Auth身份认证
-
关于Basic Auth
Basic Auth是将用户名与密码以Base64编码方式放在Authorization头中进行传输的方式。
-
配置插件
basic-auth插件用于简单的身份认证,它既可以配置在service上,也可以配置在route上,以service为例:
curl -X POST http://localhost:8001/services/vditor/plugins \
--data "name=basic-auth" \
--data "config.hide_credentials=true"
-
配置Consumer
Consumer的概念与用户接近,先创建Consumer,再在Consumer中选择Crendential,在BASIC下创建用户名与密码

-
访问
再次访问时,就会被拦截
jwt方式
-
关于jwt
Basic方式太容易被识破与攻击,于是就有了jwt。jwt是基于对称加密算法的认证算法,它有三部分组成:Header、Payload、Verfify Signature。Header中指明算法,Payload中携带非敏感的用户信息,Verfify Signature携带对称秘钥。
算法如下:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
xxxxxxxxx
)
参考:https://jwt.io/
生成的token,同样是加到Authorization
头中,如下:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbjEyMzQifQ.WQ5DzMkXG8Szxu7zFqsNR41C3YJwK-sBJyByFd9sLEE
User-Agent: PostmanRuntime/7.24.1
Accept: */*
Host: localhost:8000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
-
配置插件
curl -X POST http://localhost:8001/services/vditor/plugins \
--data "name=jwt"
-
创建consumer的jwt凭证
curl -i -X POST http://localhost:8001/consumers/admin/jwt/ \
-d "algorithm=HS256"
-d "key=admin123"
-d "secret=xxxxxxxxx"
-
从jwt官网生成token

key放到payload的iss的value上,security是上边制定的秘钥。
-
从postMan中测试
Authorization中选择Bearer Token,将token复制到后边即可。
- jwt能防止payload被修改,不能防止被人窃取信息
- 网络攻击的基本手段
限流
-
简介
限流的基本算法:计数器、令牌桶、滑动窗口等,Kong提供了Rate Limting插件,实现对请求的限流,支持consumer(默认)、credential、ip三种维度的流控。技术的存储支持local、cluster(默认)、redis3种方式,local是在nginx本地,cluster是存放在PGSQL中。
nginx本身也有流控的模块:ngx_http_limit_req_module,Kong中的更全面。
-
配置插件
每秒访问1次
curl -X POST http://localhost:8001/services/vditor/plugins \
--data "name=rate-limiting" \
--data "config.second=1" \
--data "config.limit_by=ip"
黑白名单
黑白名单指的是对某些ip进行访问控制
-
配置插件
curl -X POST http://localhost:8001/services/vditor/plugins \
--data "name=ip-restriction" \
--data "config.whitelist=54.13.21.1, 143.1.0.0/24"
curl http://192.168.31.231:8000/vditor/p1 \
-H "Authorization:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbjEyMzQifQ.WQ5DzMkXG8Szxu7zFqsNR41C3YJwK-sBJyByFd9sLEE"
whilelist 是白名单,blacklist是黑名单,逗号分割。