Skip to content

Kong简介

https://github.com/Kong/kong

https://konghq.com/

https://docs.konghq.com/

Kong网关的应用横跨互联网、电信、金融、制造、食品等领域,雅虎、GE、Honeywell、VMWare、Cisco、NASDAQ、MasterCard等多家大型企业都在使用。
同时,Kong 公司也是 CNCF 的成员之一,一直在积极推动云原生应用的发展。
但相对而言,Kong 网关在国内显得不温不火,一个主要原因是国内研发人员对网关层的认识还比较模糊,大家主要关注的是业务层代码;
另一个原因是大家对网关层的认识相对局限,由于众多与各语言栈绑定的网关组件的存在(如 Zuul、Spring Cloud Gateway 等),而忽视了更高维度的网关层的必要性。

Kong 是一款基于 OpenResty(Nginx + Lua 模块)编写的高可用、易扩展的开源 API 网关,专为云原生和云混合架构而建,并针对微服务和分布式架构进行了特别的优化。
Kong 网关在世界范围内广受欢迎。它建立在超轻量级代理之上,为海量微服务应用程序提供性能保障和可伸缩性扩展。
用户使用Kong网关可以轻松地对流量进行精细化管理和控制。

OpenResty

http://openresty.org/cn/installation.html

1
brew install openresty/brew/openresty

Kong 网关的发展历程

Kong 网关起源于 2007 年,由 Augusto、Marco、Michele 三人在意大利的一个小车库中开发,当时命名为 Mashup 平台。
在随后7年的时间里,Mashup 平台逐渐占据 API 网关市场的主导地位。2017 年 10 月,Mashup平台正式更名为 Kong,并推出了 Kong 企业版。
2018 年,Kong 公司成立,并发布了 Kong 1.0 版本。直至今日,Kong 版本已经更新到 2.1.0。

在 1.0 版本发布后,Kong 网关受到众多用户的喜爱。如今,全球大约有 200 家企业正在使用 Kong 网关,其中包括一些超大型企业,例如西门子(Siemens)、通用电器(GE)、三星(SAMSUNG)、嘉吉(Cargill)等。
其覆盖的行业也非常广泛,包括互联网/电子商务、电信、软件与技术、金融服务、汽车、食品、饮料和零售等多个领域。
大多数公司使用 Kong 网关来解决自身的痛点问题,以更好地完成微服务架构转型。

2019 年,Kong 公司对外发布了不少更倾向于云原生服务的产品。
例如:Kong 网关升级到了 2.0 版本,并与Kubernetes有机结合,可以作为入口控制器来协调整个 Kubernetes 集群;
Kuma 产品基于 Envoy 的 Service Mesh,降低了系统复杂性并提高了服务可靠性。相信 Kong 公司未来会给我们更多惊喜和更多划时代的新产品。

Kong 网关与传统网关对比

早些年间,服务器市场完全被 Apache 服务器和 Microsoft 的 IIS 服务器所垄断。
这两个服务器代表着两大开发系统的对抗,即选择 Linux 系统还是 Windows 系统。
在 2007 到2008年,我们看到了Nginx服务器的身影,随后其突飞猛进,占据服务器市场的“头把交椅”。
在大流量、超大流量网站的服务器选型中,Nginx更是作为首选,将竞争对手远远甩在身后。

Kong、OpenResty 都是基于 Nginx 打造的新一代服务器。它们兼具Web服务器的功能,但侧重于网关层特性的延伸。下图展示了三者的关系。

KongOpenResty与Nginx的关系
Kong、OpenResty 与 Nginx 的关系

在功能定位上,Kong 和 OpenResty 有很多相似之处,都是基于 Lua 脚本做二次开发。
但 Kong 在 OpenResty 之上又衍生出不少新的概念,对网关内部层级做了更好的抽象,更符合用户使用习惯。
如果你是第一次接触网关层组件,或者希望学习网关层的内部架构设计,Kong 网关都是非常好的选择。

其他主流网关

