21案例:如何使用Kong进行网关业务化定制?
文章目录
在上一课时中,我们对比了几款市面上流行的微服务网关,那么本课时我们就基于其中一款,也就是 Kong 来重点介绍微服务网关是如何搭建和实现的。
为什么使用 Kong
当我们对原有业务系统进行微服务改造时,客户端(包括移动端和 Web 端等)如何与各个微服务进行交互这个问题需要我们认真考虑,服务数量的增加会导致一些基础功能的实现变得困难,如认证授权、负载均衡和服务间通信管理。
但微服务网关所提供的访问限制、安全、流量控制、分析监控、日志、请求转发、合成和协议转换功能,可以使得开发者更加集中精力在各个业务服务的实现上,从而避免将大量时间花在考虑如何解决这些问题上。
在业内流行的微服务网关组件中,基于 Nginx 的Kong表现突出。Kong 是 Mashape 开源的高性能、高可用 API 网关,也可以认为是 API 服务管理层。它可以通过插件扩展已有功能,这些插件(使用 Lua 编写)在 API 请求响应循环的生命周期中被执行。除此之外,Kong 本身还提供了包括 HTTP 基本认证、密钥认证、CORS、TCP、UDP、文件日志、API 请求限流、请求转发及 Nginx 监控等基本功能。
在用 Kong 进行实践之前,我们得先介绍一些 Kong 中常用的术语,因为这些术语在实践中会经常用得到。
Route:请求的转发规则,按照 Hostname 和 PATH,将请求转发给 Service。
Services:多个 Upstream 的集合,是 Route 的转发目标。
Consumer:API 的用户,记录用户信息。
Plugin:插件,可以是全局的,也可以绑定到 Service、Router 或者 Consumer。
Certificate:HTTPS 配置的证书。
SNI:域名与 Certificate 的绑定,指定了一个域名对应的 HTTPS 证书。
Upstream:上游对象用来表示虚拟主机名,拥有多个服务(目标)时,会对请求进行负载均衡。
Target:最终处理请求的 Backend 服务。
安装实践
Kong 支持多种安装方式,目前最新版本是 Kong 2.1,官方支持包括 Docker、K8s 等方式的安装:
Kong 的多种安装方式
除了官方提供的安装方式,还有社区提供的安装方式:Microsoft Azure、Kongverge 等,详细情况你可参见该网址:https://konghq.com/install/ 。
为了方便,这里我们就选择基于 Docker 的方式安装,选择的 Kong 版本为 1.1.2。docker-compose.yml 中定义的镜像、依赖和参数如下所示:
|
|
如上的 docker-compose.yml 会启动三个容器服务:Kong、Konga 和 Kong-database。这三个容器之间的通信需要增加 network 段,把容器放在同一个网段内,相关链接修改为容器名称来访问:
|
|
所启动的三个容器服务,除了 Kong 之外的另两个服务:Konga是 Kong 的 Dashboard,它是基于 JavaScript 的客户端管理工具,对外暴露的端口为 8080;Kong-database是 Kong 的数据库服务,它用于存储配置信息,此处使用的是 Postgres。
这里要注意的是,在启动 Kong 容器之前,需要保持数据库的 Docker 容器在运行状态,并执行如下初始化数据库的操作:
|
|
数据库初始化成功后,再次启动 docker-compose.yml 服务就可以了。我们看到 Kong 映射出多个端口,默认情况下,Kong 监听的端口为:
8000。此端口是 Kong 用来监听来自客户端传入的 HTTP 请求,并将此请求转发到上游服务器;Kong 根据配置的路由规则转发到真实的后台服务地址。
8443。此端口是 Kong 用来监听来自客户端传入的 HTTPS 请求,跟 8000 端口的功能类似,还会转发 HTTPS 请求。我们可以通过修改配置文件来禁用 HTTPS 的功能。
8001。Kong 提供的管理 API 端口,通过此端口,管理者可以对 Kong 的监听服务进行配置,插件设置、API 的增删改查以及负载均衡等一系列的配置都是通过 8001 端口进行管理的。
8444。通过此端口,管理者可以对 HTTPS 请求进行监控。
容器都启动好之后,下面我们来验证一下:
|
|
本地访问 8001 端口,返回如上的结果,表示安装正确,可以正常使用 Kong。在浏览器中输入 http://localhost:8080 即可访问 Konga 的管理界面(如下图),如果你第一次登录使用,则需要创建管理员账号和密码。
Konga 的管理界面
至此,Kong 以及管理工具都已安装完成。下面我们将会通过创建服务、创建路由、安装插件等过程的讲解,进入 API Gateway 的具体实践。
1. 创建服务
正如我们在前面术语部分的介绍,服务 Services 是上游服务的抽象,可以是一个应用,或者具体某个接口。Kong 提供了管理接口,我们可以通过请求 8001 管理接口直接创建,也可以通过安装的管理界面,这二者的实现效果是一样的。
|
|
这里我们创建了一个服务名为 aoho-blog 的后端服务,指定转发的地址为 http://blueskykong.com。可以在管理界面中看到如下的记录:
Kong 服务列表
在创建服务的同时,我们还可以设置其中的一些参数,如 Retries(重试次数)、Connect timeout(连接的超时时间)、Write/Read timeout(写/读超时时间)等。
2. 创建路由
创建好服务之后,我们需要创建具体的 API 路由。路由是请求的转发规则,根据 Hostname 和 PATH,将请求转发。
|
|
如上所示,我们在 aoho-blog 中创建了一个访问 /api/blog 的路由,在管理界面可以看到相应的记录:
Kong 路由记录
创建好路由之后,我们就可以访问 /api/blog,如下图:
访问 /api/blog
Kong 默认通过 8000 端口处理代理的请求。成功的响应意味着 Kong 会将 http://localhost:8000 的请求转发到配置的 URL,并将响应转发给我们。需要注意的是,如果 API 暴露的地址与前面 Host 定义的地址(blueskykong.com)不一致,就需要在请求的 Headers 里面加入 Header,Kong 根据上面请求中定义的 Header:Host ,执行此操作。
创建了服务和路由之后,我们已经能够将客户端的请求转发到对应的服务,但微服务网关还承担了很多基础的功能,如安全认证、限流、分析监控等功能,因此还需要应用 Kong 的插件来实现这些功能。
安装 Kong 插件
请求到达 Kong 网关,我们可以在请求转发给服务端应用之前,应用 Kong 自带的插件对请求进行处理,如身份认证、API 限流、黑白名单校验和日志切面等。同时,我们也可以按照 Kong 的教程文档,定制属于自己的插件。这部分我们主要选择其中的三个插件示例应用,至于其余的插件应用,你可以参考这个网址:https://docs.konghq.com/hub/。
1. JWT 认证插件
JWT(JSON Web Token)是一种流行的跨域身份验证解决方案。作为一个开放的标准(RFC 7519),JWT 定义了一种简洁的、自包含的方法用于通信双方之间以 JSON 对象的形式安全地传递信息。因为数字签名的存在,这些信息是可信的。
JWT 最大的优点就是能让业务无状态化,让 Token 作为业务请求的必须信息随着请求一并传输过来,服务端不用再去存储 session 信息,尤其是在分布式系统中。Kong 提供了 JWT 认证插件,用以验证包含 HS256 或 RS256 签名的 JWT 请求。每个消费者都将拥有 JWT 凭证(公钥和密钥),这些凭证必须用于签署其 JWT。JWT 令牌可以通过请求字符串、Cookie 或者认证头部传递,Kong 将会验证令牌的签名,通过则转发,否则直接丢弃请求。
我们在前面配置的路由基础上,增加 JWT 认证插件:
|
|
可以看到,在插件列表增加了相应的记录:
Kong 插件列表
在增加了 JWT 插件之后,就没法直接访问 /api/blog 接口了,接口返回 “message”: “Unauthorized”,提示客户端要访问的话则需要提供 JWT 的认证信息。因此,我们需要创建用户:
|
|
如上我们就创建了一个名为 aoho 的用户。
Kong 创建用户
创建好用户之后,需要获取用户 JWT 凭证,执行如下的调用:
|
|
使用 key 和 secret 在 https://jwt.io 可以生成 JWT 凭证信息。在实际的使用过程中,我们通过编码实现,此处为了演示使用网页工具生成 Token。
生成 JWT Token
上图中画线部分即为 JWT 凭证的 key 和 secret。然后我们将生成的 Token,配置到请求的认证头部,再次执行请求:
带有 JWT 令牌的合法请求
可以看到,我们能够正常请求相应的 API 接口,JWT 认证插件应用成功。Kong 的 JWT 认证插件使用比较简单,但在实践过程中,我们还需要考虑如何跟自身的用户认证系统进行结合。
2. Prometheus 可视化监控
Prometheus 是一套开源的系统监控报警框架。它启发于 Google 的 BorgMon 监控系统,由工作在 SoundCloud 的员工在 2012 年作为社区开源项目进行开发,并于 2015 年正式发布。
作为新一代的监控框架,Prometheus 适用于记录时间序列数据,并且它还具有强大的多维度数据模型、灵活而强大的查询语句、易于管理和伸缩等特点。
Kong 官方提供的 Prometheus 插件,可用的 metric(指标)有如下:
状态码。上游服务返回的 HTTP 状态码。
时延柱状图。Kong 中的时延都将被记录,包括请求(完整请求的时延)、Kong(Kong 用来路由、验证和运行其他插件所花费的时间)和上游(上游服务所花费时间来响应请求)。
Bandwidth。流经 Kong 的总带宽(出口/入口)。
DB 可达性。Kong 节点是否能访问其 DB。
Connections。各种 Nginx 连接指标,如 Active、读取、写入和接收连接。
我们在 Service 为 aoho-blog 安装 Prometheus 插件:
|
|
从管理界面可以看到,我们已经成功将 Prometheus 插件绑定到 aoho-blog 服务上。
Prometheus 插件
通过访问 /metrics 接口返回收集度量数据:
|
|
返回的响应太长,有省略,从响应可以看到 Prometheus 插件提供的 metric 都有体现。Prometheus 插件导出的度量标准,可以在 Grafana(一个跨平台的开源的度量分析和可视化工具)中绘制,“Prometheus + Grafana” 的组合是目前较为流行的监控系统。
3. 链路追踪 Zipkin 插件
Zipkin 是由 Twitter 开源的分布式实时链路追踪组件。 Zipkin 收集来自各个异构系统的实时监控数据,用来追踪与分析微服务架构下的请求,应用系统则需要向 Zipkin 报告链路信息。Kong 的 Zipkin 插件将 Kong 作为 zipkin-client,zipkin-client 组装好 Zipkin 需要的数据包发送到 zipkin-server。Zipkin 插件会将请求打上如下标签,并推送到 Zipkin 服务端:
span.kind (sent to Zipkin as “kind”)
http.method
http.status_code
http.url
peer.ipv4
peer.ipv6
peer.port
peer.hostname
peer.service
关于链路追踪和 Zipkin 的具体信息,到后面的链路追踪课时我们会详细讲解,本课时我们就旨在介绍如何在 Kong 中使用 Zipkin 插件追踪所有请求的链路。
首先开启 Zipkin 插件,将插件绑定到路由上(这里可以绑定为全局的插件)。
|
|
如上配置了 Zipkin Collector 的地址和采样率,为了测试效果明显,设置采样率为 100%,但在实际生产环境中还是要谨慎使用 100% 的采样率配置,采样率对系统吞吐量会有影响。
Zipkin 插件
可以看到,Zipkin 插件已经应用到指定的路由上。下面我们将会执行请求 /api/blog 接口,打开 http://localhost:9411 界面如下:
Zipkin 链路追踪
这时 Zipkin 已经将请求记录,我们可以点开查看其链路详情:
链路详情
从链路调用可以知道,请求到达 Kong 之后,都经历了哪些服务和 Span,以及每个 Span 所花费的时间等信息。
小结
本课时我们重点介绍了微服务网关 Kong 的相关概念和安装实践,并在此基础上安装实践了其中具有代表性的三个 Kong 插件:JWT 认证插件、Prometheus 可视化监控和链路追踪 Zipkin 插件。Kong 官方对自身的定位也是适用于混合云平台的下一代 API 管理平台,其在功能方面很强大。因此,基于 Kong 的丰富生态和配套的工具,我们可以快速构建一个微服务网关,作为服务端的统一入口。
学习完本课时,你觉得还需要自定义哪些 Kong 网关的插件,欢迎你在留言区和我分享。
-– ### 精选评论 ##### 13213: > yml文件中需要指定-e “KONG_PG_PASSWORD=kong_test” ###### 讲师回复: > 这个与你的pg设置有关了,笔者这个版本不需要加。 ##### **1609: > 老师,Traefik和Kong有什么区别呢?
文章作者 anonymous
上次更新 2024-06-10