Kong动态负载均衡

  • 一、背景
  • 二、通过docker 安装 Kong
  • 三、分布式API网关存在的意义
  • 四、Kong 的相关特性
  • 五、Kong 体系结构
  • 六、Kong 工作流程
  • 七、从 nginx 配置到 Kong 配置
    • 7.1、Kong 核心四对象
    • 7.2、四对象关系
  • 八、插件机制
  • 九、Kong 网关插件
  • 十、使用konga
    • 10.1、实现一个负载均衡器
    • 10.2、实现黑白名单
    • 10.3、实现限流
    • 10.4、实现鉴权验证
  • 总结

一、背景

Kong 是一款基于 openresty 编写的高可用、易扩展的开源 API Gateway 项目。

Kong 支持两种工作模式:一种是不使用数据库;另一种是使用数据库;可用的数据库为 PostgreSQL、Cassandra(分布式NoSQL 数据库)。
官方网站
官方文档
项目地址
中文文档:基于1.1.x版本

二、通过docker 安装 Kong

(1)创建 Kong 网络。创建自定义 Docker 网络以允许容器相互发现和通信:

sudo docker network create kong-net

(2)安装 PostgreSQL。

# 创建 PostgreSQL 容器
sudo docker run -d --name kong-database --network=kong-net -p 5432:5432 -e "POSTGRES_USER=kong" -e "POSTGRES_DB=kong" -e "POSTGRES_PASSWORD=kong" --restart always postgres:9.6# 使用 Kong 容器运行进行数据库初始化
sudo 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:2.5.0 kong migrations bootstrap

(3)创建 Kong 容器。

# -u -root: Kong 启动过程中,需要权限创建一些文件和文件夹
sudo docker run -d --name kong --network=kong-net -u root -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 --restart always kong:2.5.0

(4)搭建和运行Konga。Konga 是 Kong 的可视化 API 操作工具。

# 复用上面的数据库容器
sudo docker run --rm --network=kong-net pantsel/konga:0.14.9 -c prepare -a postgres -u postgresql://kong:kong@kong-database/konga
# 运行 Konga 容器
sudo docker run -d -p 1337:1337 --network=kong-net -e "DB_ADAPTER=postgres" -e "DB_URI=postgresql://kong:kong@kong-database/konga" -e "NODE_ENV=production" --name konga pantsel/konga:0.14.9

(5)测试 Kong 和 Konga。

# 输入下列命令,若返回一个大的 json 串,说明安装成功
curl http://localhost:8001
# 浏览器运行
http://192.168.0.102:1337

三、分布式API网关存在的意义

在微服务架构之下,服务被拆的非常零散,降低了耦合度的同时也给服务的统一管理增加了难度。在旧的服务治理体系之下,鉴权,限流,日志,监控等通用功能需要在每个服务中单独实现,这使得系统维护者没有一个全局的视图来统一管理这些功能。API 网关致力于解决的问题便是为微服务纳管这些通用的功能,在此基础上提高系统的可扩展性。微服务搭配上 API网关,可以使得服务本身更专注于自己的领域,很好地对服务调用者和服务提供者做了隔离。

四、Kong 的相关特性

  1. 云原生:与平台无关,Kong 可以从裸机运行到 Kubernetes。
  2. 动态路由:Kong 的背后是 OpenResty,所以从 OpenResty 继承了动态路由的特性。
  3. 熔断。
  4. 健康检查。
  5. 日志:可以记录通过 Kong 的 HTTP,TCP,UDP 请求和响应。
  6. 鉴权:权限控制,IP 黑白名单,同样是 OpenResty 的特性。
  7. SSL:Setup a Specific SSL Certificate for an underlying service or API。
  8. 监控:Kong 提供了实时监控插件。
  9. 认证:支持 HMAC, JWT,Basic,OAuth2.0 等常用协议。
  10. 限流。
  11. REST API:通过 Rest API 进行配置管理,从繁琐的配置文件中解放。
  12. 可用性:天然支持分布式。
  13. 高性能:利用 nginx 的非阻塞 io 模型。
  14. 插件机制:提供众多开箱即用的插件,且有易于扩展的自定义插件接口,用户可以使用 Lua 自行开发插件。

五、Kong 体系结构

  1. Kong 核心基于 Openresty 构建,实现了请求/响应的 lua 处理化。
  2. Kong 插件拦截请求/响应,等价于拦截器,实现请求/响应的AOP 处理。
  3. Kong Restful 管理 API 提供了 API / API 消费者 / 插件的管理。
  4. 数据中心用于存储 Kong 集群节点信息、API、消费者、插件等信息,目前提供了 PostgreSQL 和 Cassandra支持,如果需要高可用建议使用 Cassandra。
  5. Kong 集群中的节点通过 gossip 协议(redis cluster)自动发现其他节点,当通过一个 Kong 节点的管理 API 进行一些变更时也会通知其他节点。每个 Kong 节点的配置信息是会缓存的,如插件,那么当在某一个 Kong 节点修改了插件配置时,需要通知其他节点配置的变更。

