Kong安装文档
Kong开源版不提供dashboard支持,只有Kong企业版才有该功能。但有第三方控制台Konga同样可以友好地管理Kong Admin API对象,快速安装如下:
docker run -d -p 1337:1337 \
--name konga \
--network=kong-net \
-e DB_ADAPTER=postgres \
-e DB_HOST=kong-database \
-e DB_PORT=5432 \
-e DB_USER=kong \
-e DB_PASSWORD=kong \
-e DB_DATABASE=konga \
pantsel/konga
需求定位是通过网关不仅实现API网关功能,也要能够替代原先Nginx。因此需要的主要功能如下:
Kong网关的主要概念有route、service、upstream、target,其逻辑关系见下图:
当前的负载均衡逻辑为Nginx做负载均衡,服务发版时通过动态模板解析实现:Jenkins自动化脚本修改Nginx的upstream文件实现。例如对某服务的a、b两节点发版时具体逻辑如下:
通过以上逻辑实现服务的无缝发版,但每次节点变动都需要reload一次Nginx。虽然现在的Nginx版本的reload已经支持配置平滑更新,但实际上reload操作依然会造成CPU竞争、Nginx性能降低以及提前关闭HTTP长连接导致部分客户端调用异常。
为了避免以上问题,常见的解决方案如下:
Kong网关对以上两种方案均支持,基于这两种方案,可以对当前上述服务发版流程优化成功以下几种方式:
集成Kubernetes,通过Kubernetes的DNS服务发现实现负载均衡。Kong网关只负责路由匹配、调用者认证、路由鉴权等网关责任,而服务注册发现的逻辑全部交由Kubernetes处理,使Kong网关完全脱离upstream的逻辑处理。
Kong网关提供了API接口,可以通过这些开放的API接口来管理Kong内部的各个对象,例如上线/下线节点target,详见官方文档admin-api/add-target。
# 节点上线
curl -X POST http://127.0.0.1:8001/upstreams/test-upstream/targets \
--data "target=172.17.0.1:8080" \
--data "weight=100"
# 节点下线
curl -X POST http://127.0.0.1:8001/upstreams/test-upstream/targets \
--data "target=172.17.0.1:8080" \
--data "weight=0"
因此可以搭建如上图的架构方案,自行代码实现一个节点监听服务,通过对接注册中心的API来实时监听各个服务节点的状态。当某服务节点上下线后,注册中心将节点上下线事件推送给监听服务,然后监听服务通过Kong的开放API修改该节点对应的Kong中的target对象状态。
通过上述方案从而实现一个注册中心同时管理微服务之间的服务发现和网关到服务的服务发现。此时应用发布流程例如对某服务的a、b两节点发版时具体逻辑如下:
该方案需要配合健康检查使用,具体逻辑与动态模板解析方案基本相同,仅仅是将模板修改操作替换成API请求操作。例如对某服务的a、b两节点发版时具体逻辑如下:
Kong的upstream支持target健康检查,详细文档见health-checks-circuit-breakers。
Kong支持两种健康检查方式,即可以单独使用,也可以组合使用。通过健康检查target的健康状态,被标记为不健康的target不再有请求路由到该节点。
被动健康检查不会将不健康的target标记成功健康状态,需要人工手动标记该target为健康状态从而恢复流量路由到该目标。因此如果需要使用被动健康检查,务必与主动健康检查组合使用,通过主动健康检查自动将恢复响应的target标记为健康状态。
Kong目前仅支持API路由,不支持静态资源映射,为了最简单地方式使Kong实现静态资源访问,可以搭建下图所示的架构。单独搭建一个Nginx服务做静态资源服务器,然后在Kong中将该Nginx服务配置成service并设置路由规则,将静态资源访问请求通过路由规则请求到该Nginx上。
Kong自带限流插件rate-limiting
local function get_identifier(conf)
local identifier
if conf.limit_by == "service" then
identifier = (kong.router.get_service() or
EMPTY).id
elseif conf.limit_by == "consumer" then
identifier = (kong.client.get_consumer() or
kong.client.get_credential() or
EMPTY).id
elseif conf.limit_by == "credential" then
identifier = (kong.client.get_credential() or
EMPTY).id
elseif conf.limit_by == "header" then
identifier = kong.request.get_header(conf.header_name)
elseif conf.limit_by == "path" then
local req_path = kong.request.get_path()
if req_path == conf.path then
identifier = req_path
end
end
return identifier or kong.client.get_forwarded_ip()
end
rate-limiting插件限流逻辑的对象选择关键代码如上,当基于path限流时,该插件的后续处理逻辑有点反常识。正常逻辑下对指定path限流意味着path规则匹配时则限流,path不匹配时不限流,但该插件的逻辑是path规则匹配时限流,path规则不匹配时按调用方ip限流。
且该插件的path匹配规则仅支持单个完全匹配,不支持范围匹配、正则匹配等常见规则。因此如果需要基于path做限流控制,可以对官方插件稍作修改后使用。
计数模式config.policy
支持3种策略:
灰度发布是指通过将更改缓慢推广到一小部分用户,降低在生产环境中引入新软件版本的风险。Kong开源版官方不提供该插件,但有第三方插件支持kong-plugins-canary。
支持通过ip、header、cookie、args四种匹配方案来做灰度流量控制,并支持单个、多个、正则匹配规则。
首先在Kong控制台启用prometheus插件,如下图所示,直接在全局范围启用该插件,关于prometheus插件更多配置详见官方文档。
插件启动后访问KongAdmin的/metrics
地址,如下图所示,则说明prometheus插件启动成功。
prometheus
修改配置文件,将KongAdmin的访问地址添加到targets
值域中,如下图,然后启动prometheus服务。
docker run -d \
--name prometheus \
--network=kong-net \
-p 9090:9090 \
-v /etc/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
访问prometheus的访问地址http://host:9090
后,在搜索栏中输入关键字kong
后如下图自动补全搜索关键字,则表示prometheus成功收集到了Kong的监控数据。
docker run -d \
--name=grafana \
--network=kong-net \
-p 3000:3000 \
grafana/grafana
访问grafana的控制台地址http://host:3000
(默认账号密码admin:admin),需要先关联prometheus服务。如下图,在配置栏添加prometheus数据库,并输入prometheus的服务访问地址http://host:9090
。
prometheus数据库配置完成后,添加Kong的dashboards,直接输入模板ID7424
或者访问
https://grafana.com/grafana/dashboards/7424
下载模板JSON文件后导入均可,如下图。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iN2oAYaN-1616828418728)(https://img.wakzz.cn/202102/N8zKbiCnsX.png)]
最终效果展示: