title: API网关之Kong #标题tags: #标签
date: 2021-12-12 22:13:00
categories: API网关 # 分类
kong介绍
kong是一款基于OpenResty(Niginx+Lua模块)编写的高可用、易扩展的,由Mashape公司开源的API Gateway项目,kong是基于Nginx和Apache Cassandra或PostgreSQL构建的,能提供易于使用的RESTful API来操作和配置API管理系统,所以它可以水平扩展多个kong服务器,通过前置的负载均衡配置把请求均匀的分发到各个Server,以此来应对大批量的网络请求。
参考资料:
kong的工作架构如下:
kong主要有三个组件:
- Kong server:基于nginx的服务器,用来接收API请求;
- Apache Cassandra/PostgreSQL:用来存储操作数据;
- Kong dashboard:官方推荐UI管理工具,当然,也可以用restfull方式管理admin api,或者konga。
kong采用插件机制进行功能定制,插件集(可以是0或N个)在API请求响应循环的生命周期中被执行。插件使用Lua编写,目前已有几个基础功能:HTTP基本认证、秘钥认证、CORS(Cross-Origin Resource Sharing,跨域资源共享)、TCP、UDP、文件日志、API请求限流、请求转发以及nginx监控。
kong网关架构
1、kong核心基于OpenResty构建,实现了请求/响应的Lua处理化;
2、kong插件拦截请求/响应;
3、kong restful管理API提供了API/API消费者/插件的管理;
4、数据中心用于存储kong集群节点、API、消费者、插件等信息,目前提供了PostgreSQL和Cassandra支持;
5、kong集群中的节点通过gossip协议自动发现其他节点,当通过一个kong节点的管理API进行一些变更时也会通知其他节点。每个kong节点的配置信息是会缓存的,如插件,那么当在某一个Kong节点修改了插件配置时,需要通知其他节点配置的变更。
CentOS 7 安装kong网关
安装postgresql
请参考博文部署postgresql 12.3进行部署,直至可以访问到数据库:
当部署完成后,还需要做一些修改。
修改postgresql的访问权限
$ vim /apps/usr/postgres/data/pg_hba.conf # 将下面改为你环境中的网段,以便可以远程登录到postgresql
host all all 192.168.20.0/24 md5
# 切换至postgresql的启动用户,以便重启数据库生效
$ su - postgres
$ pg_ctl restart # 重启数据库
创建kong用户及库
# 创建kong系统用户,不允许登录到系统
$ useradd -s /sbin/nologin kong
# 创建用户及数据库并授权
$ psql -U postgres # 登录到数据库中
$ create user kong with password '123.com';
$ create database kong owner kong;
$ grant all privileges on database kong to kong;
$ \q # 退出数据库
安装kong
$ curl -Lo kong-2.6.0.rpm $(rpm --eval "https://download.konghq.com/gateway-2.x-centos-7/Packages/k/kong-2.6.0.el7.amd64.rpm")
$ yum -y install kong-2.6.0.rpm
$ cd /etc/kong
mv kong.conf.default kong.conf
vim /etc/kong/kong.conf # 定义连接数据库的基本参数,如IP、端口、用户名、密码、库
pg_host = 192.168.20.10
pg_port = 5432
pg_timeout = 5000
pg_user = kong
pg_password = 123.com
pg_database = kong
# 同步数据库
$ kong migrations bootstrap -c /etc/kong/kong.conf
同步数据库成功后,输出如下:
通过Navicat登录到数据库,可以看到下面这些表:
启动kong
$ kong start -c /etc/kong/kong.conf # 启动kong
$ kong stop # 停止命令
$ kong reload # 重新加载kong
$ curl http://127.0.0.1:8000 # 访问kong
{"message":"no Route matched with those values"}
# 输出上面的信息,是因为我们现在还没有注册服务
# 请求 Admin 端口
# 注意,考虑到安全性,Admin 端口默认只允许本机访问。
$ curl http://127.0.0.1:8001
{"plugins":{"enabled_in_cluster":[],"available_on_server":{... // 省略
kong端口作用
service | port | 作用 |
---|---|---|
Proxy | 8000 | 接收客户端的 HTTP 请求,并转发到后端的 Upstream |
Proxy | 8443 | 接收客户端的 HTTPS 请求,并转发到后端的 Upstream |
Admin | 8001 | 接收管理员的 HTTP 请求,进行 Kong 的管理 |
Admin | 8444 | 接收管理员的 HTTPS 请求,进行 Kong 的管理 |
docker安装kong
安装docker
# 设置 yum repository
$ yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装 docker
$ yum install -y docker-ce-19.03.8 docker-ce-cli-19.03.8 containerd.io
# 修改 docker 镜像下载源
$ [ -d /etc/docker ] || mkdir /etc/docker
echo "{\"registry-mirrors\": [\"https://registry.cn-hangzhou.aliyuncs.com\",\"https://4grd6p3s.mirror.aliyuncs.com\"]}" >> /etc/docker/daemon.json
# 修改docker的根目录(默认根目录为:/var/lib/docker),根据需要来确定是否要修改
# 修改根目录,只是在启动命令后增加“--graph=/data/lib/docker”
$ vim /usr/lib/systemd/system/docker.service # 跳转到14行,修改如下
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --graph=/data/lib/docker
# 启动docker
$ systemctl enable docker && systemctl start docker
# 确认 docker 版本
$ docker version
如果嫌弃默认的源比较慢,请自行修改docker镜像源。
创建docker网络
$ docker network create kong-net
搭建数据库环境
Kong 目前使用Cassandra(Facebook开源的分布式的NoSQL数据库) 或者PostgreSql,你可以执行以下命令中的一个来选择你的Database。请注意定义网络--network=kong-net
。
下面两款数据库,二选一即可。
1、Cassandra容器:
docker run -d --name kong-database \
--network=kong-net \
-p 9042:9042 \
--restart always \
cassandra:3
2、PostgreSQL容器:
# 先别执行哦,看下去再说
docker run -d --name kong-databasev \
--network=kong-net \
-p 5432:5432 \
-e "POSTGRES_USER=kong" \
-e "POSTGRES_DB=kong" \
postgres:9.6 \
这里有个小问题。如果你使用的是PostgreSQL,想挂载卷持久化数据到宿主机。通过 -v 命令是不好用的。这里推荐你使用 docker volume create
命令来创建一个挂载。
$ docker volume create kong-volume
然后上面的PostgreSQL就可以通过-v kong-volume:/var/lib/postgresql/data
进行挂载了。
$ 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" \
--restart always \
postgres:9.6
初始化数据库
我们使用 docker run --rm
来初始化数据库,该命令执行后会退出容器而保留内部的数据卷(volume)。
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" \
--restart always \
kong:latest kong migrations bootstrap
navicat登录到数据库中可以看到如下表信息:
启动Kong容器
完成初始化或者迁移数据库后,我们就可以启动一个连接到数据库容器的Kong容器,请务必保证你的数据库容器启动状态,同时检查所有的环境参数 -e 是否是你定义的环境。
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 \
--restart always \
kong:latest
验证
可通过 curl -i http://127.0.0.1:8001/
或者浏览器调用 http://192.168.20.10:8001/
来验证Kong Admin 是否联通 。
安装konga
由于konga现在已经不更新了,可能有些地方不兼容2.x的kong,不管了,感兴趣的可以装上看看,另外,由于konga的安装需要依赖其他东西,国内不容易下载,所以建议konga使用docker来运行。
Konga 主要是用 AngularJS 写的,运行于nodejs服务端。具有以下特性:
- 管理所有Kong Admin API对象。
- 支持从远程源(数据库,文件,API等)导入使用者。
- 管理多个Kong节点。使用快照备份,还原和迁移Kong节点。
- 使用运行状况检查监视节点和API状态。
- 支持电子邮件和闲置通知。
- 支持多用户。
- 易于数据库集成(MySQL,postgresSQL,MongoDB,SQL Server)。
启动Konga数据库容器
如果机器没有安装docker,请按照上面的docker安装kong中,去安装docker环境。
# 创建kong-net网络
$ docker network create kong-net
# 创建持久化卷
$ docker volume create konga-postgresql
# 运行konga所用的postgresql数据库
$ 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" \
--restart always \
postgres:9.6
初始化Postgresql数据库
$ docker run --rm --network=kong-net \
pantsel/konga:latest \
-c prepare -a postgres \
-u postgres://konga:konga@konga-database:5432/konga
-c: 执行的命令,这里我们执行的是prepare;
-a: adapter 简写 ,值可以是postgres 或者mysql;
-u: db url 数据库连接全称
看到如下输出,则表明初始化数据库成功:
Konga 还有一些可配置的环境参数:
变量 | 描述 | 值 | 默认值 |
---|---|---|---|
HOST | 将被Konga的服务器绑定的IP地址 | - | ‘0.0.0.0’ |
PORT | 将被Konga的服务器使用的端口 | - | 1337 |
NODE_ENV | 环境 | production ,development |
development |
SSL_KEY_PATH | 如果您想使用SSL,这将是.key文件的绝对路径。 必须同时设置SSL_KEY_PATH 和SSL_CRT_PATH 。 |
- | null |
SSL_CRT_PATH | 如果您想使用SSL,这将是.crt文件的绝对路径。 必须同时设置SSL_KEY_PATH 和SSL_CRT_PATH 。 |
- | null |
KONGA_HOOK_TIMEOUT | 在指定时间(ms)中,Konga等待启动任务完成后才退出进程的时间。 | - | 60000 |
DB_ADAPTER | Konga将使用的数据库。 如果没有设置,将使用localDisk db。 | mongo ,mysql ,postgres |
- |
DB_URI | 完整的db连接字符串。 取决于“DB_ADAPTER”。 如果设置了该参数,则不需要其他DB相关的变量。 | - | - |
DB_HOST | 如果没有指定’ DB_URI ‘,这就是数据库主机。 取决于“DB_ADAPTER”。 | - | localhost |
DB_PORT | 如果没有指定’ DB_URI ‘,这是数据库端口。 取决于“DB_ADAPTER”。 | - | DB default. |
DB_USER | 如果没有指定’ DB_URI ‘,这就是数据库用户。 取决于“DB_ADAPTER”。 | - | - |
DB_PASSWORD | 如果没有指定’ DB_URI ‘,这是数据库用户的密码。 取决于“DB_ADAPTER”。 | - | - |
DB_DATABASE | 如果没有指定’ DB_URI ‘,这是Konga的db的名称。 取决于“DB_ADAPTER”。 | - | konga_database |
DB_PG_SCHEMA | 如果使用postgres作为数据库,这是将使用的模式。 | - | public |
KONGA_LOG_LEVEL | 日志级别 | silly ,debug ,info ,warn ,error |
debug on dev environment & warn on prod. |
TOKEN_SECRET | 将用于签署Konga发行的JWT代币的秘密 | - | - |
NO_AUTH | 运行Konga而不需要认证 | true/false | - |
BASE_URL | 定义加载Konga的基本URL或相对路径。 例:[www.example.com/konga] (http://www.example.com/konga) | - | |
KONGA_SEED_USER_DATA_SOURCE_FILE | 在第一次运行时的默认用户。 Docs. | - | |
KONGA_SEED_KONG_NODE_DATA_SOURCE_FILE | 在第一次运行时种子默认的Kong Admin API连接 Docs | - |
启动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 \
--restart always \
pantsel/konga
运行成功后,即可通过容器所在的宿主机的1337端口,登录到konga,如下:
首次登录需要注册一个管理员用户,如下:
登录后,需要先设置你的kong 管理接口的访问路径以及连接的名字,由于kong的管理接口默认只监听本机回环地址,所以需要先修改kong的管理端口监听地址,如下:
$ vim /etc/kong/kong.conf
admin_listen = 0.0.0.0:8001 reuseport backlog=16384, 0.0.0.0:8444 http2 ssl reuseport backlog=16384
# 重启kong,以便生效
$ kong stop && kong start -c /etc/kong/kong.conf
登录后,基本就是一些点点点的操作了,这里不做什么介绍。后续的操作,也是直接操作kong的API管理接口的。
kong快速开始
动态负载均衡实现
下面是一个简单的nginx负载均衡配置示例:
upstream product-upstream {
server 192.168.65.190:8866 weight=100;
server 192.168.65.190:8867 weight=100;
}
server {
listen 80;
location /pms/ {
proxy_pass http://product-upstream;
}
}
Kong 组件 | 说明 |
---|---|
route | route 对应路由,它负责匹配实际的请求,映射到 service 中 ,(对应nginx配置文件中的 location /pms/ ) |
service | service 对应服务,可以直接指向一个 API 服务节点( host 参数设置为 ip + port),也可以指定一个 upstream实现负载均衡。简单来说,服务用于映射被转发的后端API 的节点集合。(对应nginx配置文件中的 proxy_pass http://product-upstream; ) |
upstream | upstream 对应一组 API 节点,实现负载均衡(对应nginx配置文件中的 product-upstream { } ) |
target | target 对应一个 API 节点(对应nginx配置文件中的 server 192.168.65.190:8866 weight=100;) |
其工作流程图如下:
创建upstream
# 创建一个名为ljz-product-upstream的upstream
$ curl -X POST http://127.0.0.1:8001/upstreams --data "name=ljz-product-upstream"
创建targets
用 Kong Admin API /upstreams/{upstream}/targets ,创建 ljz-product-upstream 服务对应的 2 个 target。注意, {upstream} 路径参数为实际的 upstream 的名字。
两个target的接口自行配置,这里不展开配置。
# 192.168.20.6:80 对应的 target
$ curl -X POST http://127.0.0.1:8001/upstreams/ljz-product-upstream/targets --data "target=192.168.20.6:80" --data "weight=100"
# 192.168.20.7:80 对应的 target
$ curl -X POST http://127.0.0.1:8001/upstreams/ljz-product-upstream/targets --data "target=192.168.20.7:80" --data "weight=100"
创建service
curl -X POST http://127.0.0.1:8001/services --data "name=ljz-product" --data "host=ljz-product-upstream" --data "path=/"
创建route
curl -X POST http://127.0.0.1:8001/services/ljz-product/routes --data "name=ljz-product-route" --data "paths[]=/pms/"
访问测试
$ for i in {1..2};do curl http://192.168.20.10:8000/pms/;done
192.168.20.6
192.168.20.7
kong的插件
kong提供了很多免费插件供我们使用,比如:基于Basic Auth和JWT的身份认证、限流配置、黑白名单等等:
这里不一一介绍了,如果需要可以结合如下资料进行配置: