Kong 网关
Kong介绍
Kong 基于OpenResty(Nginx + Lua模块)编写的高可用、易扩展的,性能高效且稳定,支持多个可用插件(限流、鉴权)等,开箱即用。
相对于纯Nginx ,Kong具有以下优点:
(1)高性能:亚毫秒级处理延迟,可支持关键任务用例和高吞吐量。
(2)可扩展性:可插拔的体系结构,可通过Kong的Plugin SDK扩展 Kong。
(3)可移植性:Kong 可以部署在任何平台、或者云。
为什么要使用Kong

Kong组件

其中:
Nginx和OpenResty层,是Kong的基础,因为Kong是一款基于OpenResty (Nginx + Lua) 编写的高可用、易扩展的API Gateway。
DataStore层:Kong的配置文件可以支持化的存储在NoSQL中,可选:Cassandra、PostgreSQL。
Plugin层:如果想拓展Kong的功能,只需要提供对应的插件就行。可以直接使用现成的插件,也可以编写自定义插件。
RESTful层:它支持通过RESTful API的方式来操作操作和配置Kong(管理Nginx的配置文件)。而且Kong也支持在可视化的界面下配置。
Kong架构

相关概念
Kong网关管理员使用对象模型来定义他们想要的流量管理策略。该模型中的两个重要对象是服务和路由。服务和路由以协调的方式进行配置,以定义请求和响应在系统中的路由路径。

service
在 Kong Gateway 中,服务是现有上游应用程序的抽象。对应着后端的一个服务,或者是一个App。
服务可以存储诸如插件配置和策略之类的对象集合,并且它们可以与路由关联。
route
路由是到上游应用程序中的资源的路径。不同的route对应着service中的不同接口。
在 Kong Gateway 中,路由通常映射到通过 Kong Gateway 应用程序公开的接口。路由还可以定义将请求匹配到关联服务的规则。因此,一个路由可以引用多个端点。路由应该有一个名称、路径或路径,并引用现有的服务。
路由支持以下配置:
- Protocols: 用于与上游应用程序通信的协议。
- Hosts:匹配路由的域名列表。
- Methods:匹配路由的 HTTP 方法
- Headers:请求标头中预期的值列表
- Redirect status codes:HTTPS 状态码
- Tags:用于将路由分组的可选字符串集
Upstream和Target
Upstream:和nginx中的upstream差不多,都对应着一组服务节点。
Target:对应着一个api服务节点。
Kong相关概念可以按下图来理解:

Kong管理后台
Konga
https://github.com/pantsel/konga 之前社区版本的管理后台(自从官方推出Kong Manager之后就没更新了)
Kong Manager
Kong Manager是Kong官方推出的管理后台,也有开源版本 Kong Manager Open Source(也称OSS版本)。
Kong安装
Kong支持多种平台安装。👉 https://konghq.com/install#kong-community

本地环境部署
本地快速搭建kong环境,推荐使用官方提供的docker-compose.yml
1、git clone 官方提供的代码库至本机,然后切换到该目录下。
$ git clone https://github.com/Kong/docker-kong
$ cd docker-kong/compose/2、执行以下命令启动Kong网关相关实例。
$ KONG_DATABASE=postgres docker-compose --profile database up -dKong 网关现在可以在本地主机的下列端口上使用:
:8000- Kong 网关的流量入口(外部流量通过8000端口流入,经过Kong转发至实际服务节点):8001- Kong 网关的配置端口(可以通过Admin API 或decK对Kong进行配置):8002- 可以通过localhost:8002访问 Kong 的管理 Web 用户界面(Kong Manager)
启动成功后,可以使用浏览器打开 localhost:8002 看到以下界面。

实际生产环境部署方案
在实际的生产环境下的部署方案一般将API Gateway挂到负载均衡下。

此外,各大云厂商都有提供现成的 API Gateway 产品,可直接购买使用。
路由转发/API转发
一个外部请求到达 Kong 网关之后要先进行路由匹配,匹配成功后会将请求转发到对应的服务上。
一个服务可以配置多个路由。
可以通过API对Kong进行配置,也可以直接使用Kong Manager管理界面进行配置。
这里演示如何通过Kong Manager管理界面进行配置。
0、前提准备
编写以下代码,默认会在9870端口提供简单的HTTP服务。
package main
import (
"flag"
"fmt"
"net/http"
)
func main() {
var (
port int
msg string
)
flag.IntVar(&port, "port", 9870, "http server port")
flag.StringVar(&msg, "msg", "resp", "resp message")
flag.Parse()
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, msg+" from %d", port)
})
err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
if err != nil {
fmt.Printf("http server failed, err:%v\n", err)
return
}
}建议按以下顺序进行配置。
1、添加Service
根据业务实际情况,新增Service。



2、添加路由
有了Service之后,我们需要还定义Route,将外部访问Kong的流量引向 Service。



3、测试
使用浏览器打开 http://localhost:8000/mall ,可以看到如下响应。

负载均衡
负载均衡也是比较常用的配置。
之前我们配置的 Service 中都指定了一个具体提供服务的实例URL,如果我们有多个实例同时提供服务就需要定义Upstream。
设置upstreams 和 targets
找到先前定义的Service,打开编辑



在菜单栏找到 Upstream 菜单,新建一个 Upstream。








同时在本地的9870和9871两个端口分别启动先前的HTTP服务。
此时,使用浏览器多次访问 http://localhost:8000/mall,会显示分别收到 9870和9871的返回响应。
默认情况下,会以轮询方式请求两个Target。
常用的发布策略
Kong可以支持实现不同场景下的灰度发布和测试,可以满足金丝雀发布、蓝绿部署与 A/B 测试等业务场景。
通常有两种流量切分的方式:一是基于用户请求的流量切分,具体又包括了基于Request Header的流量切分与基于Cookie的流量切分两种方式;

另一种方式是**基于权重的流量切分,**如下图所示

这里新增一个 mall_service_new Service和一个mall_route_new Route,路由配置中按下图添加一组请求头。

新增一个 mall_upstream_newUpstream和一个9872端口的Target。

安装ModHeader插件



插件
Kong 通过插件机制实现强大的可扩展性。我们可以使用官方和社区提供的各种插件,也可以自定义开发插件。

Rate Limiting(速率限制)

Proxy Caching (缓存)

Authentication with JWT (认证)
C端用户 –> 登录 –> 下发JWT
C端用户携带JWT –> Kong网关(认证校验)–> 业务接口
