Kong 是一款开源的 API 平台,它是基于 Nginx 扩展版 OpenResty 的 Lua 应用,其将 Nginx 的配置解构成多个 Lua 应用模块,通过 Lua 应用实现了 Nginx 中各请求阶段的操作。Kong 把 Nginx 操作的配置存储在外部数据库中,并提供了 REST 风格的管理接口,用户可以通过管理接口实现 Kong 所有功能的动态操作。
Kong 支持 PostgreSQL 和 Cassandra 两种数据库,可以通过数据库的主从同步或分布式部署实现配置数据的高可用,多台 Kong 服务器通过数据库共享配置数据,实现对多台 Kong 服务器的统一配置管理。Kong 提供了基于 Lua 脚本实现的多种功能插件,在将用户请求转发给后端服务之前,用户可使用这些插件实现用户请求的认证、访问限流、链路跟踪、日志处理等各种操作。
Kong 是一个微服务网关平台,它作为微服务 API 的统一入口对外提供服务,为方便 API 的管理,定义了如下术语。
Kong 系统中,把访问微服务 API 的用户定义为消费者,用户可以通过消费者对象定义消费者身份,并可通过相关插件实现消费者访问路由规则或服务的授权。
消费者接口是消费者访问微服务 API 的接口,用于实现后端被代理目标的访问转发。
管理接口是进行 Kong 功能配置的接口,可通过管理接口对操作对象进行配置,其约定了 REST 风格的语法,用户可以很容易地通过管理接口实现对 Kong 的功能配置。
Kong 为方便实现 Nginx 配置的动态管理,定义了多个操作对象和对象参数,通过管理接口对不同的操作对象按照该对象的对象参数进行配置,可以非常快速地完成 Kong 的管理操作。Kong 常用的操作对象有目标(target)对象、上游(upstream)对象、服务(service)对象、路由(route)对象、消费者(consumer)对象、插件(plugin)对象、证书(certificate)对象、CA 证书(CA Certificate)对象、SNI 对象。
目标对象和上游对象构成真实的被访问服务器集群,可通过上游对象实现目标对象的负载均衡、会话保持等配置。路由对象和服务对象构成了 Nginx 虚拟主机的访问入口路由和转发目标的配置,服务对象可以直接代理一个外部主机域名,也可以直接关联上游对象实现用户请求的转发。
插件对象由不同的功能插件脚本组成,其可以与路由对象、服务对象及消费者对象关联,实现消费者对象请求转发给后端服务之前的各种功能操作。消费者对象用于描述客户端标识,通过认证及 ACL 插件可以对其进行访问认证和访问路由对象或服务对象的授权。证书对象、CA 证书对象、SNI 对象均用于 SSL 相关配置。
由于管理工具 Konga 基于管理接口提供了更加方便的 Web 化操作方式,这里为方便读者理解和操作,便直接使用 Konga 配置界面的对象参数介绍 Kong 的相关操作对象和对象参数。
目标对象等同于 Nginx 配置中上游服务器的主机,一个上游对象可以关联多个目标对象,目标对象的配置是动态即时生效的。由于上游对象需要维护目标对象的变更记录,因此目标对象只能手动或通过管理接口 DELETE 方法设置权重为 0。目标对象的对象参数说明如下表所示。
参数名 | 参数说明 |
---|---|
Target | 被访问的真实服务器,可以是 IP:Port,默认端口为 8000,也可以是域名 |
Weight | 当前目标对象在上游对象中的权重,默认为 100,取值范围为 0~1000 |
Kong 的上游对象用于描述 Nginx 配置指令域 upstream 的配置内容,Kong 支持对其所关联的目标对象进行主动或被动健康检测的设置。Kong 为方便上游对象及其关联目标对象的管理,通过 Lua 脚本实现了加权轮询(round-robin)、一致性哈希(consistent-hashing)、最少连接(least-connections)负载均衡算法,默认为轮询。
一个上游对象由多个目标对象组成,可以通过管理接口实现目标对象的动态变更。通常在一致性哈希算法和加权轮询负载策略下,目标对象数量的动态变化会引起负载策略的重新计算,虽然这种影响无法避免,但为了降低因负载算法重新计算产生的影响,Kong 为每个上游对象定义了一个环平衡器(ring-balancer),每个环平衡器有预先定义好数量的插槽(slot),上游对象中的每个目标对象将根据其权重被分配到相应数量的插槽,当目标对象数量变化时,只需对部分目标对象重新分配插槽而不需要负载策略的重新计算。
环平衡器只有在上游对象更改总插槽数时才会进行负载策略的重新计算,目标对象初始分配的插槽数官方建议至少为 100 个,当上游对象预期为 8 个时,即使初始时为两个目标也至少应将总插槽数定义为 800。上游对象的对象参数说明如下表所示。
参数名 | 参数说明 |
---|---|
Name | 上游对象实例的名称 |
Hash on | 设置是否启用一致性哈希负载,选项为 none 及哈希类型 consumer、ip、header 或 cookie,默认为 none,即仅使用加权轮询对目标对象实现负载 |
Hash on header | 当哈希类型被设置为 header 时,此参数用于指定请求头字段的名称 |
Hash on cookie | 当哈希类型被设置为 cookie 时,此参数用于指定 cookie 字段的名称,如果请求的 cookie 中无此字段,Kong 将为该字段生成一个值并在响应头中设置客户端 cookie |
Hash on cookie path | 当哈希类型被设置为 cookie 时,此参数用于指定 cookie 路径的值,默认为 / |
Hash fallback | 如果启用一致性哈希负载策略,若用户的请求无法计算哈希值时,此处可指定一个备份哈希类型,选项为 none、consumer、ip、header 或 cookie,默认为 none。如果哈希类型设置为 cookie,则参数无效 |
Hash fallback header | 当备份哈希类型被设置为 header 时,此参数用于指定请求头字段的名称 |
Slots | 上游对象环平衡器的总插槽数,取值范围为 10-65536,默认值为 1000 |
Kong 中的服务(Service)对象是指被代理的服务目标,既可以是一个域名,也可以是一个上游对象的名称,区别在于是否由 Kong 实现负载均衡。每个服务对象可以关联多个路由对象。一个服务对象只能关联一个上游对象或被代理的主机域名。服务对象的对象参数说明如下表所示。
参数名 | 参数说明 |
---|---|
Name | 服务对象实例名称 |
Description | 服务对象实例描述 |
Tags | 服务对象实例标签 |
Url | 为方便配置,通过 URL 形式描述被代理主机的通信协议(Protocol)、主机(Host)、端口(Port)及路径(Path)的配置 |
Protocol | 与被代理服务目标的通信协议。可选项为 http 或 https |
Host | 上游对象名或被代理的主机域名 |
Port | 当前主机端口。默认为 80 |
Path | 被代理主机的访问路径。默认为空 |
Retries | 访问失败时执行重试的次数。默认为 5 |
Connect timeout | 与被代理主机的连接超时时间,单位为毫秒。默认为 60000 |
Write timeout | 与被代理主机的连续写超时时间,单位为毫秘。默认为 60000 |
Read timeout | 与被代理主机的连续读超时时间,单位为毫秒。默认为 60000 |
路由(Route)对象用于表示 Nginx 配置中虚拟主机的配置,对应 Nginx 的指令域 Server 及其包含的 location 配置。Kong 配置结构中,因为服务对象用于关联被代理的目标,而路由对象单独存在没有意义,所以其必须与服务对象关联使用。路由对象的对象参数说明如下表所示。
参数名 | 参数说明 |
---|---|
Name | 路由规则名称 |
Hosts | 当前路由规则匹配的虚拟主机名称,同 Nginx 配置指令 server name 的设置。该指令值是个列表值,可以输入多个 |
Paths | 当前路由规则匹配的路径,同 Nginx 配置指令 location 的配置。该指令值是个列表值,可以输入多个 |
Regex priority | 在同一虚拟主机下,当用户请求的路径被正则匹配到多个时,将只匹配该设定值最低的路由规则,默认值为0 |
Methods | 当前路由规则允许的 HTTP 请求方法。它是个列表值,可以输人多个 |
Strip Path | 当用户请求匹配当前规则时,设置是否在转发给服务对象的请求 URL 中包含当前路由规则匹配的路径。默认值为 false,表示保持用户请求的 URL 不变。当指令值为 true 时,相当于把用户请求 URL 中的当前路由规则匹配的路径替换为空。当代理协议为 GRPC 或 GRPCS 时不能使用该参数 |
Preserve Host | 设置是否将用户请求当前虚拟主机的域名作为转发给服务对象的请求头中 Host 的值。默认为 false,当设置为 true 时,Kong 发送给服务对象请求头中 Host 的值为当前用户请求的域名 |
Protocols | 当前路由规则支持的用户访问协议,该参数选项是个列表值,默认为 ["http","https"],可以输入选项为 http 和 https,当只选 https 时,所有 HTTP 请求都将跳转到 HTTPS |
插件对象用于对用户在消费接口的请求/响应闭环中的不同插件执行方法进行配置,不同的插件与路由对象、服务对象及消费者对象关联,实现对消费者对象在 Nginx 中各请求阶段的相关操作。
Kong 的插件对象既可以关联到服务对象,实现所有该服务的请求控制,也可以关联到路由对象,仅对某些路由接口的请求进行控制,甚至是更细粒度的,仅对指定的消费者进行控制。一个插件在一个请求的生命周期中只运行一次,当一个插件被与多个操作对象关联时,与路由对象、服务对象及消费者对象这3个对象关联的越具体则执行优先级最高,插件的全局配置优先级最低。
消费者对象是描述用户身份的对象,通过认证及 ACL 插件可以对其进行访问认证和访问路由对象或服务对象的授权。
证书对象表示 HTTPS 域名关联的证书,证书对象用于存储 SSL 证书的公共证书/私钥对。Kong 使用这些对象来处理加密请求的 SSL 终止。
CA 证书对象表示受信任的 CA。Kong 使用这些对象来验证客户端或服务器证书的有效性。
Kong 的 SNI(Server Name Indication)对象可与证书对象进行关联,将证书/密钥对绑定到一个或多个域名。SNI 是一种改善 SSL/TLS 的技术,用于对客户端请头中 Host 字段进行处理,通过对 Host 字段的识别解决了当一个服务器绑定多个域名时 SSL 证书选择的问题,服务器将根据 Host 字段的域名返回该域名的 SSL 证书。