您现在的位置是:首页 >技术交流 >【云原生网关】Kong 使用详解网站首页技术交流
【云原生网关】Kong 使用详解
目录
3.1.2 Apache Cassandra/PostgreSQL
一、前言
在上一篇,详细介绍了云原生网关apisix的使用,与apisix相似的另一款高性能的云原生网关kong,也是近些年备受关注并且有过不少生产实践成功案例的面向云原生的api网关,接下来将详细介绍下kong的使用。
二、Kong介绍
Kong是一款基于OpenResty(Nginx + Lua模块)编写的高可用、易扩展、由Mashape公司开源的API Gateway项目。
Kong是基于NGINX和Apache Cassandra或PostgreSQL构建的,能提供易于使用的restful API来操作和配置API管理系统。它可以水平扩展为多个Kong服务器,通过前置的负载均衡配置把请求均匀地分发到各个Server,来应对大批量的网络请求。 官网: 地址
三、Kong核心组件
Kong主要有三个核心组件,以下分别做具体介绍
3.1 kong组件介绍
3.1.1 Kong Server
基于nginx的服务器,用于接收API请求
3.1.2 Apache Cassandra/PostgreSQL
用来存储操作数据,比如客户端调用kong的api操作产生的数据
3.1.3 Kong dashboard
官方推荐UI管理工具,当然,也可以使用 restfull 方式 管理admin api。
Kong采用插件机制来进行功能定制。插件集(可以是0或N个)在API请求响应循环的生命周期中被执行。插件使用Lua编写,目前已有几个基础功能:HTTP基本认证、密钥认证、CORS(Cross-Origin Resource Sharing,跨域资源共享)、TCP、UDP、文件日志、API请求限流、请求转发以及Nginx监控。
3.2 传统网关与Kong工作模式对比
通过下图不难看出,相比传统网关,kong在设计上具有更好的扩展性,尤其是自身强大的插件机制,能够满足生产中更加丰富的使用场景。
四、Kong网关特征与架构
4.1 kong网关特征
4.1.1 可扩展性
通过简单地添加更多的服务器,可以轻松地进行横向扩展,这意味着您的平台可以在一个较低负载的情况下处理任何请求;
4.1.2 模块化
可以通过添加新的插件进行扩展,这些插件可以通过RESTful Admin API轻松配置;
4.1.3 在任何基础架构上运行
Kong网关可以在任何地方都能运行。您可以在云或内部网络环境中部署Kong,包括单个或多个数据中心设置,以及public,private 或invite-only APIs。
4.2 kong网关架构
关于kong架构图中的核心组件做如下的补充说明:
- Kong核心基于OpenResty构建,实现了请求/响应的Lua处理化;
- Kong插件拦截请求/响应;
- Kong Restful 管理API提供了API/API消费者/插件的管理;
- 数据中心用于存储Kong集群节点信息、API、消费者、插件等信息,目前提供了PostgreSQL和Cassandra支持,如果需要高可用建议使用Cassandra;
- Kong集群中的节点通过gossip协议自动发现其他节点,当通过一个Kong节点的管理API进行一些变更时也会通知其他节点。每个Kong节点的配置信息是会缓存的,如插件,那么当在某一个Kong节点修改了插件配置时,需要通知其他节点配置的变更;
五、Kong环境搭建
对kong 的理论有一定了解之后,接下来将kong的环境快速部署起来,kong安装文档参考,kong支持裸机安装,容器安装,以及在k8s中部署,为了演示方便,下文将基于docker部署kong的使用环境。
注意:提前准备好docker环境;
5.1 搭建pg环境
kong的运行和操作需要依赖postgresql数据库,因此在安装kong之前,需要提前安装pg数据库,请参考如下步骤。
5.1.1 构建 Kong 的容器网络
首先我们创建一个 Docker 自定义网络,以允许容器相互发现和通信。在下面的创建命令中 kong-net 是我们创建的 Docker 网络名称。
docker network create kong-net
5.1.2 安装pg数据库
Kong 目前使用Cassandra(Facebook开源的分布式的NoSQL数据库) 或者PostgreSql,你可以执行以下命令中的一个来选择你的Database。
请注意使用上面那个自定义的网络: --network=kong-net
这里有个小问题。如果你使用的是PostgreSQL,想挂载卷持久化数据到宿主机。通过 -v 命令是不好用 的。这里推荐你使用 docker volume create 命令来创建一个挂载。
docker volume create kong-volume
所以完整的操作命令
docker pull postgres:9.6
docker run -d --name kong-database
--network=kong-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
关于这段命令做如下的补充说明:
- pg数据库的版本为9.6;
- 对外暴露的端口号为5432;
- 创建完pg的容器后,同时创建一个名为kong的数据库;
- 创建完kong的数据库,同时创建一个kong的用户,并拥有对kong库的访问权限;
5.1.3 初始化或者迁移数据库
我们使用 docker run --rm 来初始化数据库,该命令执行后会退出容器而保留内部的数据卷(volume)。这个命令我们还是要注意的,一定要跟你声明的网络,数据库类型、host 名称一致。同时注意 Kong 的版本号(注:当前 Kong 最新版本为 2.x,不过目前的 kong-dashboard (Kong Admin UI) 尚未支持 2.x 版的 Kong,为了方便后面的演示,这里以最新的 1.x 版的 Kong 作为演示)
执行下面的命令
docker run --rm
--network=kong-net
-e "KONG_DATABASE=postgres"
-e "KONG_PG_HOST=kong-database"
-e "KONG_PG_PASSWORD=kong"
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database"
kong:latest kong migrations bootstrap
完成后,就可以连接一下PG的数据库,看到如下的初始化表的数据信息,说明kong需要的数据库环境已经准备完成
5.2 启动kong容器
使用下面的命令启动kong的运行容器
docker run -d --name kong
--network=kong-net
-e "KONG_DATABASE=postgres"
-e "KONG_PG_HOST=kong-database"
-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
注意kong的版本,与上面的版本保持一致,关于这段启动命令做如下的补充说明,
- Kong 默认绑定 4 个端口;
- 8000:用来接收客户端的 HTTP 请求,并转发到 upstream;
- 8443:用来接收客户端的 HTTPS 请求,并转发到 upstream;
- 8001:HTTP 监听的 API 管理接口;
- 8444:HTTPS 监听的 API 管理接口;
- KONG_DATABASE=postgres,指定kong运行时数据库类型;
- KONG_PG_HOST=kong-database,指定pg;
- KONG_PG_PASSWORD=kong,指定运行时pg数据库名称;
到这里为止,Kong已经安装完毕,通过docker ps 命令,可以查看当前正在运行的容器,正常情况下可看到 Kong 和 PostgreSQL 的两个容器;
可通过 curl -i http://IP:8001/ 或者浏览器调用 http://IP:8001/ 来验证Kong Admin 是否联通 ;
六、安装Kong管理UI
Kong 企业版提供了管理 UI,开源版是没有的。但是有很多的开源的管理 UI ,其中比较 Fashion 的有Kong Dashboard 和 Konga。Kong Dashboard 当前最新版本(3.6.x)并不支持最新版本的 Kong,最后一次更新也要追溯到 1 年多以前了,选择 Konga 会更好一点。下面介绍下konga的安装。
6.1 konga介绍
Konga (官网地址:pantsel.github.io/konga/ ,Github 地址:github.com/pantsel/kon… )可以很好地通过 UI 观察到现在 Kong 的所有的配置,并且可以对于管理 Kong 节点情况进行查看、监控和预警。Konga 主要是用 AngularJS 写的,运行于 nodejs 服务端。具有以下特性:
- 管理所有 Kong Admin API 对象;
- 支持从远程源(数据库,文件,API等)导入使用者;
- 管理多个 Kong 节点。使用快照备份,还原和迁移 Kong 节点;
- 使用运行状况检查监视节点和 API 状态;
- 支持电子邮件和闲置通知;
- 支持多用户;
- 易于数据库集成(MySQL,PostgresSQL,MongoDB,SQL Server);
6.2 konga安装流程
6.2.1 定义挂载卷
docker volume create konga-postgresql
6.2.2 进行数据库挂载
docker run -d --name konga-database
--network=kong-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
6.2.3 初始化 PostgreSQL 数据库
docker run --rm --network=kong-net pantsel/konga:latest -c prepare -a postgres -u postgres://konga:konga@konga-database:5432/konga
到此Konga的数据库环境就搞定了,通过Navicat可以查看到konga数据库及其数据表
6.2.4 启动konga容器
docker run -d -p 1337:1337
--network kong-net
-e "DB_ADAPTER=postgres"
-e "DB_URI=postgres://konga:konga@konga-database:5432/konga"
-e "NODE_ENV=production"
-e "DB_PASSWORD=konga"
--name konga
pantsel/konga
如果启动成功,可以在浏览器中输入 http://IP:1337/ 来访问管理界面
通过注册后进入,然后在dashboard面板里面添加Kong的管理Api路径 http://ip:8001
配置完成后,就可以看到konga的完整功能菜单了;
七、Kong Admin Api基本使用
kong提供了丰富的admin api以满足开发运维人员日常对于各种需要配置网关场景的使用,比如基本的服务路由,反向代理,负载均衡,ACL等,接下来详细介绍下admin api的使用。
7.1 前置准备
为了接下来做测试,提前创建两个springboot的服务,端口分别为80883,8085,并提供一个接口,启动服务之后,可以通过浏览器访问接口,如下效果
7.2 kong admin api 核心配置模块
而在kong中,可以使用其提供的amin api 来完成,官方配置手册:配置文档,其中涉及到的几个核心组件如下,简单来说,这些组件的共同配合可以完成上面类似于nginx的一个负载均衡的配置效果;
7.3 kong admin api 配置服务代理
使用kong进行服务代理,模拟nginx中的路由转发,即通过kong提供的admin api的配置实现如下效果;
server {
listen 8000;
location /product {
proxy_pass http://外网IP:8083/product;
}
}
7.3.1 创建service
使用下面的命令创建一个service
curl -i -X POST http://公网IP:8001/services --data name=product-service --data url='http://公网IP:8083/product'
创建完成后,可以通下面的过命令查看service的创建信息;
curl http://公网IP:8001/services/product-service
也可以在控制台界面看到当前这个service的名v
7.3.2 创建route
执行下面的命令,创建一个route
curl -i -X POST --url http://公网IP:8001/services/product-service/routes --data 'paths[]=/product' --data name=product-route
执行成功后,可以通过界面看到这个route信息
7.3.3 测试验证
通过上面的两步,就完成了一个模拟nginx服务路由代理的配置,通过浏览器访问一下即可看到效果
7.4 kong admin api 配置负载均衡
在nginx的使用中,经常涉及到负载均衡的配置,接下来模拟下如何使用kong配置一个类似nginx负载均衡的效果;
7.4.1 创建upstream
curl -i -X POST http://公网IP:8001/upstreams --data name=product-upstream
7.4.2 创建target
使用下面的命令创建一个target,绑定上面的upstream
curl -i -X POST http://公网IP:8001/upstreams/product-upstream/targets --data target="公网IP:8003"
7.4.3 修改service
使用下面的命令建立service与upstream的绑定关系;
curl -i -X PATCH http://公网IP:8001/services/product-service --data url='http://product-upstream/product'
7.4.4 测试验证
上面的配置就等同于 Nginx 中的nginx.conf配置 :
upstream product-upstream{
server 10.95.35.92:8001;
}
server {
listen 8000;
location /product {
proxy_pass http://product-upstream/product;
}
}
然后在浏览器中输入下面的地址进行测试验证,看到下面的效果后,说明配置生效了;
从上面的两个简单的操作配置演示不难发现,不管是配置路由代理,还是负载均衡,均无需重启kong的服务,即配置操作到生效都是动态的。
八、Kong 插件使用
Kong通过插件Plugins实现日志记录、安全检测、性能监控和负载均衡等功能。通过插件机制,可以大大提升kong应对个性化、定制化类的业务场景。
8.1 kong插件总结
Kong 网关常用的插件概括为如下:
8.1.1 身份认证插件
Kong 提供了 Basic Authentication、Key authentication、OAuth2.0 authentication、HMAC authentication、JWT、LDAP authentication 认证实现。
8.1.2 安全控制插件
ACL(访问控制)、CORS(跨域资源共享)、动态 SSL、IP 限制、爬虫检测实现。
8.1.3 流量控制插件
请求限流(基于请求计数限流)、上游响应限流(根据 upstream 响应计数限流)、请求大小限制。限流支持本地、Redis 和集群限流模式。
8.1.4 分析监控插件
Galileo(记录请求和响应数据,实现 API 分析)、Datadog(记录 API Metric 如请求次数、请求大小、响应状态和延迟,可视化 API Metric)、Runscope(记录请求和响应数据,实现 API 性能测试和监控)。
8.1.5 协议转换插件
请求转换(在转发到 upstream 之前修改请求)、响应转换(在 upstream 响应返回给客户端之前修改响应)。
8.1.6 日志应用插件
TCP、UDP、HTTP、File、Syslog、StatsD、Loggly 等。
8.2 配置 key-auth 插件
下面将演示一个例子,通过启动 apikey 实现简单网关安全检验。
8.2.1 添加路由插件
使用下面的命令为上面的:product-route这个路由配置一个插件,即这个路由访问时需要校验
curl -i -X POST http://公网IP:8001/routes/product-route/plugins --data name=key-auth
这个插件接收 config.key_names 定义参数,默认参数名称 ['apikey']。在 HTTP 请求中 header 和 params 参数中包含 apikey 参数,参数值必须 apikey 密钥,Kong 网关将坚持密钥,验证通过才可以访问后续服务。
此时我们使用 curl -i http://IP:8000/product/
来验证一下是否生效,如果如下所示,访问失败(HTTP/1.1 401 Unauthorized,"No API key found in request" ),说明 Kong 安全机制生效了。
8.2.2 为访问者配置apikey
定义消费者访问 API Key, 让他拥有访问 hello-service 的权限。
创建消费者 Hidden:
curl -i -X POST http://公网IP:8001/consumers/ --data username=Hidden
之后为消费者 Hidden 创建一个 api key
curl -i -X POST http://公网IP:8001/consumers/Hidden/key-auth/ --data key=123456
效果验证,再使用下面的命令进行访问时就可以正常看到结果了;
curl -i http://公网IP:8000/product/1 --header "apikey:123456"
九、Kong限流使用
9.1 kong限流简介
Kong 提供了 Rate Limiting 插件,实现对请求的限流功能,避免过大的请求量过大,将后端服务打挂。Rate Limiting 支持秒/分/小时/日/月/年多种时间维度的限流,并且可以组合使用。例如说:限制每秒最多 100 次请求,并且每分钟最多 1000 次请求。
Rate Limiting 支持 consumer 、 credential 、 ip 三种基础维度的限流,默认为 consumer 。例如
说:设置每个 IP 允许每秒请求的次数。计数的存储,支持使用 local 、 cluster 、 redis 三种方式进行存储,默认为 cluster :
- local :存储在 Nginx 本地,实现单实例限流;
- cluster :存储在 Cassandra 或 PostgreSQL 数据库,实现集群限流;
- redis :存储在 Redis 数据库,实现集群限流;
Rate Limiting 采用的限流算法是计数器方式,所以无法提供类似令牌桶算法的平滑限流能力
9.2 配置 Rate Limiting 插件
调用 Kong Admin API services/${service}/plugins ,创建 Rate Limiting 插件的配置:
9.2.1 服务(service)级别启用限流插件
curl -X POST http://公网IP:8001/services/product-service/plugins --data "name=rate-limiting" --data "config.second=1" --data "config.limit_by=ip"
执行成功后,可以通过模拟调用,当每秒请求次数超过1的时候,可以看到下面的信息,说明被限流了
9.2.2 路由(route)级限流配置
curl -X POST http://127.0.0.1:8001/routes/{route_id}/plugins --data "name=rate-limiting" --data "config.second=5" --data "config.hour=10000"
9.2.3 consumer上启用插件
curl -X POST http://127.0.0.1:8001/plugins
--data "name=rate-limiting"
--data "consumer_id={consumer_id}"
--data "config.second=5"
--data "config.hour=10000"
关于以上配置中的参数,做如下补充说明:
- name 参数,设置为 rate-limiting 表示使用 Rate Limiting 插件;
- config.second 参数,设置为 1 表示每秒允许 1 次请求;
- config.limit_by 参数,设置为 ip 表示使用 IP 基础维度的限流;
- 也可以通过konga UI操作添加rate-limiting插件;
注意:以上的限流配置,除了admin的api,均可以通过konga界面进行设置,效果是一样;
十、Kong黑白名单使用
黑白名单对于网关来说也是一种比较常用的场景,在kong中,也可以通过插件进行黑白名单的配置,具体来说,黑白名单配置的生效,可以是service级别,也可以是路由级别;
10.1 service配置白名单
在服务上启用插件,执行下面的命令
curl -X POST http://公网IP:8001/services/{service}/plugins --data "name=ip-restriction" --data "config.whitelist=192.168.3.18"
其中:
- {service}是具体的服务名称;
-
config.whitelist :白名单,逗号分隔的 IPs 或 CIDR 范围;
-
config.blacklist :白名单,逗号分隔的 IPs 或 CIDR 范围;
10.2 route配置白名单
也可以基于某个具体的route进行配置,可以通过:http://公网IP:8001/routes 拿到你的route-id,然后填写进去即可
curl -X POST http://公网IP:8001/routes/{route-id}/plugins --data "name=ip-restriction" --data "config.whitelist=192.168.3.18"
执行上面的命令,然后就可以在界面上看到配置的这个IP白名单的插件了;
十一、写在文末
随着云原生应用越来越广泛,以k8s为代表的统一的云原生解决方案已经逐步开始在各类互联网公司使用,作为产品的流量门户,网关可以说承载着及其重要的角色,相信在不久的将来,云原生网关将会成为微服务治理架构下不可或缺的一个组件走向人们的视野,所以有必要对云原生网关进行深入的学习和探究。