除了Kong网关之外,网关层生态中还有许多其他成熟的网关可供选择,这里我们会给大家做一些简单介绍。

Træfik

Træfik 是一款云原生的新型 HTTP 反向代理、负载均衡软件,能轻易部署微服务。
它支持多种后端(Docker、Swarm、Mesos/Marathon、Consul、Etcd、Zookeeper、BoltDB、Rest API、File 等),也可以对配置进行自动化、动态管理。
Træfik 整体架构如下图所示。

Trafik整体架构
Træfik 整体架构

Træfik有如下特点。

1)使用Go语言编写、单文件部署、与系统无关,同时提供小尺寸Docker镜像。
2)支持Docker/Etcd后端,天然连接微服务集群。
3)内置Web UI,支持可视化管理。
4)自动配置证书。
5)性能良好,主打易用性。

Træfik 凭借其超轻量级、易于配置、简单易上手的特点,满足了中小公司初期对于网关层的需求。
相比接下来介绍的几款网关产品中,Træfik与Kong网关在功能上最为接近(虽然底层架构完全不一样)。
对Træfik网关感兴趣的读者可以查阅公司官网(https://docs.traefik.io/)学习。

Ambassador

Ambassador 是一款基于 Envoy Proxy 构建的、Kubernetes 原生的开源微服务网关。Am-bassador 在构建之初就致力于支持多个独立团队。
传统的网关产品一般是基于 Restful API 或者 yaml 文件进行配置,而 Ambassador 完全基于 Kubernetes 标准的注解(Annotation)或者 CRD 进行配置,可以认为是 Kubernetes 原生的网关产品。

Ambassador 依靠 Kubernetes 实现可扩展、高可用性和持久性,所有配置都直接存储在 Kubernetes 的 Etcd 中。
Ambassador 被打包成一个单独的容器,其中包含控制平面(Control Plane)和Ambassador代理实例。
默认情况下,Ambassador 会被部署为 Kubernetes Deplo-yment,并可以像其他 Kubernetes Deployment 资源一样进行扩展和管理。

Ambassador 作为一款较新推出的开源微服务网关产品,与 Kubernetes 结合得相当好。
它基于注解或 CRD 的配置方式与 Kubernetes 浑然一体,就像 Kubernetes 自身功能的一部分,真正做到了 Kubernetes 原生。其底层基于 Envoy 进行流量代理,使得用户无须担心性能问题。

Ambassador 和同类的网关产品类似,分为社区版及商业版,其中社区版提供了网关层所必需的基础功能,开发语言为 Go。
想要深入了解 Ambassador 网关的读者可以参考 https://www.getambassador.io/

Tyk

Tyk是一款采用Go语言实现的API网关产品,拥有 API Gateway、Tyk Dashboard、Tyk Pumpd和Tyk Identity Broker 等组件。
不过,只有 API Gateway 组件的源代码是开放的。Tyk的插件功能比较强大,一方面提供了IP黑白名单、参数提取和认证等诸多插件,另一方面支持使用 JavaScript、Python、Lua 语言来自定义插件。

总地来说,Tyk 丰富的插件、强大的认证机制给人眼前一亮的感觉。
不过,其开源版本的集群管理、日志监控和灰度发布等功能相对较弱,有兴趣的读者可以访问官网(https://tyk.io/)了解相关内容。

Zuul

Zuul 是 Netf lix 开源的一个 API 网关,本质上是一个 Web Servlet 应用。
Zuul 可以动态加载过滤器,从而实现网关层的各项功能。Zuul 网关从 1.0 版本升级到 2.0 版本发生了很大的变化。
我们先从图 1-5 和图 1-6 看看二者的差别。

图1_5Zuul1_0架构
图 1-5 Zuul 1.0 架构

图1_6Zull2_0架构
图 1-6 Zuul 2.0 架构

这里我们对 Zuul 1.0 和 Zuul 2.0 做一个简单对比,如表 1-1 所示。

表1-1:

Zull 1.0 Zuul 2.0
优点 编程模型简单、开发调试运维简单 线程开销少、连接数易扩展
缺点 线程上下文切换开销大、连接数受限、延迟阻塞消耗资源 编程模型复杂、ThreadLocal 不工作

相对而言,Zuul 1.0 适用于CPU密集型(CPU-bound)场景,而 Zuul 2.0 适用于 I/O 密集型(I/O-bound)场景。
由于 Zuul 网关或者之后推出的 Spring Cloud Gateway 网关组件都是基于 Spring Cloud 全家桶提供的配套组件实现的,因此受到了人们的普遍认可。
但这两个网关组件也有一些限制,一是它们的底层技术栈要基于 Java 技术栈,或者基于 Spring Cloud 框架;
二是它们并非云原生服务,相对而言,偏向于企业级内部部署。
如果排除这两点,二者在其他各方面的表现都是比较出色的。

注意:
I/O 密集型任务 vs CPU 集型任务

  • I/O 密集型任务指的是磁盘 I/O 或者网络 I/O 占主要消耗的任务,计算量很小,比如请求网页、读写文件等。大多数 Web 应用都是 I/O 密集型任务。
  • CPU 密集型任务指的是 CPU 计算占主要消耗的任务,比如图形渲染中矩阵的运算、神经网络卷积运算等。现在大多数计算任务由 GPU 完成,更复杂的任务由 TPU、NPU 完成。

各网关横向对比

我们从基本情况、配置、部署、可扩展性和功能等维度对上述各网关进行横向对比,如表 1-2 至表 1-6 所示。

表 1-2 基本情况

Kong Traefik Ambassador Tyr Zuul
主要用途 微服务网关/企业级 API 管理 微服务网关 微服务网关 微服务网关 微服务网关
学习曲线 适中 简单 简单 适中 简单
使用成本 开源/企业版 开源 开源/企业版 开源/企业版 开源
社区活跃度(GitHub Star) 26K+ 28k+ 28k+ 5.6k+ 9.5k+

表 1-3 配置

Kong Traefik Ambassador Tyr Zuul
配置方式 Restful API/配置文件 Restful API/toml 文件 yaml 文件 Restful API yaml 文件
配置端点类型 命令式 声明式 声明式 命令式 命令式

表 1-4 部署

Kong Traefik Ambassador Tyr Zuul
Kubernetes 适中 简单 简单 适中 适中
Cloud IaaS 困难 简单 N/A 简单 简单
Private Data Center 困难 简单 N/A 简单 简单
元数据存储 PostgreSQL/Cassandra Kubernetes Kubernetes Redis 内存
Kong Traefik Ambassador Tyr Zuul
服务发现 动态 动态 动态 动态 动态
支持协议 HTTP/HTTPS/WebSocket HTTP/HTTPS/gRPC/WebSocket HTTP/HTTPS/gRPC/WebSocket HTTP/HTTPS/gRPC/WebSocket HTTP/HTTPS
路由匹配条件 host/path/method host/path host/path/header host/path 需自定义开发
限流 支持 不支持 支持 不支持 支持
熔断 支持 支持 不支持 支持 支持
重试 支持 支持 不支持 支持 支持
健康检查 支持 不支持 不支持 支持 支持
负载均衡 轮询/加权轮询/哈希 轮询/加权轮询 加权轮询 轮询 轮询/加权轮询/哈希
Istio 集成 不支持 不支持 支持 不支持 不支持
管理界面 官方支持 官方支持 Grafana + Prometheus 官方支持 官方支持

可以发现,Kong 网关在多项对比中较其他网关均占有一定优势。
但我们也不应该忽略 Kong 网关的薄弱项,即在部署方面相对复杂,这与 Kong 网关本身偏向提供企业级服务有一定关系。
不可否认的是,Kong 网关社区版的功能依旧足够强大,并且给开发者留有大量定制化的空间。

注意:

我们在做技术选型时,除了需要考虑上述几点之外,还要考虑以下细节。

  • 开源组件是否易于扩展自己的业务逻辑,是否易于定制化。
  • 社区是否成熟,文档是否齐全,漏洞修复得是否及时。
  • 软件是否容易使用,日后升级和维护是否便捷。
  • 如果对性能指标或者业务场景有特殊要求,需要着重关注该软件是否支持,以免发生本末倒置的现象。

Kong 网关基础组件

下面我们看一下Kong网关的基础架构。它主要由三大组件组成。

1)Kong 服务器:基于 OpenResty 构建,用来接收 API 请求,并对请求进行转发处理,返回结果。
2)数据库:包含 PostgreSQL、Cassandra,用来存储操作数据。
3)Kong 管理 GUI:Kong 服务界面管理工具。

