Kong 网关 快速入门
kong 网关 快速入门
1.网关的认识
1.1概念
网关是系统对外的唯一入口,在客户端和服务端之间,处理非业务功能。将1对N的问题转变为了1对N。
1.1为什么要使用网关
- 1.解耦
- 2.负载均衡 平衡多节点微服务的请求
- 3.安全:api网关和其他微服务可以在同一个受保护的网络中以专有通道进行通信,而其他微服务为私有ip,不对外开放
- 4.优化响应速度:区别于之前前端向多个微服务发送请求在前端处理数据,现在请求通过api处理,他们处在同一个网络中从而连接更好。
- 5.重试策略和断路器,限流,ip限制,日志,请求转换,鉴权等非业务功能。
产生的问题
- 可用性降低(增加了一个必须开发、部署、维护的高可用组件)
- 网关可能成为性能瓶颈
1.2.kong,gateway,zuul的区别
参考
kong
kong基于nginx(基于C)和lua开发,性能高,稳定。插件开箱即用。最高支持5w并发。
专注于全局的Api管理策略,比如全局流量监控,日志记录,全局限流,黑白名单空值,类似于防火墙属于流量网关。服务器级别.nginx的负载均衡属于服务器负载均衡,服务列表由nginx维护,请求到nginx,nginx进行策略转发。
问题:二次开发,自由拓展困难,需要会C和lua。
zuul
zuul 网飞开源,基于Java开发,servlet实现,易于二次开发;需要运行在web容器中,如Tomcat。
阻塞式的API,不支持长连接,只能同步,不支持异步。
问题:缺乏管控,无法动态配置;依赖组件多;处理请求依赖Web容器,性能不如nginx,tomcat 8.5最大10000并发。
gateway
SpringCloud提供的网关服务 。gateway基于netty,用java编写的,并发1w左右,性能比zuul强。
针对业务提供特定的流控策略,缓存策略,鉴权认证策略等,属于业务网关。项目级别。业务网关和流量网关之前没有严格的界线。响应式非阻塞式的Api,支持长连接。 支持异步。gateway和zuul的负载均衡属于本地(客户端)负载均衡,服务列表维护在eureka,通过ribbon和eureka。在发起请求前进行本地策略计算,然后进行转发。
本地负载均衡相比于服务端负载均衡,运维成本低,强依赖注册中心,微服务框架(服务器负载均衡适合Tomcat,JBoss部署传统应用)
2.Kong介绍
官方文档地址
Kong 网关是一个轻量级、快速、灵活的云原生 API 网关。API 网关是一个反向代理,可以管理、配置和路由 对 API 的请求。
Kong Gateway是一个运行在Nginx中的Lua应用程序。Kong Gateway 与OpenResty一起分发,OpenResty是扩展 lua-nginx-modules的一组模块。
OpenResty是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。可编辑的nginx。
Kong提供了许多插件提供在 网关部署。还可以自定义插件。
2.1 Nginx
模块化设计的反向代理软件,由C语言开发,是多进程(单线程) & 多路IO复用模型(高并发)。
Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器",在BSD-like协议下发行。其特点是占有内存少,并发能力强。
特点:
- 1.占用内存少不超过2M
- 2.并发能力强5万/秒 tomcat 150-220个/秒
- 3.开发语言C语言
核心功能:动态的生成nginx配置
2.2 重要属性
- upstream:虚拟主机名,通过多个目标ip进行负载均衡
- target:代表了一个物理服务,是ip+port的抽象 组名对应的后端,可以有多个
- service:上游服务的抽象,它可以直接映射到一个物理服务(host指向 ip + port),也可以指向一个upstream来做到负载均衡; 可以关联upstream的一个名字
- route:定义客户端请求规则,他负责将实际的request映射到service。 访问哪个域名的哪个url,然后把流量打到service
- consumer 服务的消费者/用户。消费者的核心原则是您可以将插件附加到他们,从而自定义请求行为。
消费者配合插件使用,通过认证识别消费者来使用插件。通过绑定插件定义消费请求行为。
配置插件加消费者id无效: 认证插件绑定消费者,插件作用在此消费者上,但是只有识别该消费者才能使用该插件,但又没有别的识别插件,所以无效。比如增加限流插件,但是却没有识别消费者的认证插件所以无法生效。
target无法配置域名的原因
配置host会慢慢偏离,因为dns刷新只有秒精度,并且只有在host真正被请求过才会更新,另外一些域名服务器不会返回。
Do not use hostnames in the balancer as the balancers might/will slowly diverge because the DNS ttl has only second precision and renewal is determined by when a name is actually requested. On top of this is the issue with some nameservers not returning all entries, which exacerbates this problem. So when using the hashing approach in a Kong cluster, add target entities only by their IP address, and never by name.
2.3 服务和路由
就是上文中的service和router。
Kong 网关管理员使用对象模型来定义其 所需的流量管理策略。该模型中的两个重要对象是服务和路由。服务和路由在 以协调的方式定义请求和响应将采用的路由路径 通过系统。
下面的高级概述显示了到达路由并转发到服务的请求, 响应采取相反的途径:
- 什么是服务
在 Kong Gateway 中,服务是现有上游应用程序的抽象。 服务可以存储插件配置和策略等对象的集合,它们可以与路由相关联。
定义服务时,管理员提供名称和上游应用程序连接 信息。连接详细信息可以在字段中作为单个字符串提供,也可以通过提供 协议、端口 、主机 和路径的单个值。
服务与上游应用程序具有一对多关系,这允许管理员创建复杂的流量管理行为。 - 什么是路由
路由是上游应用程序中资源的路径。将路由添加到服务来访问基础应用程序。在 Kong 网关中,路由通常映射到通过 Kong 网关应用程序公开的服务。路由还可以定义匹配请求的规则。因此,一个路由可以引用到多个服务。一个基本的路由应具有 名称、单个或者多个路径和一个指向服务的引用。 - 代理请求:Kong 是一个 API 网关,它基于当前配置接收来自客户端的请求并将其路由到相应的上游应用程序。
- 支持协议:http/https,tcp,tls,grpc/grpcs,ws/wss(企业版)
- 路由匹配规则:可选http方法,hosts,路径,请求头header,snis,IP sources,IP destinations等
- 请求转换插件:支持对请求和相应中的body,header,querystring的删除,替换,重命名,添加。
- 路由优先级:router的Regex priority属性。 当多个路由提供时使用正则表达式匹配时,用来选择用哪个路由来解析。当相同时,采用创建时间更长的。
- router中的可配置属性路径处理算法Path handling algorithms:
控制向上游发送请求时如何组合服务路径、路由路径和请求的路径。
v0:给定服务路径 /s、路由路径 /r 和请求路径 /re,串联路径将为 /s/re
v1:给定服务路径 /s、路由路径 /r 和请求路径 /re,串联路径将为 /sre
2.4 负载均衡
负载均衡是一种在多个上游服务之间分配 API 请求流量的方法。负载平衡提高了整体系统响应能力 并通过防止单个资源过载来减少故障。
上游是指位于 Kong 网关后面的服务应用程序, 将客户端请求转发到哪些客户端请求。在 Kong 网关中,上游代表一个虚拟主机名,可以是 用于跨多个目标后端服务对传入请求进行运行状况检查、断路和负载均衡。
kong提供基于dns的负载均衡和环形平衡器。
环形平衡器的可选算法:
- 加权轮训
- 一致性哈希
- 最小连接数
- 时延。
时延算法:基于峰值EWMA(指数加权移动平均),保证均衡器以最小时延来选择服务器。
一致性哈希算法:减少平衡器因目标变化发生的哈希损失。
2.5 健康检查
kong可以在upstream中配置健康检查
配置的间隔以秒为单位,配置为0则为禁用健康检查(默认禁用)
可以自定义健康和非健康的状态码
主动健康检查
定期请求特定http和https的endpoint,根据响应确定目标健康状态。
会产生流量,需要配置健康检查的路径,可以自定义健康和非健康的响应状态,在目标恢复健康状态后可以将目标标记健康
目前只适用于HTTP/HTTPS目标,不适用于分配给协议属性为tcp和tls的service的upstream
被动健康检查
断路器模式 kong通过分析代理流量,根据响应状态确定target的健康状况。
不会产生流量,不需要配置路径(根据目标响应状态判断),不能自定义状态,不能在目标健康后自动设置为健康,需要手动设置(执行命令为curl -i -X POST http://localhost:8001/upstreams/my_upstream/targets/10.1.2.3:1234/healthy
HTTP/1.1 204 No Content)(该命令会广播集群)
上述命令会在集群范围内广播该target的“健康”状态,同步到整个Kong集群。Kong节点会重置所有健康检查器的运行状况计数器,负载均衡可以再次将流量路由到该target。在无DB模式下不可用。
客户端请求量大的时候被动健康检查更快(被动没有时间间隔,只有阈值)
api
http://localhost:8001/upstreams/{name 或 id}/health/
无db模式下查询各节点的健康状态
upstream配置healthchecks.threshold = 健康target/总target 55为55%
upstream不健康后,Kong不再向upstream发送请求,直接返回错误
health字段
如果由于 DNS 问题无法在平衡器中激活目标,则其状态显示为DNS_ERROR。
当上游配置中未启用健康检查时,活动目标的健康状态显示为 HEALTHCHECKS_OFF。
当启用健康检查并且自动或手动确定 Target 健康时,其状态显示为HEALTHY。这意味着此 Target 当前包含在此 Upstream 的负载均衡器执行中。
当目标已被主动或被动健康检查(断路器)或手动禁用时,其状态显示为UNHEALTHY。负载均衡器不会通过此上游将任何流量定向到此目标。
节点状态不会在集群之间进行同步。
kong会根据响应更新计数器
健康-增加成功,清除其他计数器
连接失败-增加target的“TCP”失败计数器,清除成功计数器
响应超时-增加超时计数器,清成功
不健康-增加http失败计数器,清成功
不健康的target不会从loadbalancer中删除,因此在使用散列算法时不会对负载均衡器的布局产生任何影响(不健康的target将被跳过);
配置active health checks下的配置项
- healthchecks.active.concurrency - 并发检查的target数目
- healthchecks.active.https_verify_certificate - 使用HTTPS执行健康检查时是否检查远程主机的SSL证书的有效性
- healthchecks.active.https_sni - 使用HTTPS执行健康检查时的SNI(服务器名称标识)主机名。 当target使用IP时,只有配置SNI才可以正常验证目标主机的证书。
- 失败的TLS验证会增加“ TCP失败”计数器; “ HTTP失败”仅指HTTP状态代码,无论是通过HTTP还是HTTPS进行健康检查。
- 被动可能误杀
- 主动和被动健康检查的状态码不能冲突
- 健康检查中,tcp和http是两种错误,如果tcp失败,不会在http_failure中计数
kong的熔断基于健康检查,本身只有请求终止插件,不够智能。
2.6 nginx/kong获取真实ip
在黑白名单中,限流使用ip限流等通过真实ip使用的插件,获取经过多层代理的真实的客户端ip,需要修改相关配置来获取。
在kong之前的nginx代理中添加命令
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
在kong.conf中配置
real_ip_header=X-Forwarded-For
real_ip_recursive=on
trusted_ips=0.0.0.0/0
2.7 限流
限流用于控制发送到上游服务的请求的速率。 它可用于防止 DoS 攻击、限制 Web 抓取和其他形式的过度使用。 没有速率限制,客户端可以无限制地访问您的上游服务,这可能会对可用性产生负面影响。
Kong Gateway通过使用速率限制插件对客户端施加速率限制。 启用速率限制后,客户端在可配置时间段内可以发出的请求数受到限制。 该插件支持将客户端标识为消费者或通过请求的客户端 IP 地址。
限流策略:
cluster(无db模式不适用):kong服务器中
local:本地节点内存
redis:redis服务器,节点间共享
cluster | 准确,无需额外组件支持 | 相对最大的性能影响,每个请求都强制对底层数据存储进行读取和写入。 |
---|---|---|
redis | 准确,比cluster策略对性能的影响更小 | 需要额外的 redis 安装,比local策略更大的性能影响 |
local | 最小的性能影响 | 不太准确,除非在 Kong 前面使用一致性哈希负载均衡器,否则在扩展节点数量时会发散 |
启用插件后会在响应头的head中添加
RateLimit-Limit: 6 允许的限制
RateLimit-Remaining: 4剩余的请求
RateLimit-Reset:47 重置配额的剩余时间
kong的限流不准确时:可能kong的限流没有考虑并发情况,延迟,配置redis解决
2.8 部署方式
Konnect(收费)
- 通过单个 SaaS 控制平面管理所有 API 和服务;
- 跨任何环境预置高性能 API 网关;
- 简化 API 安全性、合规性和用户管理;
- 获得所有服务的实时集中视图;
- 通过强大的插件和集成即时扩展功能。
混合模式
在混合模式下,群集中的 Kong 网关节点分为两个角色:控制平面 (CP),其中管理配置并提供管理 API,以及数据平面 (DP),为代理提供流量。许多 DP 节点连接到单个 CP 节点。DP节点不像传统部署方式那样直接访问数据库内容,而是与CP节点保持连接,实时接收最新配置。
相较于传统模式(多个实例,访问同一个数据库)的优点:
1.减少数据库访问量:现在只有CP节点直接连接数据库
2.提高安全性:一个DP节点的服务器遭受入侵不会影响到其他的DP节点
3.易于管理:只需要通过CP节点就可以获取集群状态信息
传统(数据库)模式
在传统模式下,Kong Gateway 需要一个数据库来存储已配置的实体,例如路由、服务和插件。Kong Gateway 支持 PostgreSQL 10+ 和 Cassandra 3.11.x 作为其数据存储。
在传统模式下运行 Kong 网关是开始使用 Kong 的最简单方法,它也是唯一支持需要数据库的插件的部署拓扑,例如集群策略的速率限制或 OAuth2。但是,也有一些缺点。
在传统模式下运行时,每个 Kong 网关节点都作为控制平面 (CP) 和数据平面 (DP) 运行。这意味着,如果任何节点遭到入侵,则整个正在运行的网关配置都会受到威胁。相比之下,混合模式(如下所示)具有不同的 CP 和 DP 节点,从而减少了攻击面。
无数据库和声明式模式
启用无数据库模式来降低 的复杂性并创建更灵活的部署模式。在此模式下,路由、服务和插件等配置的实体存储在节点上的内存中。
在无数据库模式下运行时,使用第二个文件向 Kong 网关提供配置。此文件包含使用 Kong 的声明性配置语法的 YAML 或 JSON 格式的配置。
无数据库模式也被 Kong 入口控制器使用,其中 Kubernetes API 服务器使用 Kong 的端点在任何时候进行更改时更新内存中的运行配置。/config
好处:减少依赖关系数量;配置始终处于已知状态;非常适合 CI/CD 方案中的自动化。
3.其他插件
3.1 监控
API 网关将您的应用程序与外界隔离并提供关键路径 保护您的上游服务。了解 API 网关的状态 系统对于提供可靠的基于 API 的系统至关重要。
有许多可用的监控和警报系统,Kong Gateway与 多种解决方案:
Prometheus 是一个开源系统监控和警报工具包。 Prometheus 提供了一种多维度的时间序列数据模型和查询语言。 普罗米修斯监控指南 演示如何安装和配置 Kong Gateway Prometheus 插件。
Datadog是一种流行的基于云的基础架构和应用程序监控服务。 有关以下方面的信息 将Kong Gateway与Datadog集成。您还可以将Datadog插件与Kong Gateway集成以获取更多见解。
StatsD 是一个轻量级网络守护进程,可侦听 UDP 或 TCP 并将聚合值发送到一个或多个后端服务。Kong Gateway直接支持StatsD 与 StatsD 插件。使用 StatsD 进行监视可提供 启用 StatsD 的分步指南。
3.2 代理缓存
基于可配置的响应代码和内容类型以及请求方法缓存响应实体。缓存实体配置一段时间,之后会重新请求。缓存实体也可以在过期之前通过Admin API强制清楚
3.3 黑白名单
白名单权限更高,黑白都设置,是可以访问的
3.4 日志
/var/lib/docker/overlay2/kong镜像所在地址/merged/tmp/file.log
request 包含有关客户端发送的请求的属性
response 包含有关发送到客户端的响应的属性
tries 包含负载均衡器为此请求进行的(重新)尝试(成功和失败)列表
route 包含有关所请求的特定路线的Kong属性
service 包含与所请求的路线相关联的服务的Kong属性
authenticated_entity 包含有关经过身份验证的凭据的Kong属性(如果已启用身份验证插件)
workspaces包含与请求的路由关联的工作空间的Kong属性。仅限Kong Enterprise版本> = 0.34。
consumer 包含经过身份验证的使用者(如果已启用身份验证插件)
latencies:包含一些有关延迟的数据:
proxy 是最终服务处理请求所花费的时间
kong 是运行所有插件所需的内部Kong延迟
request是从客户端读取的第一个字节之间以及最后一个字节发送到客户端之间经过的时间。用于检测慢速客户端。
client_ip 包含原始客户端IP地址
started_at 包含开始处理请求的UTC时间戳。
latencies:
包含一些有关延迟的数据:
- proxy 是最终服务处理请求所花费的时间
- kong 是运行所有插件所需的内部Kong延迟
- request是从客户端读取的第一个字节之间以及最后一个字节发送到客户端之间经过的时间。用于检测慢速客户端。
- client_ip 包含原始客户端IP地址
- started_at 包含开始处理请求的UTC时间戳。
ps:日志的路径配合要注意,kong需要有这个路径文件的读写权限,否则无法写入日志
chown -R kong kong
reopen:true
问题:在没有权限读的文件夹中,给了子文件夹权限也不行,给了跟文件夹权限就能写了
3.5 请求转换,认证,虚拟服务
请求转换
支持对请求和相应中的body,header,querystring的删除,替换,重命名,添加。
https 认证:certificate add 公钥,私钥,关联域名
证书:
新建consumer,添加证书basic,添加用户名和密码,添加组
basic acl consumer
虚拟服务
一般用于测试
kong.conf中配制plugins = bundled,kong-service-virtualization
采用luarocks install kong-service-virtualization安装或者直接将文件复制进usr/local/share/lua/版本/kong/plugins中
kong restart即可
4.Kong修改nginx配置
4.1 Kong代理tcp请求
下面用mysql举例,kafka等同理
环境,mysql数据库放在windows上了,开启远程连接。linux直接装的kong,没用容器。
mysql开启远程连接
USE mysql;
UPDATE user SET host=‘%’ WHERE user=‘root’;
FLUSH PRIVILEGES;
还需要在windows防火墙新建个入站规则,把3306端口开放了
4.1.1 使用kong配置
Kong入门学习实践(6)HTTPS与TCP流代理
Kong转发TCP请求
开启stream模块
/etc/kong/kong.conf
stream_listen = 0.0.0.0:7000
配置service route 协议需要调整为TCP,同时需要设置SNIs、Sources、Destinations三者中的任意一个,这里我们选择设置Sources(即访问的源IP地址)
配置文件yaml格式如下
services:
- connect_timeout: 60000
enabled: true
host: 192.168.126.1
name: mysql-s
port: 3306
protocol: tcp
read_timeout: 60000
retries: 5
routes:
- https_redirect_status_code: 426
name: mysql-r
path_handling: v1
preserve_host: false
protocols:
- tcp
regex_priority: 0
request_buffering: true
response_buffering: true
sources:
- ip: 192.168.126.129
- ip: 192.168.126.1
strip_path: true
write_timeout: 60000
4.1.2 向kong注入nginx配置
etc/kong/kong.conf的配置
nginx_stream_include=/usr/local/kong/stream.conf
stream_listen = 192.168.126.1:3306
backlog:等待连接的队列的最大长度。listen函数中的参数,握手成功队列(三次握手过程中收到客户端的ack放入accept_queue)队列的大小。当客户链接请求大于设置个数,其他未进入链接缓冲池的客户端在tcp层的tcp模块会重新链接,直到超时。
reuseport:允许多个套接字监听同意ip和端口的组合。内核能够在这些套接字中对传入的连接进行负载均衡。对于nginx而言,可以减少某些场景下的锁竞争而改善性能。
同一个ip端口多个socket去监听,每个socket可对应一个工作线程,内核决定分给哪个socket获得连接。可以减少工作进程请求资源加锁之间的竞争。
开启resuseport时,accept_mutex参数无效,因为互斥锁对于reuseport是多余的。
/usr/local/kong/stream.conf的配置
upstream mysql {
server 192.168.126.1:3306;
}
server {
listen 3306;
proxy_connect_timeout 10s;
proxy_timeout 30s;
proxy_pass mysql;
}
最后执行kong restart 即可
4.2 kong修改nginx access.log日志
参考kong笔记——自定义 nginx模板/日志格式
进入配置目录,修改nginx_kong.lua文件
cd /usr/local/share/lua/5.1/kong/templates/
在128行附近 server上面定义变量
log_format main ‘$remote_addr | $remote_user | $time_local |
$request | $status | $body_bytes_sent | $http_referer | $request_time
| $request_length | $http_user_agent | $http_x_forwarded_for |
$upstream_response_time’;
在server中的access_log后添加日志模板 main
kong reload
tail -f /usr/local/kong/logs/access.log
通过在执行前后的access日志查看配置已经生效
5.安装
Docker下安装
前置条件
在linux下安装,
安装docker,net,npm,kong和postgres执行命令时会自动安装
docker安装和部分镜像
docker要配置镜像加速地址阿里云镜像
常用命令
docker rm -f $(docker ps -a)
docker rm -f 容器id
docker images
docker ps -a
docker stop 容器id
docker network ls
netstat -tnlp
ps -ef | grep java/kong 查看java/kong进程
kill -9 PID号
jps
sudo docker inspect -f=’{{.Name}}’ $(sudo docker ps -a -q)-----docker
namesudo docker inspect -f=’{{.NetworkSettings.IPAddress}}’ $(sudo docker
ps -a -q)-----docker ip
docker inspect 容器id–查看容器内部细节#7.查看容器的运行日志
docker logs[0PTIONS]容器id或容器名—-查看容器日志-t加入时间戳
find / -name *flag*
安装步骤
1.创建docker网络
docker network create kong-net
docker network ls 查看docker网络
docker network rm 自定义networkID 移除网络
2.运行postgresql的数据库
docker run -d --name kong-database \
--network=kong-net \
-p 5432:5432 \
-e "POSTGRES_USER=kong" \
-e "POSTGRES_PASSWORD=kong" \
-e "POSTGRES_DB=kong" \
--restart always \
postgres:9.6
3.初始化数据库(迁移数据)
docker run --rm \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_PG_PORT=5432" \
-e "KONG_PG_USER=kong" \
-e "KONG_PG_PASSWORD=kong" \
-e "KONG_PG_DATABASE=kong" \
kong:latest kong migrations bootstrap
不加密码我的会报错,版本低了用konga也会报错
4.运行kong
docker run -d --name kong \
--network=kong-net \
-e "KONG_TRUSTED_IPS=0.0.0.0/0,::/0" \
-e "KONG_REAL_IP_HEADER=X-Forwarded-For" \
-e "KONG_REAL_IP_RECURSIVE=on" \
-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 80:8000 \
-p 443:8443 \
-p 8001:8001 \
-p 8444:8444 \
--restart always \
kong:latest
linux 下安装kong
安装问题
postgres 权限问题 chmod 700 /var/lib/pgsql/9.6/data
centOS 卸载 postgresql
yum remove postgresql*
rm -f /etc/init.d/postgresql-10
Postgres CentOS 7: Data directory is not empty
rm -rf /var/lib/pgsql/9.5/data
cant find module
找到指定目录,安装
konga的js脚本过低,在postgressql的依赖中已经废弃
Warning: Grunt functionality may not work properly with your current configuration.
npm install sails-hook-grunt --save
安装kong
kong.conf中的配置
database = postgres
pg_host = 192.168.126.132
pg_port = 5432
pg_timeout = 5000
pg_user = kong
pg_password = kong
pg_database = kong
declarative_config = /usr/local/kong/bin/kong.yml (可选)(reload时使用该声明配置文件)
admin_listen = 0.0.0.0:8001 reuseport backlog=16384, 0.0.0.0:8444 http2 ssl reuseport backlog=16384(可选)(确定哪个ip可以使用admin api发布声明配置文件)
kong migrations bootstrap
kong start -c kong.conf
kong config -c kong.conf init//创建声明式配置文件
kong config parse apis.yml 检测配置文件是否合法
kong check <path/to/kong.conf>//验证配置
kong reload 重新加载
声明性配置文件kong.yaml中
- 嵌套只能指定一对一的关系如果要一对多,一的下级要加 -
- _format_version: “2.1”,它指定声明性配置语法格式的版本号。这也匹配解析文件所需的最低版本的 Kong。
- _transform 明文密码设置为t,否则设置为f,避免二次加密
无DB模式
在kong.conf中设置 database = postgres
限流在 DB-less 模式下,local和redis策略可用,cluster不能使用
local内存计数器
cluster kong数据库
deck工具
用来下载当前kong的声明式配置文件
mac
$ brew tap kong/deck
$ brew install decklinux
$ curl -sL https://github.com/kong/deck/releases/download/v1.6.0/deck_1.6.0_linux_amd64.tar.gz -o deck.tar.gz
$ tar -xf deck.tar.gz -C /tmp
$ sudo cp /tmp/deck /usr/local/bin/
docker
docker pull kong/deck
命令
deck ping 检查连接
deck dump 获取当前配置到deck安装目录中的kong.yaml
deck sync 保存文件。从您的终端,同步配置以更新 Kong
通过Kong的restful API生成nginx配置文件
- 配置upstream
curl -X POST http://localhost:8001/upstreams --data “name=helloUpstream”
新建组 - 配置target
curl -X POST http://localhost:8001/upstreams/helloUpstream/targets --data “target=localhost:3000” --data “weight=100”
在组名下新建target,(配置权重) - 配置Service
curl -X POST http://localhost:8001/services --data “name=hello” --data “host=helloUpstream”
新建Service,对应组 - 配置route
curl -X POST http://localhost:8001/routes --data “paths[]=/hello” --data “service.id=
014edc3a-0fc8-4f03-b15c-05d8bc2d8368”
id是服务id
新建路由,当访问路径下hello时访问service
默认情况下,KONG监听的端口为:8000、8001、8443、8444
处理用户请求http:8000.https:8443
管理员进行管理http :8001 https:8444
8444:通过此端口,管理者可以对HTTP请求进行监控;
其中 8000/8443分别是用来监听来自客户端的Http和Https请求,等价于Nginx默认的80端口,而8001端口便是默认的管理端口,可以通过HTTP Restful API来动态管理Kong 的配置;
除了以上方式也可以直接用图形化界面来进行处理
图形化界面
kongdashboard
docker run -d --name kong-dashboard --rm -p 8080:8080 pgbi/kong-dashboard start --kong-url http://192.168.126.129:8001 --basic-auth kong=123
-d 后端跑
–rm 临时跑,一关就没了 生产环境关闭
kongUser 用户名
123 密码
konga
以web的方式管理kong,需要数据库的支持,支持postgre
1.初始化数据库
docker run --rm pantsel/konga:latest -c prepare -a postgres -u postgresql://kong:kong@192.168.126.129:5432/konga
kong名和密码 数据库的地址
2.创建数据库
docker run -d -p 1337:1337 --network kong-net \
-e "TOKEN_SECRET=kong" \
-e "DB_ADAPTER=postgres" \
-e "DB_URI=postgresql://kong:kong@kong-database:5432/konga" \
-e "NODE_ENV=production" \
--name konga \
--restart always \
pantsel/konga
先创建个管理员帐号
konga可以管理多个kong
选择管理kong的地址
http://192.168.126.129:8001
界面
pgadmin postgre数据库界面
docker run -d -p 8090:80 \
--name=pgadmin \
--network=kong-net \
--link kong-database:kong-database \
-e "PGADMIN_DEFAULT_EMAIL=admin@1000phone.cn" \
-e "PGADMIN_DEFAULT_PASSWORD=kong" \
--restart always \
-d dpage/pgadmin4
输入设置的密码登录
postgres的地址,用户名和密码
8.其他
kong限流根据路由自定义报错
修改插件,获取path,根据path判断返回什么样的错误
百度之后发现修改文件并没有作用,然后发现我们环境不一样,他直接安装在linux中,而我的kong是在docker镜像中存储,因此找到我的kong的地址。
查看kong容器的id
查看容器详细信息
找到当中的数据存储位置
进入/var/lib/docker/overlay2/docker镜像数据存储地址/merged/usr/local/share/lua/5.1/kong/
修改两个文件,因为要根据路径来判定错误,因此要在原来限流报错的方法里面添加path参数,重写error方法(因为工具类utils.lua中无法引用获得请求path方法,因此在其他位置重写)
1./var/lib/docker/overlay2/docker镜像数据存储地址
/merged/usr/local/share/lua/5.1/kong/plugins/rate-limiting/handle.lua
在191行响应报错方法中添加kong.request.get_path_with_query()参数。
修改merged/usr/local/share/lua/5.1/kong/pdk/response.lua文件
重写_RESPONSE.error方法
在方法头尾各加一个path参数
将其中的get_error_template中的方法重写一下
改为自己的方法,get_error_template在
/var/lib/docker/overlay2/docker镜像存储地址/merged/usr/local/share/lua/5.1/kong/tools/
Utils 1251-1350
错误模板是一个数组表,唯一键值对,同一个索引只能对应一个错误模板,因此如果要自定义返回页面,需要另写一个模板数组,写在一起最后的会覆盖前面的。
最后通过判断返回
限流报错后:
因为返回的html模板就在工具类utils.lua中,因此就想直接在utils中判断并修改,否则还得从别的地方传过来。
获取path的方法在插件的request中有写
1.借用request代码获取path------->api禁用,初始化失败,部分方法未成功加载
百度:简单操作就是将原接口loadData改成ngx.time.at(0,loadData)即可。
loadData为function,function修改语法需要研究,
这个根本无法下手
2.直接引用request 方法
request.lua只提供了new
2.1 调用new,需要传值self,尝试传值为nil
2.2 自己添加接口,必须从new调,不从new调,api禁用,从new调传不了一个正常的self值,问题回到 function修改语法需要研究
lua:和. 在原本自带方法调用没用:
报错nil网上换用:,同样报nil错误
然后发现别的文件调用方法,
并不需要2,使用1就行了。然后还是不行。
这时候心态已经崩了,问了问组长梳理了一下。
在utils掉不成功,是因为还没加载好request。成功放弃了在utils中获取路径。
然后在插件报错handle.lua中找到调用了response的error方法
在response中调用了utils的gettemplate方法。在response中重写gettemplate方法
因为在response中也调用不了request的获取path的方法,因此在handle中获取path,并传到response,然后重写error。
添加模板后判断发现怎么都是同一个,发现lua的数组是唯一索引,因为用了字符串作为索引,后面的值会覆盖,然后多写了个几个数组,最后终于实现了限流根据路由自定义报错。
konga安装的坑
1.node的版本别太高了
2.sails的版本最新konga里的package-lock.json中sails版本就是0.12.xx
npm安装之后依赖不要, audit fix ,它自动修完之后会替你升级sails版本,升级之后konga就起不来了。
内网安装konga的时候
把外网安装好的依赖文件node_modules拷贝到项目根目录就行了
注册之后是空白,把正常konga软件目录中asset中的bower_components也放进去就可以了
Nginx和X-Forward-For
1.启动命令: ./nginx
2.重启命令: ./nginx -s reload
3.关闭命令: ./nginx -s stop
nginx在配置代理转发时,如果在proxy地址后面加/表示绝对根路径,否则是相对路径,会把匹配路径也代理走。
nginx中的常用变量:
$server_port :nigix监听的端口
$proxy_port : 服务器真正访问的端口
proxy_set_header Host $http_host; #设置请求头"Host"值(为入口域名和端口)
proxy_set_header Host $proxy_host; #设置为upstream对应服务器(IP和端口)
$request_uri #完整的原始请求URI,访问的URL除去域名(或IP)和port,如/nginx/varindex?a=1&b=2
$remote_addr 客户端ip地址
proxy_set_header Host $ host:$server_port;#设置为入口Host和当前nginx监听端口
- X-Real-IP:自定义头
- proxy_set_header X-Real-IP $remote_addr;
$remote_addr 只是上一个代理的地址
tcp连接中真实和客户端地址,无法伪造,因为tcp连接需要三次握手,伪造无法连接 - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
kong在0.11后会把请求请过的代理放入 x-forwarded - proxy_set_header Host $host;
把域名传过去 会报错 - proxy_set_header X-Forwarded-Proto $scheme;
传递协议名 可有可无 - proxy_redirect off;
用来修改被代理服务器传来的应答头中的location和refresh字段,可以通过该指令设置
例如 proxy_redirect http://localhost:8000/two/ http://frontend/one/;
将Location字段重写为http://frontend/one/some/uri/。
参数off将在这个字段中禁止所有的proxy_redirect指令。 - expires -1
nginx控制页面缓存
-1 永远过期
off 不修改expire和cache-control的值
max 十年
epoch:指定“Expires”的值为 1 January,1970,00:00:01 GMT
max:指定“Expires”的值为31 December2037 23:59:59GMT,"Cache-Control"的值为10年
X-Forwarded-For
Squid开发的,用于识别通过 代理或者负载均衡器 原始ip连接到web服务器的客户机地址非rfc标准。
设置后每条转发会有记录 例如client1, proxy1, proxy2,非rfc标准,X-Forwarded-For默认没有,需要强制添加
如果我们想要通过X-Forwarded-For获得用户的ip,我们需要自己在nginx添加如下配置:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
是增加不是覆盖
$proxy_add_x_forwarded_for = X-Forwarded-For + $remote_addr
一个web应用通过两次转发
第一次转发 X-Forwarded-For 空 $remote_addr 用户ip $proxy_add_x_forwarded_for 用户ip
第二次转发 X-Forwarded-For 用户ip $remote_addr 上一个台nginx的ip
$proxy_add_x_forwarded_for 用户ip,第一台nginx的ip
第二次转发 X-Forwarded-For 用户ip 第一台nginx的ip $remote_addr 上一个台nginx的ip
$proxy_add_x_forwarded_for 用户ip,第一台nginx的ip 第二台nginx的ip
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)