六、Kong 工作流程


API 网关可以通过实现一些中间组件来解决一些问题,这些中间组件的功能就不需要到每个微服务中实现了,这样不同的团队可使用不同的方式来实现了不同的微服务。

API 网关不仅可以帮你解决 API 的管理部分,而且还可以解决下面两件事情:

  1. 分析(Analytics)。API 网关可以和你的分析基础设施保持透明的交互和通信,因为 API 网关是每个请求(request)的入口,必经地。API 网关可以看到所有的数据,可以知道经过你的 service 的流量。这就相当于你有一个集中的地方,你可以把所有的这些信息 push 到你的监控或分析工具,比如 Kibana 或者 Splunk。
  2. 自动化(Automation)。网关有助于自动化部署,还可以实现自动化登入验证。 什么是登入呢? 如果你有 API,并且你希望有身份验证,你可能需要一些功能可以允许用户为该API 创建登入凭据(credentials)然后开始使用(消费)API。 开发人员门户网站或你的文档中心等都可以与网关集
    成来配置这些凭据(credentials),这样就不用从头开始构建一些功能了。

Kong 默认是缺失如 API 级别的超时、重试、fallback 策略、缓存、API 聚合、AB 测试等功能,这些功能插件需要企业开发人员通过 Lua 语言进行定制和扩展。

init_by_lua_block {kong = require 'kong'kong.init() -- 完成 Kong 的初始化,路由创建,插件预加载等
}
init_worker_by_lua_block {kong.init_worker() -- 初始化 Kong 事件,worker之间的事件,由 worker_events 来处理, cluster 节点之间的事件,由 cluster_events 来处理,缓存机制
}
upstream kong_upstream {server 0.0.0.1;balancer_by_lua_block {kong.balancer() --负载均衡}keepalive 60;
}
server {server_name kong;listen 0.0.0.0:8000 reuseport backlog=16384;listen 0.0.0.0:8443 ssl http2 reuseport backlog=16384;rewrite_by_lua_block {kong.rewrite() --插件生效策略的筛选,并执行对应的操作,只能处理全局插件(kong插件级别,全局(作用于所有请求),route(作用于当前路由),service(作用于匹配到当前service的所有请求)),路由匹配未开始。}access_by_lua_block {kong.access() --1.完成路由匹配,2.确认加载的插件(并加入缓存) 3.进入balancer阶段}header_filter_by_lua_block {kong.header_filter() --遍历在缓存中的插件列表,并执行}body_filter_by_lua_block {kong.body_filter() --遍历在缓存中的插件列表,并执行}log_by_lua_block {kong.log() --遍历在缓存中的插件列表,并执行}location / {proxy_pass $upstream_scheme://kong_upstream$upstream_uri;}
}

七、从 nginx 配置到 Kong 配置

nginx:

upstream my_upstream {server 192.168.0.106:3000 weight=100;
}
server {listen 80;location /hello {proxy_pass my_upstream;}
}

Kong:

# 配置 upstream
curl -X POST http://localhost:8001/upstreams --data "name=mark_upstream"
# 配置 target
curl -X POST http://localhost:8001/upstreams/mark_upstream/tar gets --data "target=192.168.31.91:8888" --data "weight=100"
curl -X POST http://localhost:8001/upstreams/mark_upstream/tar gets --data "target=192.168.31.91:9999" --data "weight=100"
# 配置 service
curl -X POST http://localhost:8001/services --data "name=hello" --data "host=mark_upstream"
# 配置 route
curl -X POST http://localhost:8001/routes --data "paths[]=/hello" --data "service.id=15722364-296f-4624-9026-ceff2d2166f2"

7.1、Kong 核心四对象

Kong 涉及到 upstream,target,service,route 概念。

  1. upstream 是对上游服务器的抽象。
  2. target 代表了一个物理服务,是 ip + port 的抽象。
  3. service 是抽象层面的服务,他可以直接映射到一个物理服务(host 指向 ip + port),也可以指向一个 upstream 来做到负载均衡。
  4. route 是路由的抽象,他负责将实际的 request 映射到service。

consumer 是使用 service 的用户,可以为 consumer 添加plugin 插件,从而定义 consumer 的请求行为。

7.2、四对象关系

  1. upstream 和 target :1 : n。
  2. service 和 upstream :1 : 1 或 1 : 0;(service 也可以直接指向具体的 target,相当于不做负载均衡)。
  3. service 和 route:1 : n。

八、插件机制

Kong 的插件机制是 Kong 最核心的功能;Kong 要解决的问题是承担所有服务共同需要的那部分功能;插件可能是作用全局的,也可能是作用局部的,比如大部分插件是作用在 service 或route 上。
Kong 的插件列表

# 为 hello 服务添加 50/s 的限流,作用在 service 上
curl -X POST http://localhost:8001/services/hello/plugins \
--data "name=rate-limiting" \
--data "config.second=50"
# 为某个 routeId 添加 50/s 的限流,作用在 routes 上
curl -X POST http://localhost:8001/routes/{routeId}/plugins \
--data "name=rate-limiting" \
--data "config.second=50"

九、Kong 网关插件

  1. 身份认证插件:Kong提供了 Basic Authentication、Key authentication、OAuth2.0 Authentication、HMAC authentication、JWT、LDAP authentication 认证实现。
  2. 安全控制插件:ACL(访问控制)、CORS(跨域资源共享)、动态 SSL、IP限制、爬虫检测实现。
  3. 流量控制插件:请求限流(基于请求计数限流)、上游响应限流(根据 upstream 响应计数限流)、请求大小限制。限流支持本地、Redis 和集群限流模式。
  4. 分析监控插件:Galileo(记录请求和响应数据,实现 API 分析)、Datadog(记录 API Metric 如请求次数、请求大小、响应状态和延迟,可视化 API Metric)、Runscope(记录请求和响应数据,实现 API 性能测试和监控)。
  5. 协议转换插件:请求转换(在转发到 upstream 之前修改请求)、响应转换(在 upstream 响应返回给客户端之前修改响应)。
  6. 日志应用插件:TCP、UDP、HTTP、File、Syslog、StatsD、Loggly 等。

十、使用konga

10.1、实现一个负载均衡器

输入IP和端口号即可进入konga。比如:192.168.0.106:1337

(1)第一次进入需要注册一个用户。

(2)创建完用户后需要登录。

(2)创建connections。


(3)创建完成后激活。

(4)先使用openresty创建三个后台服务器:创建两个文件夹conf和logs,在conf文件夹下创建nginx.conf文件并输入以下内容:

worker_processes 2;
events {worker_connections 10240;
}http {server {listen 7001;location / {content_by_lua_block {ngx.say(7001,"\t",ngx.var.remote_addr)}}}server {listen 7002;location / {content_by_lua_block {ngx.say(7002,"\t",ngx.var.remote_addr)}}}server {listen 7003;location / {content_by_lua_block {ngx.say(7003,"\t",ngx.var.remote_addr)}}}}

(5)启动后台服务器。

openresty -p . -c conf/nginx.conf

查看:

ps aux | grep nginx

(6)konga中创建upstream。

然后直接点击提交。
(7)创建tagets。


(8)创建service。

然后点击提交。
(9)创建route。


然后点击提交。
(10)现在配置完成了7001,可以测试一下访问了。网页输入IP和端口。

此时会发现,网页返回的IP地址是docker容器的IP地址,客户端的IP地址丢失了。其实kong已经把IP地址传过去了,只是我们还没有使用而已。它在头信息里面,需要自己提取出来。

可以把nginx.conf修改一下:

worker_processes 2;
events {worker_connections 10240;
}http {server {listen 7001;location / {content_by_lua_block {local header = ngx.req.get_headers()local cjson = require "cjson"ngx.say(7001,"\t",ngx.var.remote_addr)ngx.say(cjson.encode(header))}}}server {listen 7002;location / {content_by_lua_block {ngx.say(7002,"\t",ngx.var.remote_addr)}}}server {listen 7003;location / {content_by_lua_block {ngx.say(7003,"\t",ngx.var.remote_addr)}}}}

然后重写加载一下:

openresty -p . -s reload

重新访问一下就可以看到真正的客户端IP:

(11)上面已经添加了一个taget,为了演示负载均衡,继续添加创建两个tagets:7002和7003。

(12)然后在网址输入IP和端口,每次访问的返回信息就有改变了。至此实现一个负载均衡器。

10.2、实现黑白名单

有了前面的基础,我们可以在service上加上黑白名单的插件。插件是 ip restriction。


加完之后,再次访问就会出现如下信息:

要移出黑名单直接叉掉就可以。

10.3、实现限流

限流可以是限制次数和限制大小。限流使用的插件是rate limiting。


限流效果:

10.4、实现鉴权验证

(1)先创建consumer。

(2)然后创建用户和密码:

(3)添加验证插件,basic auth。


(4)浏览器访问时就会弹出登录验证。

总结

  1. kong是openresty的一个应用,开箱即用,可以不开发只使用。kong的功能基本涵盖不部分问题。

  2. kong重要的特性:抽象对象,不需要写nginx配置;插件机制,使用一个功能,直接用插件应用在对象上(service、route、consume)就行。

  3. openresty如何解决问题:在nginx的关键阶段嵌入lua;openresty实现了cosocket,通过协程黏合异步事件回调,可以写同步的代码。

  4. kong可以是我们不需要写复杂的nginx配置文件,它抽象了四个对象,这几个对象的关系需要清楚;而且kong提供了丰富的插件。

Kong动态负载均衡与服务发现相关推荐

  1. 网络动态负载均衡算法分析

    转自CSDN博客:http://blog.csdn.net/wallacexiang/archive/2009/07/24/4376147.aspx 随着Internet的日益普及,无论在企业网.园区 ...

  2. Nginx动态负载均衡与配置管理

    背景 在Nginx集群有一定的规模时,比较让人头疼的问题有2个,一是如何在不reload nginx的情况下,动态更新后端rs,减少nginx reload的性能损耗,也能更好的对接到内部的部署平台: ...

  3. 客户端负载均衡与服务端负载均衡

    原文:https://segmentfault.com/a/1190000011081111 通过Nginx负载均衡服务器发送到不同的上游服务器去处理,这种负载均衡就是一种典型的服务端负载均衡,那么客 ...

  4. 负载均衡和动态负载均衡

    Nginx一般作为反向代理服务器来实现反向代理来转发处理请求,同时也可以作为静态资源服务器来加快静态资源的获取和处理. 1.正向代理与反向代理 正向代理: 正向代理 是一个位于客户端和原始服务器之间的 ...

  5. 如何让 Nginx 动态负载均衡

    一.什么是动态负载均衡 传统的 Nginx 负载均衡,是在 Nginx config 配置文件中,对 upstream 进行修改(扩展新服务器)进行,进行负载均衡,此时就需要让 Nginx 重启加载 ...

  6. openresty lua-resty-balancer动态负载均衡

    openresty lua-resty-balancer动态负载均衡 lua-resty-balancer:https://github.com/openresty/lua-resty-balance ...

  7. mqtt服务器性能分析,MQTT服务器动态负载均衡的研究与应用

    1. 引言 随着越来越多的工业设备接入物联网,因处理器能力.网络带宽等具有局限性,所以对其通信技术提出了更高的要求 [1].作为网页标准的HTTP,已不能满足机器之间的大规模沟通,其请求/回答模式不再 ...

  8. 客户端负载均衡与服务端负载均衡对比

    客户端 服务端 开发团队灵活修改 运维人员把控修改 运维成本低,开发人员直接可以修改 运维成本高 强依赖注册中心 不依赖注册中心 微服务框架 tomcat等传统应用 服务端负载均衡 负载均衡是我们处理 ...

  9. 来自东软的 OpenStack 负载均衡即服务开源项目

    东软ADSG(应用交付安全网关,Application Delivery Security Gateway) LBaaS Driver 当前实现了对 OpenStack(Havana 版本或更高)负载 ...

最新文章

  1. MySQL 系列(一) 生产标准线上环境安装配置案例及棘手问题解决
  2. iptables小案例,nat表应用
  3. php service原理,轻松搞懂WebService工作原理
  4. zigbee定位_基于RFID室内定位技术的解决方案,能满足高精度室内定位吗?
  5. Struts2整合SiteMesh
  6. php异步查询数据库,php中mysql数据库异步查询实现
  7. java GZIP压缩和解压
  8. WEB安全基础-XSS基础
  9. Linux的shell编程(三)
  10. 数据库测试JBDCTest
  11. 0 公式 0 基础学习电磁兼容 — 2.IEC及其EMC标准体系简介
  12. AI应用启示录:自动驾驶与“狼来了”的故事
  13. 淘宝京东拼多多自动查券找券返利机器人实现方法分享
  14. Macbook实用技巧——小白入门必须会的
  15. 使用vue做图片的闪光效果
  16. 2017cad光标大小怎么调_怎么设置CAD中十字光标的长度
  17. 温商机器人企业_4家温商企业跻身2018年中国500强
  18. 国货崛起,科技潮流——雷神星驰轮胎
  19. ubuntu-16.04.6安装教程
  20. 2019年十大网络流行语,你了解几个?

热门文章

  1. deepstream检测帧率很高,但是视频有延迟和拖延情况(问题解决)
  2. 十问 Linux 虚拟内存管理 (glibc)
  3. 【Lua】哈夫曼树构造算法的分析与实现
  4. 1103: 平均学分绩点(函数专题)C语言
  5. Gradle 通用配置项
  6. proxmox ve win7/windows7安装过程分享
  7. mysql数据库入门(没学会,算我输)-姥姥家的程序员
  8. eclipse代码和背景颜色设置、个性化设置、主题设置
  9. 【pytest】概述pytest——setup、teardown方法和conftest中的fixture用法,来执行测试用例的前置/后置条件语句操作
  10. python 桌面应用 h5_python前端之h5和css3