Kong 服务器

Kong 服务器架构如图 1-7 所示。

图1_7Kong服务器架构
图 1-7 Kong 服务器架构

1)Kong 服务器基于 OpenResty 构建,使用 Lua 脚本处理请求、响应。
2)Kong 插件拦截请求、响应,类似于 Java Servlet 中的拦截器,实现请求、响应的 AOP 处理。
3)RESTful API 提供了对路由、服务、插件等一系列元数据的统一管理。
4)数据中心用于存储 Kong 集群节点信息,以及路由、服务、插件等一系列元数据。目前,其支持 PostgreSQL 和 Cassandra 数据库。
5)Kong 集群中的节点通过 Gossip 协议自动发现其他节点。当某一节点通过 Admin API 对配置进行变更时,同时会通知其他节点。每个 Kong 节点的配置信息是有缓存的。

注意:

Gossip 协议通过一种随机、带有传染性的方式,将信息传播到整个网络,并在一定时间内使得系统内所有节点的数据一致,是常用的解决分布式环境中数据最终一致性问题的通信协议。
使用 Gossip 协议的还有 Redis Cluster、Consul、Apache Cassandra 等。

Kong 服务器的架构设计带来以下好处。

1)高扩展性:用户可以通过简单地向 Kong 集群中添加更多服务器实现横向扩展,这意味着用户在面对超大流量时可以轻松应对,整个集群可以保持正常负载,保证整个网关层服务可靠稳定。
2)模块化:Kong 服务器的路由、服务、插件均是基于模块构建的,这些元素可以通过 Admin API 轻松配置,或者通过 Kong 管理 GUI 进行可视化管理。
3)与运行环境无关:Kong 服务器理论上可以在任何环境中运行,也就是说,用户可以在云服务器或者内部网络环境中部署 Kong 服务器。

数据库

Kong 网关支持 PostgreSQL 和 Cassandra 数据库。下面我们对它们做一些简单介绍。

PostgreSQL:

PostgreSQL 是一个功能强大的开源关系型数据库系统。它使用和扩展了SQL语言,并结合了许多安全存储和扩展复杂数据工作负载的功能。

PostgreSQL 凭借其可靠性、数据完整性、强大的功能集、可扩展性以及开源社区赢得了良好的声誉,始终如一地提供高性能和创新的解决方案。

Kong 选择 PostgreSQL 作为默认数据库存储。对于普通用户来说,其仅需了解如何使用即可。 PostgreSQL 的使用并不复杂,此处不做展开。可以访问 PostgreSQL 官网(https://www.postgresql.org/)了解更多 PostgreSQL 的相关知识。

Cassandra:

Cassandra 是一套开源分布式 NoSQL 数据库系统。它最初由 Facebook 开发,于 2008 年开源,用于储存收件箱数据等,集 Google Big Table 的数据模型与 Amazon Dynamo 的完全分布式架构于一身。
此后,由于 Cassandra 良好的可扩展性,被 Digg、Twitter 等知名 Web 2.0 网站所采纳,成为一种流行的分布式结构化数据存储方案。

Cassandra 的主要特点是,它不是一个单纯的数据库,而是由一堆数据库节点共同构成的一个分布式网络服务。
Cassandra上 的一个写操作会被复制到其他节点,读操作也会被路由到其他节点。对于 Cassandra 集群来说,其扩展性是容易实现的,只需在集群中添加节点。

更多 Cassandra 的相关特性,可以访问 Cassandra 官网(https://cassandra.apache.org/)了解详情。

Kong 管理 GUI

当前主流的开源 Kong 管理 GUI 有 KongDashboard 和 KONGA,其中 KongDashboard 对新版本的 Kong 支持不好,建议使用 KONGA。
图 1-8 是 KONGA 的界面。

图1_8KONGA欢迎界面
图 1-8 KONGA 欢迎界面

Kong 网关安装指南

https://konghq.com/install/#kong-community

在 Mac 环境中安装 Kong 网关

1
2
brew tap kong/kong
brew install kong
1
2
kong version
2.6.0

安装完成后,我们还需要准备两个配置文件,一个是启动项配置文件。
用户可以从 https://raw.githubusercontent.com/Kong/kong/master/kong.conf.default 或者 https://github.com/Kong/kong/blob/master/kong.conf.default 下载配置模块,并更改配置文件名为 kong.conf
修改 kong.conf 配置文件内容如代码清单 1-1 所示。

代码清单 1-1 kong.conf 配置文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
#database = postgres             # Determines which of PostgreSQL or Cassandra
                                 # this node will use as its datastore.
                                 # Accepted values are `postgres`,
                                 # `cassandra`, and `off`.
...
#declarative_config =           # The path to the declarative configuration
                                # file which holds the specification of all
                                # entities (Routes, Services, Consumers, etc.)
                                # to be used when the `database` is set to
                                # `off`.
                                #
                                # Entities are stored in Kong's in-memory cache,
                                # so you must ensure that enough memory is
                                # allocated to it via the `mem_cache_size`
                                # property. You must also ensure that items
                                # in the cache never expire, which means that
                                # `db_cache_ttl` should preserve its default
                                # value of 0.
                                #
                                # If the Hybrid mode `role` is set to `data_plane`
                                # and there's no configuration cache file,
                                # this configuration is used before connecting
                                # to the Control Plane node as a user-controlled
                                # fallback.
...                                

另一个是 kong.yml 文件,需要使用 kong config init 命令生成。该配置文件内容可以为空,但文件本身不可缺失。当一切准备就绪后,使用 kong start -c kong.conf 命令启动 Kong 服务,在浏览器中输入 http://127.0.0.1:8001 可以查看服务是否启动成功,效果如图 1-9 所示。

Kong服务启动页面
图 1-9 Kong服务启动页面

在 Linux 环境中安装 Kong 网关

对于Linux环境,我们选用rpm包安装,命令如下:

1
2
$ wget https://bintray.com/kong/kong-rpm/download_file?file_path=centos/7/kong-2.0.5.el7.amd64.rpm
$ rpm -ivh kong-2.0.5.el7.amd64.rpm

安装完成后,我们可以效仿在Mac环境中的启动流程继续操作,验证步骤也类似。

在 Docker 环境中安装 Kong 网关

Docker 可以跨系统运行,非常适合企业在前期资源不足的情况下搭建环境。
可根据代码清单 1-2 安装 Kong 网关。

程序清单 1-2 安装 Kong 网关

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$ docker network create kong-net
$ docker run -d --name kong-database \
  --network=kong-net \
  -p 5432:5432 \
  -e "POSTGRES_USER=kong" \
  -e "POSTGRES_DB=kong" \
  -e "POSTGRES_PASSWORD=kong" \
  postgres:9.6
$ docker run --rm \
  --network=kong-net \
  -e "KONG_DATABASE=postgres" \
  -e "KONG_PG_HOST=kong-database" \
  -e "KONG_PG_USER=kong" \
  -e "KONG_PG_PASSWORD=kong" \
  -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
  kong:2.0.5 kong migrations bootstrap
$ docker run -d --name kong \
  --network=kong-net \
  -e "KONG_DATABASE=postgres" \
  -e "KONG_PG_HOST=kong-database" \
  -e "KONG_PG_USER=kong" \
  -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:2.0.5

安装完成后,我们使用相同方法进行验证。