探究架构之 - 45张图玩转Kong Gateway,建议收藏系列
联系笔者,点击阅读原文
联系笔者,点击阅读原文
联系笔者,点击阅读原文
联系笔者,点击阅读原文
Kong Gateway解决了什么问题?
看上图,常见的我们的服务之间通过rpc相互调用。
如上图的左部分,在没有引入网关之前,为了保障交互的安全,每个服务都需要自己实现一套权限校验(Auth)、日志、限流、监控等方案。这样就不太好,各种成本很高。
引入网关之后呢,像鉴权、监控、安全、限流、日志、缓存等等方案都可以统一由网关实现。各个服务只需要专注于自己的业务实现就OK。
Kong Gateway都有哪些模块?
搞清楚下面的这四点OK:
一、上图中的最下面的两层是:Nginx、Openretry,它的意思是:kong是一款基于OpenRetry(Nginx + Lua) 编写的高可用、易扩展的API Gateway。其实我感觉你可以直接把Kong理解成是Nginx,但是Kong的功能不止于Nginx。
二、上图中间部分的Datastore的意思是:kong的配置文件可以支持化的存储在NoSQL中,可选:cassandra、postgreSQL。
三、上图中的plugin的意思是:如果想拓展kong的功能,只需要提供对应的插件就行。有一些现成的插件可以直接用,可以自定义插件。
四、上图中最上层的Restful的意思是:它支持通过Restful API的方式来操作操作和配置Kong(管理nginx的配置文件)。而且kong有专属的dashboard,支持在可视化的界面下和Restful API交互,实现对kong的可视化配置。
安装Kong
官网doc:https://docs.konghq.com/enterprise/1.5.x/deployment/installation/docker/
选择安装1.5.X版本的kong,因为kong dashboard对高版本的kong还不支持
Step1:下载镜像
docker pull kong:1.5.0-alpine
Step2:给image打tag
~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
kong 1.5.0-alpine a79fdd990557 22 months ago 129MB
~]# docker tag a79fdd990557 kong-oss
Step3:创建一个专属的网络空间,kong及其相关的容器均加入到这个网络中,方便容器间的相互发现和互通
docker network create kong-ee-net
Step4:创建volume,用于将容器的目录挂载到宿主上,防止容器被删后,数据丢失。
docker volume create kong-volume
Step5:启动kong依赖的db容器:运行postgresql数据库
docker run -d --name kong-ee-database \
--network=kong-ee-net \
-p 5432:5432 \
-v kong-volume:/var/lib/postgresql/data \
-e "POSTGRES_USER=kong" \
-e "POSTGRES_DB=kong" \
-e "POSTGRES_PASSWORD=kong" \
postgres:9.6
此时可以使用navicate尝试连接一下postgresql数据库,是可以联通的
Step6:初始化kong需要的数据库
docker run --rm --network=kong-ee-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-ee-database" \
-e "KONG_PG_PASSWORD=kong" \
-e "KONG_PASSWORD=kong" \
kong-oss kong migrations bootstrap
验收结果
Step7:启动Kong网关
docker run -d --name kong \
--network=kong-ee-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-ee-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-oss:latest
备注:
1、KONG_PG_HOST和KONG_PG_USER的值在Step6中可以找到
2、最后的kong-oss:latest,是kong的镜像
3、network是Step3中创建的网络空间
启动成功,验收:
因为我设置的启动参数是:8001:8001
而不127.0.0.1:8001:8001
,所以可以直接通过浏览器访问8001端口查看到kong的源数据信息,如下:
安装Konga
konga提供了对kong的可视化管理能力。
konga本身也需要连接数据库持久化自己的一些数据,所以为它启动一个postgresql
Step1:创建存储卷
docker volume create konga-postgresql
Step2:启动konga
docker run -d --name konga-database \
--network=kong-ee-net \
-p 5433:5432 \
-v konga-postgresql:/var/lib/postgresql/data \
-e "POSTGRES_USER=konga" \
-e "POSTGRES_DB=konga" \
-e "POSTGRES_PASSWORD=konga" \
postgres:9.6
Step3:初始化该数据库
docker run --rm --network=kong-ee-net \
pantsel/konga:latest \
-c prepare \
-a postgres \
-u postgres://konga:konga@konga-database:5432/konga
Step4:启动Konga
docker run -d -p 1337:1337 \
--name konga \
--network=kong-ee-net \
-e "DB_ADAPTER=postgres" \
-e "DB_URI=postgres://konga:konga@konga-database:5432/konga" \
-e "NODE_ENV=production" \
-e "DB_PASSWORD=konga" \
pantsel/konga
验收:http://10.4.7.103:1337/register
Step5:注册用户并登录
可以在konga数据库中看到注册的用户信息
Step6:Konga连接Kong
主页>Connections >NEW CONNECTION
Step7:激活白日梦Kong
Step8:激活后的界面如下:
Kong中的名称概念解释
Service:对应着后端的一个服务,或者是一个App。
Route:路由,不同的route对应着service中的不同接口。
Upstream:和nginx中的upstream擦不多,都对应着一组服务节点。
Target:对应着一个api服务节点。
# upstream 对应kong中的Upstream
upstream default_backend {
# server 对应着Kong中的一个target
server 10.4.4.21:81 max_fails=3 fail_timeout=10s;
server 10.4.4.22:81 max_fails=3 fail_timeout=10s;
}
server {
server_name *.bairimeng.com;
# location / 对应着Kong中的一个route
location / {
proxy_pass http://default_backend;
proxy_set_header Host $http_host;
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
}
}
使用Konga添加一个服务
添加upstream
往service中添加服务实例
添加service
给service添加后端真实的路由
验收访问:http://10.4.7.103:8000/serverAddr
10.4.7.103是kong所在机器的地址
8000是kong对外暴露的接受http请求的端口
如果service的path为/的话,访问路径则是:http://10.4.7.103:8000/serverAddr/serverAddr
Kong身份认证插件
Basic Auth
Kong支持针对Route和Service两种粒度添加Basic Auth认证的方式
比如你添加的Basic Auth插件后,可以去访问该路由去验收结果
需要输入用户名和密码之后才能访问。
这里的用户名密码其实就是Kong中的Consumer的Basic Auth的用户名密码。
Step1:创建Consumer
Step2:为第一步中创建的Consumer创建Basic Auth的用户名密码。
然后使用这个用户名和密码就能验证成功,成功访问该接口。
Jwt
jwt的验证可以在service、route、consumer三个维度上添加。
例如下:
Step1:给单个route添加jwt验证
Step2:给想访问Step1中的route的Consumer添加Jwt凭证
注意记录上面的 key:bairimeng、secret:bairimeng-secret
Step3:使用key和secret签发密钥:https://jwt.io/
验证
1、如果没有执行上面的Step2的话,请求该接口返回值如下:
2、如果jwt非法的话,请求该接口返回值如下:
3、全部正常返回值如下:
Key Auth
key auth 也是Kong提供的一种身份证的身份。
它会对url中的参数key为apikey的值进行校验,如果合法的话则方行。
apikey的具体值需要在consumer中添加
如果没有合法的key,将得到如下的返回值
Kong限流
同样Kong也是通过组件来实现限流操作的
可以把限流组件添加到service、route或者针对某个consumer进行限流
名称 | 作用 |
---|---|
Rate Limiting | 限制访问速率,如:每秒/分/时/月/年 访问次数不能超过 1000次 |
Response Limiting | 有后端服务控制,如:每天会响应10次 |
Request Size Limiting | 限制请求大小,当请求大小超过一定的值时,拒绝请求 |
Request Termination | 临时阻止外界对kong托管的service的访问,返回给外界503和自定义提示信息 |
Proxy Cache |
Kong黑白名单
配置告诉Kong哪些ip是允许访问kong的,以及拒绝哪些ip的访问。
针对Consumer仅能添加下图中的ip黑白名单
针对route、service能添加下图中安全策略
IP Restriction
如果非法的ip,会得到如下的返回值
ACL
它的作用也是限制谁可以访问Kong、谁不可以访问Kong,需要和Basic Auth结合起来使用。
如果仅有Basic Auth的话,效果如下:
如果添加ACL之后,会在仅有Basic Auth的基础上更严格,允许访问的粒度就从:所有的合法用户 细化成了 具体的某个用户或者用户组
如果访问者不在ACL指定的白名单组中的话,返回值如下:
想正常访问接口,需要将consumer加入到上面的whitelist指定的用户组中,如下:
bot-detection
用于过滤请求发送者的设备信息。
如过滤掉来自火狐浏览器的请求如下:
这时火狐浏览访问该接口的话响应如下: