Kong 是 Mashape 开源的一款云原生架构下的分布式 API 网关,其性能和可扩展性在同类组件中,表现都很优异。Kong 官方提供了不少直接可用的插件,此外,Kong 还能够经过插件扩展已有功能。nginx
本文的主要内容:git
文章篇幅较长,后半部份内容将会在下一篇文章介绍,敬请关注。sql
本文的标题是:云原生架构下的 API 网关实践。首先谈谈关于云原生的具体定义,仁者见仁智者见智。docker
Pivotal 是云原生应用的提出者,并推出了 Pivotal Cloud Foundry 云原生应用平台和 Spring 开源 Java 开发框架,成为云原生应用架构中先驱者和探路者。Pivotal 公司的 Matt Stine 关于云原生应用架构的定义,提出来几个主要特征:数据库
随着技术的发展,云原生的概念也在不断的完善。云原生的定义将来还会变,本文参考 CNCF V1.0 的定义:编程
云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的表明技术包括容器、服务网格、微服务、不可变基础设施和声明式 API。json
所以,云原生网关很重要的特性之一,就是可以快速集成到持续发布的云原生环境中。bootstrap
当使用单体应用程序架构时,客户端(Web 或移动端)经过向后端应用程序发起一次 REST 调用来获取数据。负载均衡器将请求路由给 N 个相同的应用程序实例中的一个。而后应用程序会查询各类数据库表,并将响应返回给客户端。微服务架构下,单体应用被切割成多个微服务,若是将全部的微服务直接对外暴露,势必会出现安全方面的各类问题。后端
客户端能够直接向每一个微服务发送请求,其问题主要以下:api
服务端的各个服务直接暴露给客户端调用势必会引发各类问题。同时,服务端的各个服务可扩展和伸缩性不好。API 网关是微服务架构中的基础组件,位于接入层之下和业务服务层之上,如前所述的这些功能适合在 API 网关实现。
关于服务网关的开源组件,有 Netflix Zuul、Spring Cloud Gateway、Kong、Traefik、NGINX 和服务网关类型的 Envoy 等。在以前的文章已经介绍过可编程的新型网关:Spring Cloud Gateway,须要了解的读者能够查看 Spring Cloud Gateway。 本文主要介绍现代微服务网关 Kong,在 Kong 的官网介绍中,第一条特性即是 Kong 的云原生属性:与平台无关,Kong 能够从裸机运行到 Kubernetes。本文基于 Kong 1.2.1,自定义插件部分会涉及部分 Lua 编码,适合服务端开发和运维人员。
Mashape 开源的高性能高可用 API 网关和 API 服务管理层——KONG(基于NGINX)特色尤其突出,它能够经过插件扩展已有功能,这些插件(使用 lua 编写)在 API 请求响应循环的生命周期中被执行。与此同时,KONG 自己提供包括HTTP基本认证、密钥认证、CORS、TCP、UDP、文件日志、API请求限流、请求转发及NGINX监控等基本功能。目前,Kong 在 Mashape 管理了超过 15,000 个 API,为200,000开发者提供了每个月数十亿的请求支持。
什么是 Kong
当咱们决定对应用进行微服务改造时,应用客户端如何与微服务交互的问题也随之而来,毕竟服务数量的增长会直接致使部署受权、负载均衡、通讯管理、分析和改变的难度增长。
面对以上问题,API GATEWAY是一个不错的解决方案,其所提供的访问限制、安全、流量控制、分析监控、日志、请求转发、合成和协议转换功能,能够解放开发者去把精力集中在具体逻辑的代码,而不是把时间花费在考虑如何解决应用和其余微服务连接的问题上。
为何使用Kong
在众多 API GATEWAY 框架中,Mashape 开源的高性能高可用API网关和API服务管理层——KONG(基于 NGINX)特色尤其突出,它能够经过插件扩展已有功能,这些插件(使用 lua 编写)在API请求响应循环的生命周期中被执行。于此同时,KONG自己提供包括 HTTP 基本认证、密钥认证、CORS、TCP、UDP、文件日志、API请求限流、请求转发及 NGINX 监控等基本功能。目前,Kong 在 Mashape 管理了超过 15,000 个 API,为 200,000 开发者提供了每个月数十亿的请求支持。
Kong 是 Mashape 开源的高性能高可用 API 网关和 API 服务管理层,一款基于 Nginx_Lua 模块写的高可用服务网关,因为 Kong 是基于 Nginx 的,因此能够水平扩展多个 Kong 服务器。经过前置的负载均衡配置把请求均匀地分发到各个 Server,来应对大批量的网络请求。
Kong 主要有三个组件:
Kong 采用插件机制进行功能定制,插件集(能够是 0 或 N 个)在 API 请求响应循环的生命周期中被执行。插件使用 Lua 编写,基础功能包括:HTTP 基本认证、密钥认证、CORS(Cross-Origin Resource Sharing,跨域资源共享)、TCP、UDP、文件日志、API 请求限流、请求转发以及 Nginx 监控等。
Kong 网关具备如下的特性:
Kong 中经常使用的术语介绍,这些术语会在下面的实践中常常用到。
客户端的请求将会首先经由微服务网关处理,一些通用的功能切面将会在网关生效,即 Kong 中的插件,以后才会将请求进行转发到对应的 Backend 服务,以下图所示。
目前 Kong 的最新版本 1.2,Kong 的安装支持多种方式。官方支持以下列出方式的安装:
除了官方提供的安装方式,还有社区提供的安装方式,详细了解参见:konghq.com/install/。
笔者为了方便,基于 docker 的方式安装。docker-compose.yml 中定义的镜像、依赖和参数以下所示:
version: "3.7"
services:
kong:
image: kong:1.1.2
environment:
- "KONG_DATABASE=postgres"
- "KONG_PG_HOST=kong-database"
- "KONG_CASSANDRA_CONTACT_POINTS=kong-database"
- "KONG_PROXY_ACCESS_LOG=/dev/stdout"
- "KONG_ADMIN_ACCESS_LOG=/dev/stdout"
- "KONG_PROXY_ERROR_LOG=/dev/stderr"
- "KONG_ADMIN_ERROR_LOG=/dev/stderr"
- "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl"
ports:
- 8000:8000
- 8443:8443
- 8001:8001
- 8444:8444
networks:
- kong-net
depends_on:
- kong-database
konga:
image: pantsel/konga
environment:
- "TOKEN_SECRET=blueskykong.com"
- "NODE_ENV=production"
ports:
- 8080:1337
networks:
- kong-net
depends_on:
- kong-database
kong-database:
image: postgres:9.6
ports:
- "5432:5432"
environment:
- POSTGRES_USER=kong
- POSTGRES_DB=kong
networks:
- kong-net
volumes:
- /etc/localtime:/etc/localtime:ro
- /data/data/postgresql:/var/lib/postgresql/data
networks:
kong-net:
external: true
复制代码
如上的 docker-compose.yml 会启动三个容器服务:Kong、konga 和 kong-database。这三个容器之间的通讯须要增长 network 段,把容器放在同一个网段内,相关连接修改成容器名称来访问:
docker network create kong-net
复制代码
所启动的三个容器服务,除了 Kong 以外的两个服务:konga 是 Kong 的 Dashboard,基于 js 的客户端管理工具,对外暴露的端口为 8080;kong-database 是 Kong 的数据库服务,存储配置信息,这里使用的是 postgres。须要注意的是,在启动 Kong 容器以前,须要保持数据库的 Docker 容器在运行状态,并执行以下初始化数据库的操做:
docker run --rm \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
kong:latest kong migrations bootstrap
复制代码
数据库初始化成功后,再次启动 docker-compose.yml 服务就能够了。咱们看到 Kong 映射出多个端口,默认状况下,Kong 监听的端口为:
容器都启动好以后,咱们来验证一下:
curl -i http://localhost:8001/
HTTP/1.1 200 OK
Date: Sat, 20 Jul 2019 08:39:08 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Server: kong/1.1.2
Content-Length: 5785
...
复制代码
如上的结果,表示安装正确,能够正常使用 Kong。访问 http://localhost:8080 访问 Konga 的管理界面,第一次登陆使用须要建立管理员账号和密码。
更多内容参照官网的安装文档。至此,Kong 以及管理工具都已安装完成,下面将进入 API Gateway 的具体实践。
如咱们在术语部分的介绍,服务是上游服务的抽象,能够是一个应用,或者具体某个接口。Kong 提供了管理接口,咱们能够经过请求 8001 管理接口直接建立,也能够经过安装的管理界面,实现的效果是同样的。
curl -i -X POST \
--url http://localhost:8001/services/ \
--data 'name=aoho-blog' \
--data 'url=http://blueskykong.com/'
复制代码
咱们建立一个服务名为 aoho-blog
,指定转发的地址为 http://blueskykong.com
。能够在管理界面中看到以下的记录:
建立好服务以后,咱们须要建立具体的 API 路由。路由是请求的转发规则,根据 Hostname 和 PATH,将请求转发。
curl -i -X POST \
--url http://localhost:8001/services/aoho-blog/routes \
--data 'hosts[]=blueskykong.com' \
--data 'paths[]=/api/blog'
复制代码
如上在 aoho-blog 中建立了一个访问 /api/blog 的路由,在管理界面能够看到相应的记录:
建立好路由以后,咱们就能够访问 /api/blog。
Kong 默认经过 8000 端口处理代理的请求。成功的响应意味着 Kong 将 http://localhost:8000
的请求转发到配置的 URL,并将响应转发给咱们。须要注意的是,若是 API 暴露的地址与前面 Host 定义的地址(blueskykong.com)不一致,就须要在请求的 Headers 里面加入 Header,Kong 根据上面请求中定义的 Header:Host,执行此操做。
本文主要介绍了云原生和云原生网关的相关概念,随后具体介绍了本文的主角 Kong 的特性和基本架构。重点介绍了如何使用 Kong 构建服务网关。Kong 官方和社区提供了不少插件,关于 Kong 中的经常使用插件使用,以及如何定制本身的 Kong 插件,将会在下文讲解。