前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kong网关:入门、实战与进阶-重读

Kong网关:入门、实战与进阶-重读

作者头像
yeedomliu
发布2023-12-21 16:30:58
8590
发布2023-12-21 16:30:58
举报
文章被收录于专栏:yeedomliuyeedomliu

思维导图

前言

https://github.com/fossilman/Kong-In-Action

全面了解

1.1 网关简介

问题领域

描述

影响

系统架构

网关层作为流量中枢,对系统稳定性至关重要

网关层不稳定或宕机可导致整个系统不可用

微服务架构实践

微服务架构要求网关层支持技术栈变迁和服务聚合

缺乏网关层支持会限制微服务架构的实施和效能

安全性与运维

网关层需处理加解密、鉴权、黑白名单等安全需求

更新网关层代码时,不影响生产环境流量是一大挑战

微服务独立功能

微服务架构导致需在多个小应用中实现通用功能

缺乏统一的底层架构导致重复劳动和高研发成本

1.2 Kong网关简介

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

图1-3 Kong、OpenResty与Nginx的关系

1.3 Kong网关基础组件

图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节点的配置信息是有缓存的。

1.4 Kong网关安装指南

在Mac环境中安装Kong网关

安装Homebrew,如果已经安装请忽略

代码语言:javascript
复制
$ ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"  $ brew tap kong/kong$ brew install kong

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

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

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

图1-9 Kong服务启动页面

在Docker环境中安装Kong网关

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

代码语言:javascript
复制
$ 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

1.5 使用Kong网关搭建Web应用

程序清单1-6 docker-compose.yml启动文件

代码语言:javascript
复制
29     ...30     ...31   kong:32     build:33       context: ./kong-gateway34     container_name: kong35     environment:36       KONG_DATABASE: 'off'37       KONG_DECLARATIVE_CONFIG: /usr/local/kong/declarative/config.yml38       KONG_PROXY_ACCESS_LOG: /dev/stdout39       KONG_ADMIN_ACCESS_LOG: /dev/stdout40       KONG_PROXY_ERROR_LOG: /dev/stderr41       KONG_ADMIN_ERROR_LOG: /dev/stderr42       KONG_ADMIN_LISTEN: 0.0.0.0:8001, 0.0.0.0:8444 ssl43     ports:44       - '8000:8000'45       - '8443:8443'46       - '8001:8001'47       - '8444:8444'48     volumes:49       - ./kong-gateway:/usr/local/kong/declarative50     depends_on:51       - backend

Dockerfile配置文件如下。

代码语言:javascript
复制
1 # kong dockerfile2 FROM kong:2.0.5

2.4 本章小结

在云原生热度持续火热的当下,Nginx赖以生存的高并发、高性能壁垒已开始出现松动。灵活性、易用性、系统伸缩性以及可高度定制化,这些特性变得越来越重要。Kong网关正是在这种市场需求下应运而生的。

Lua

3.1 Lua入门与规范

  1. Lua就非常明确自己的定位:它不想自己做大,而是想做得足够精简、小巧,嵌入宿主语言,以提供一些动态特性。除Lua之外,常用的胶水语言还有Shell脚本、TCL语言等。
  2. LuaJIT解释器的执行效率为Lua解释器执行效率的10倍以上。LuaJIT还有很多其他性能优化技巧。

3.2 数据类型

程序设计语言中的一等、二等、三等公民。

  1. 一等公民:可以作为参数传递,也可以从子程序中返回,还可以赋值给变量。
  2. 二等公民:可以作为参数传递,但是不能从子程序中返回,也不能赋值给变量。
  3. 三等公民:值作为参数传递都不行。

函数为“一等公民”是函数式编程的基础。

公民类别

作为参数传递

从子程序中返回

赋值给变量

一等公民

可以

可以

可以

二等公民

可以

不能

不能

三等公民

不能

不能

不能

OpenResty

4.2 OpenResty详解

md2pod.pl:主要用于将GitHub风格的Markdown格式文档转换为Perl的POD格式文档。代码清单4-1展示了它的基本用法。

4.4 OpenResty性能优化

常见的火焰图类型有on-CPU、of f-CPU、Memory、Hot/Cold和Differential等。关于火焰图详细的介绍,读者可以参考Blazing Performance with Flame Graphs。on-CPU火焰图或者off-CPU火焰图的使用场景取决于当前的瓶颈。如果瓶颈是CPU,则使用on-CPU火焰图;如果瓶颈是I/O或锁,则使用off-CPU火焰图。如果瓶颈无法确定,可以通过压测工具来确认。通过压测工具观察能否让CPU使用率趋于饱和,如果能,则使用on-CPU火焰图;如果不能,则使用of f-CPU火焰图。

火焰图的生成主要依赖于SystemTap工具

火焰图类型

使用场景

瓶颈指示

额外信息

on-CPU

当瓶颈是CPU时

CPU利用率高

适用于CPU饱和场景,依赖于SystemTap工具

off-CPU

当瓶颈是I/O或锁时

I/O或锁等待时间长

适用于CPU未饱和但性能受限场景,依赖于SystemTap工具

部署

5.4 Kong网关部署

Kong网关可分为三种部署方式:无数据库部署模式、数据库部署模式和混合部署模式。

无数据库部署模式中,Kong网关使用特定的配置文件进行部署。配置文件的格式为yaml,通常以yml后缀结尾。用户可以在启动项配置中使用declarative_config指定该文件路径。需要注意的是,使用该配置文件的前提条件是database配置项设置为of f。

1)首先创建一个Docker网络,名称为kong-net,网络模式为bridge模式。

2)预先准备声明性配置文件kong.yml,此处我们使用的是官方提供的模板文件。

程序清单5-7 kong.yml文件

表5-9 元数据配置文件配置项

程序清单5-9 2.3.4节中的kong.yml配置文件

从使用场景来说,PostgreSQL偏向于单点模式,Cassandra可在集群模式下使用。

混合部署模式是在Kong 2.0版本中新引入的一种部署方式,也可以称为控制平面/数据平面分离部署。控制平面(Control Plane,CP)功能类似于Admin API,用于管理配置。数据平面(Data Plane,DP)用于为代理提供流量。每个DP节点都会连接到CP节点。DP节点摒弃了传统的通信方式,不直接与数据库连接,而是与CP进行交互,并接收最新的配置项

图5-3 混合部署模式架构

代理和鉴权

7.2 Kong网关代理示例

使用Admin API为Kong网关添加代理配置,步骤如下。 1)创建一个名为demo的上游服务:

代码语言:javascript
复制
$ curl -X POST http://127.0.0.1:8001/upstreams \  --data "name=demo"

2)为上游服务绑定一个target,代理到www.baidu.com地址:

代码语言:javascript
复制
$ curl -X POST http://127.0.0.1:8001/upstreams/demo/targets \  --data "target=www.baidu.com:80" \  --data "weight=100"

3)创建一个名为service_demo的服务,host属性与之前创建的上游服务对应:

代码语言:javascript
复制
$ curl -X POST http://127.0.0.1:8001/services \  --data "name=service_demo" \  --data "host=demo"

4)创建一个名为route_demo的路由,匹配路径为/baidu:

代码语言:javascript
复制
$ curl -X POST http://127.0.0.1:8001/services/service_demo/routes \  --data "paths[]=/baidu"  \  --data "name=route_demo"

5)验证代理是否生效:

代码语言:javascript
复制
$ curl 127.0.0.1:8000/baidu

...百度一下,你就知道...

步骤

操作

描述

1

创建上游服务

使用curl命令创建名为demo的上游服务

2

绑定Target

将www.baidu.com作为目标绑定到demo服务上

3

创建服务

创建一个名为service_demo的服务,其host属性对应于之前创建的上游服务

4

创建路由

创建名为route_demo的路由,匹配路径为/baidu

5

验证代理

使用curl命令验证代理配置是否已生效

7.3 路由匹配规则

Kong网关可以划分为三种代理模式。这三种代理模式是互斥的,各模式之间支持的可配置属性也存在差异

表7-1 三种代理模式信息

Kong网关还支持使用正则表达式进行模糊匹配。这个功能在实际场景中非常实用。

Paths属性匹配优先级

1)普通前缀路径遵守最长前缀路径匹配规则,即/version/any/优先级高于/version。 2)正则表达式根据路由的regex_priority属性从最高优先级到最低优先级进行评估。同优先级的正则表达式也遵守最长前缀路径匹配规则。 3)正则表达式的匹配优先级始终高于前缀路径表达式。

匹配类型

优先级规则

描述

普通前缀路径

最长前缀路径优先

如/version/any/的优先级高于/version

正则表达式

根据regex_priority属性评估

同优先级的正则表达式遵守最长前缀路径匹配规则

正则表达式 vs. 前缀路径

正则表达式优先级高于前缀路径

正则表达式匹配优先于前缀路径表达式

sources & destinations属性仅适用于TCP和TLS路由。它们允许通过传入的IP地址和端口号列表来匹配路由。两个属性的不同点在于一个是匹配源地址,一个是匹配目标地址。我们来看一个示例:

代码语言:javascript
复制
{  "protocols": ["tcp", "tls"],  "sources": [{"ip":"10.1.0.0/16", "port":1234}, {"ip":"10.2.2.2"},     {"port":9123}],  "id": "...",}

路由会匹配源地址是10.1.0.0/16(CIDR范围中的IP),或者IP地址是10.2.2.2,抑或者端口号为9123的TCP或TLS连接。

snis属性

特性

描述

注意事项

SNI路由匹配

当使用安全协议,snis属性可以作为路由属性。例如,TLS连接的SNI扩展名匹配snis字段时,请求匹配该路由

SNI指示不能在TLS连接建立后修改

多SNI支持

snis属性中可以指定多个SNI,匹配任何一个即可满足路由条件,实现“或”关系

虽然理论上可以随意配置snis和hosts属性,但通常不推荐这样做

SNI的重要性

SNI在TLS握手期间指示要连接的服务器,支持多个SSL证书安全托管在同一IP地址上

使用SNI时,每个HTTPS网站可以拥有独立的TLS证书,即使网站共享IP地址

当使用安全协议时(HTTPS、gRPC或TLS),用户可以将snis当作路由属性。示例如下:

代码语言:javascript
复制
{  "snis": ["foo.test", "example.com"],  "id": "..."}

在TLS连接的SNI扩展名中设置的主机名若能匹配snis属性中的字段,则该请求可以匹配此路由。如前所述,SNI路由不仅适用于TLS,还适用于TLS上承载的其他协议,例如HTTPS。如果在snis属性中指定多个SNI,仅需匹配其中任何一个即可,名称之间匹配满足“或”关系。 SNI指示在TLS握手期间要连接的服务器,并且在建立TLS连接后无法修改。这意味着在执行路由匹配时,无论请求头中host字段是什么,复用相同keepalive连接的多个请求将具有相同的SNI主机名。理论上,用户可以随便配置路由的snis属性和hosts属性,但通常情况下不推荐这么操作。 注意 SNI(server Name Indication,服务器名称指示)指示在握手期间浏览器正在联系的主机名,允许服务器为多个网站安全地托管多个SSL证书。多个网站存在于同一IP地址上。使用SNI时,服务器的主机名包含在TLS握手中,这使得HTTPS网站具有唯一的TLS证书(即使网站共享IP地址)。

7.9 Kong网关鉴权

步骤

操作

描述

1

创建服务

添加名为example-service的服务,代理到http://mockbin.org/request

2

添加路由

为example-service服务添加路由,访问路径为/auth-sample

3

验证配置

使用curl命令检查服务和路由配置是否成功

4

添加鉴权插件

为example-service服务添加名为key-auth的鉴权插件

5

验证鉴权插件

验证鉴权插件是否成功应用,检查无key时是否返回错误

6

创建消费者实体

添加消费者,用户名为user123,自定义ID为SOME_CUSTOM_ID

7

提供身份验证凭据

为user123消费者配置新的凭证,并使用该凭证进行身份验证测试

消费者的核心原则是用户可以将插件附加在其之上,从而定制请求行为。 注意 理解消费者的最简单方法就是将它们一对一映射到具体用户。然而,对于Kong网关来说,这个理解过于狭隘。例如开发者有多个应用,他可以为每个应用及其版本定义一个消费者,或者为每个平台定义一个消费者,例如AndroidConsumer、IOSConsumer等。

最常见的鉴权是对服务进行身份校验,并且不允许任何未经身份验证的请求通过。鉴权插件的通用方案如下。 1)配置服务和路由实体,验证代理请求是否通过。 ①添加一个名为example-service的服务,并代理到http://mockbin.org/request,修改地址为Kong官方给出的示例地址:

代码语言:javascript
复制
$ curl -i -X POST \  --url http://127.0.0.1:8001/services/ \  --data 'name=example-service' \  --data 'url=http://mockbin.org/request'

②为该服务添加一个路由,访问路径为/auth-sample:

代码语言:javascript
复制
$ curl -i -X POST \  --url http://127.0.0.1:8001/services/example-service/routes \  --data 'paths[]=/auth-sample'

③使用curl命令验证上述配置是否成功:

代码语言:javascript
复制
$ curl http://127.0.0.1:8000/auth-sample{  "startedDateTime": "2020-09-25T00:34:45.620Z",  "clientIPAddress": "162.20.0.1",  "method": "GET",  "url": "http://127.0.0.1/request",  "httpVersion": "HTTP/1.1",  "cookies": {},  "headers": {    "host": "mockbin.org",    "connection": "close",    "x-forwarded-for": "162.20.0.1, 10.102.78.77, 3.12.247.135",    "x-forwarded-proto": "http",    "x-forwarded-host": "127.0.0.1",    "x-forwarded-port": "80",    "x-real-ip": "47.75.63.6",    "user-agent": "curl/7.64.1",  ...

2)将鉴权插件作用于服务实体或者全局。 ①为services添加名为key-auto的鉴权插件:

代码语言:javascript
复制
$ curl -X POST 127.0.0.1:8001/services/example-service/plugins \  --data "name=key-auth"

②验证该鉴权插件是否添加成功,如果添加成功,但是没有key,返回结果会报错;如果没有添加成功,则正常返回。

代码语言:javascript
复制
$ curl http://127.0.0.1:8000/auth-sample{"message":"No API key found in request"}

3)创建一个消费者实体。 添加一个消费者,username为user123,custom_id为SOME_CUSTOM_ID:

代码语言:javascript
复制
$ curl -d "username=user123&custom_id=SOME_CUSTOM_ID"   http://127.0.0.1:8001/consumers/

4)为消费者提供特定身份验证方法的身份验证凭据。 ①为该消费者配置新的凭证:

代码语言:javascript
复制
$ curl -X POST http://127.0.0.1:8001/consumers/user123/key-auth -d ''{  "created_at":1600994689,"consumer":{"id":"d833db4e-4eae-4575-947e-    d7c2f61bb299"},  "id":"bb499039-e071-4419-9c00-5bd8af17a5f7",  "tags":null,  "ttl":null,  "key":"joWSLkrBQUgXT2darCwZGjVxBFPUHljs"}

②将上述消费者中的key作为url的querystring参数并发出请求:

代码语言:javascript
复制
$ curl http://127.0.0.1:8000/auth-sample?apikey=joWSLkrBQUgXT2darCwZGjVxBFPUHljs{  "startedDateTime": "2020-09-25T00:46:01.856Z",  "clientIPAddress": "162.20.0.1",  "method": "GET",  "url": "http://127.0.0.1/request?apikey=joWSLkrBQUgXT2darCwZGjVxBFPUHljs",  "httpVersion": "HTTP/1.1",  "cookies": {}, ...  "queryString": {    "apikey": "joWSLkrBQUgXT2darCwZGjVxBFPUHljs"  },...

匿名接入流程 从上述的例子我们发现,当添加key-auth鉴权插件后,请求必须带上凭据才能访问通过。接下来我们看一下如何配置匿名用户直接访问代理服务。 1)紧接上述流程添加一个名为anonymous_users的匿名用户:

代码语言:javascript
复制
$ curl -i -X POST \  --url http://127.0.0.1:8001/consumers/ \  --data "username=anonymous_users"

2)配置key-auth鉴权插件允许匿名用户访问:

获取plugins的id

代码语言:javascript
复制
$ curl 127.0.0.1:8001/services/example-service/plugins{"next":null,"data":..."id":"16276239-c173-48d5-82c7-171e01d8fb5f",...}

获取consumers的id

代码语言:javascript
复制
$ curl http://127.0.0.1:8001/consumers/anonymous_users{..."id":"19a20edc-ade4-45ff-8201-259c542727d3",...}

允许匿名用户访问

代码语言:javascript
复制
$ curl -i -X PATCH \  --url http://localhost:8001/plugins/16276239-c173-48d5-82c7-171e01d8fb  5f \  --data "config.anonymous=19a20edc-ade4-45ff-8201-259c542727d3"

3)使用curl命令验证是否可以直接访问:

代码语言:javascript
复制
$ curl -X GET \  --url http://localhost:8000/auth-sample{  "startedDateTime": "2020-09-25T01:03:23.809Z",  "clientIPAddress": "162.20.0.1",  "method": "GET",  "url": "http://127.0.0.1/request",  "httpVersion": "HTTP/1.1",  "cookies": {},...  "x-consumer-id": "19a20edc-ade4-45ff-8201-259c542727d3",  "x-consumer-username": "anonymous_users",  "x-anonymous-consumer": "true",...  "queryString": {},...

Kong网关能够配置服务,同时允许身份验证和匿名访问。比如用户可以对某个服务开设匿名用户访问权限,但是限流策略比较严格;同时对该服务增加一个需要身份验证的访问权限,并放宽限流策略。

多重认证策略 Kong网关支持给服务配置多个鉴权插件,允许不同客户端使用不同的身份验证策略来访问指定的服务或路由。在评估多个身份验证凭据时,逻辑比较复杂,关键因素在于config.anonymous属性。

  1. 未设置config.anonymous属性时,鉴权插件将始终执行身份验证。如果身份未通过验证,则会返回40XX。当使用多个鉴权插件时,验证结果之间会取“与”关系。
  2. 设置config.anonymous属性时,不是每个鉴权插件都会执行,而是仅当上个鉴权条件失败,才会执行下一个鉴权插件。当所有身份验证失败后,不会返回4XX,而是将请求当作匿名消费者接入。当使用多个鉴权插件时,验证结果之间会取“或”关系。

多重认证策略补充说明如下。

  1. 当给服务配置多个鉴权插件时,必须统一配置匿名访问权限或者统一不配置。如果有些鉴权插件的配置,有些没配置,会造成鉴权结果未知。这在开发环境中是严禁的。
  2. 当多个插件间为“与”关系时,最后执行的插件的凭据信息将被接入上游服务;当多个插件间为“或”关系时,第一个验证成功的插件的凭据信息会被接入上游服务,或者最后一个匿名接入的消费者的信息会被接入上游服务。

特性

未设置config.anonymous

设置config.anonymous

补充说明

鉴权执行

每个插件总是执行身份验证

仅上一个鉴权条件失败时执行下一个鉴权插件

统一配置匿名访问权限,避免不确定的鉴权结果

验证结果逻辑

身份验证结果取“与”关系

身份验证结果取“或”关系

“与”关系时,最后一个插件的凭据信息接入上游;“或”关系时,第一个成功的或最后一个匿名消费者的信息接入

认证失败行为

返回40XX错误

将请求作为匿名消费者处理,不返回4XX

注意匿名访问权限的配置对整体鉴权逻辑的影响

LB

8.1 负载均衡

市场上较为成熟的软件负载均衡解决方案为Nginx、HAProxy和LVS;硬件负载均衡解决方案为F5、A10等。 软硬件负载均衡解决方案各有优缺点。我们可以横向对比一下F5和Nginx这两种常用解决方案,如表8-1所示。

表8-1 F5与Nginx优缺点

Kong网关在Nginx负载均衡策略基础上做了更高的抽象。从功能特性上划分,其可以分为两种实现方式:

  1. 一种是基于DNS
  2. 另一种是基于Ring-Balancer(环状负载均衡器,无须DNS服务器即可实现服务注册,并且可以动态挂载、注销后端服务、调整服务权重配比)。

8.2 基于DNS的负载均衡

DNS记录类型

描述

DNS记录优先级

A记录

指定主机名(或域名)对应的IPv4 IP地址记录

3

AAAA记录

将域名解析到指定的IPv6 IP地址

同A记录

CNAME记录

别名解析,可以将不同域名转到一个域名记录上

4

SRV记录

指定服务地址,包括服务器的地址、端口、优先级和权重

2

DNS记录类型

  1. A记录:指定主机名(或域名)对应的IP地址记录。
  2. AAAA记录:将域名解析到一个指定的IPv6的IP上。
  3. CNAME记录:通常称为别名解析,可以将注册的不同域名都转到一个域名记录上。由这个域名记录统一解析、管理注册的域名。与A记录不同的是,CNAME记录设置的不一定是IP地址,也可以是域名。
  4. SRV记录:用来指定服务地址。与常见的A记录、CNAME记录不同的是,SRV记录中除了记录服务器的地址,还记录了服务的端口,并且可以设置每个服务地址的优先级和权重。

DNS记录优先级

  1. 上一次成功解析的记录类型
  2. SRV记录
  3. A记录(包含AAAA记录)
  4. CNAME记录

8.5 健康检查

响应类型

影响

计数器更新

健康状态影响

状态码为healthy

递增successes计数器

清零其他计数器

如果successes计数器达到阈值,服务标记为健康

连接失败

递增tcp failure计数器

清零successes计数器

如果tcp failures达到阈值,服务标记为不健康

发生超时

递增timeouts计数器

清零successes计数器

如果timeouts达到阈值,服务标记为不健康

状态码为unhealthy

递增http failure计数器

清零successes计数器

如果http failures达到阈值,服务标记为不健康

处理完一个请求可能会返回TCP错误、超时或者http状态码等信息。根据这些信息,系统内部会实时更新一系列内部计数器。

  1. 当返回的状态码是healthy时,系统内部会递增successes计数器,并清零其他计数器。
  2. 如果发生连接失败,系统内部会递增tcp failure计数器,并清零successes计数器。
  3. 如果发生超时,系统内部会递增timeouts计数器,并清零successes计数器。
  4. 当返回的状态码是unhealthy时,系统内部会递增http failure计数器,并清零successes计数器。
  5. 如果tcp failures、http failures或timeouts计数器中的任何一个达到预设阈值,对应的后端服务将标记为不健康。如果successes计数器达到预设阈值,对应的后端服务将标记为健康。

Kong网关中的健康检查方式包括主动健康检查和被动健康检查。

特征

主动健康检查

被动健康检查

描述

定期请求后端服务的特定http/https端点,根据响应确定健康状态

根据流量中的响应行为判断后端服务的健康状态

优点

可自动重新启用恢复健康的后端服务;允许自定义健康检查指标

不产生额外流量;无需额外配置

缺点

产生额外流量;需要后端服务配置特定端点

恢复健康的后端服务不会自动重新启用

插件

Kong网关插件内容

描述

组件

插件简介

Kong网关是一个加载和执行Lua模块的Lua应用程序,插件通过PDK与HTTP请求、响应或流交互

-

自定义插件

自定义插件遵循特定命名规范,需在配置文件中指定插件名称以被加载

kong.plugins.<plugin-name>

基本插件模块

插件至少包含handler.lua和schema.lua两个模块,分别用于定义插件的接口和配置项规则

handler.lua, schema.lua

高级插件模块

高级插件模块包括额外功能,如定义数据库业务数据表、在Admin API中暴露端点等

api.lua, daos.lua, migrations, handler.lua, schema.lua

9.1 Kong网关插件简介

Kong网关就是一个Lua应用程序。它的主要功能就是加载和执行Lua模块(这里我们抽象成了插件),并为它们提供整个开发环境,包括SDK、数据库抽象、数据迁移等。 插件是由Lua模块组成的,它们通过插件开发包(Plugin Development Kit,PDK)与HTTP请求、响应或者流进行交互,然后实现各种逻辑。PDK也是一组Lua方法。插件可以通过它们与Kong服务器的核心组件进行交互。

9.3 自定义Kong网关插件

Kong插件中的Lua脚本遵循同一个命名规范。Kong网关会检测符合命令规范的Lua文件并加载它们。命名规范如下所示: kong.plugins..

为了让Kong网关明确需要去查找哪些自定义插件,用户需要在配置文件的plugins属性中添加插件名称字段。多个插件之间使用逗号隔开,例如:

代码语言:javascript
复制
plugins = bundled,my-custom-plugin # 用户自定义插件名

当用户不希望加载任何系统自带的插件时,可以在plugins属性中添加自定义的插件名:

代码语言:javascript
复制
plugins = my-custom-plugin  # 用户自定义插件名

现在,Kong网关会尝试从以下命名空间加载多个Lua模块:

代码语言:javascript
复制
kong.plugins.my-custom-plugin.

其中,有些模块是必需的(例如handler模块),有些是可选的,以便实现一些额外功能。下面我们会详细描述基本插件模块以及它们的用途。

基本插件模块 插件必须包含两个模块,目录结构如下:

代码语言:javascript
复制
simple-plugin├── handler.lua└── schema.lua

·handler模块:插件的核心模块。它提供了一组接口,需要用户自定义实现,其中每个方法都会在请求和连接生命周期中的指定时间点运行。 ·schema模块:该模块定义了配置项的规则和格式,会对用户输入的数据进行校验。

高级插件模块 有些插件与Kong网关集成得很深,比如需要在数据库中定义业务数据表,或者在Admin API中暴露新的端点等。插件可以通过添加新的模块来完成这些功能。一个插件包括所有的可选模块(除基本模块之外,还有高级模块),其目录结构如下:

代码语言:javascript
复制
complete-plugin├── api.lua├── daos.lua├── handler.lua├── migrations│   ├── cassandra.lua│   └── postgres.lua└── schema.lua

表9-15 插件模块

日志

优化对象

优化层面

优化策略

详细描述

Elasticsearch

索引层面

增加刷新时间间隔

延长刷新时间间隔以减少段合并压力

调整副本数量

增加副本数量提高可用性,但影响写入效率

开启异步刷写

允许微量日志数据丢失来提升性能

开启慢查询日志

用于排查问题的慢查询日志

服务器层面

内存调优

平衡Lucene和Elasticsearch内存占比,禁止Swap分区

调整集群分片

分片容量和数目调整

Mapping建模和查询优化

避免复杂关联关系处理

Logstash

性能调优

JVM调优

扩展JVM堆内存,设置Xms和Xmx为相同值

增加工作线程数

增加filter和output工作线程数

配置pipeline.batch.size

平衡性能和内存开销

Elasticsearch调优 Elasticsearch性能优化主要分为两个方面:索引层面和服务器层面。 在索引层面,Elasticsearch性能优化如下。

  1. 增加刷新时间间隔:当我们对日志系统查询延迟要求不高时,可以适当延长刷新时间间隔,这样能够有效减少段(Segment)合并压力,提高索引速度。与之对应的配置项为index.refresh_interval,默认为1秒,推荐设置为30秒。
  2. 调整副本数量:增加副本数量可以提高集群的可用性和搜索并发数,但同时会影响写入索引的效率。建议将副本数量设置为1,以便提升整体性能。
  3. 开启异步刷写:如果业务上允许微量的日志数据丢失,可以对某些特定索引开启异步刷写。
  4. 开启慢查询日志:无论是数据库还是搜索引擎,在排查问题时,开启慢查询日志相当必要。我们可以调用模板API进行全局设置。

在服务器层面,Elasticsearch性能优化如下。

  1. 内存调优:由于Elasticsearch基于Lucene构建,在分配内存时,我们需要平衡好两者的内存占比。通常情况下两者约各占一半,还需预留一些内存供操作系统使用,同时必须禁止Swap分区交换,因为允许内存与磁盘交换会引发致命的性能问题。在elasticsearch.yml中设置bootstrap.memory_lock为true,可以保持JVM锁定内存,保证Elasticsearch的性能。
  2. 调整集群分片:每个分片占用的硬盘容量不超过Elasticsearch最大的JVM堆空间(一般不超过32GB),分片数目一般不超过集群节点数目的3倍。
  3. Mapping建模和查询优化:尽量避免使用关联关系处理,如nested或parent/child。当必须使用nested fields时,需要限制字段数量。

Logstash调优 在进行Logstash性能调优时,建议每次仅修改一个配置项并观察性能和资源消耗。通常我们需要考虑的性能指标有CPU、内存和I/O。I/O包括磁盘I/O和网络I/O。Logstash具体的性能调优包括以下几项。

  1. 常见的JVM调优:尽量扩展JVM堆内存,但是需要给操作系统和其他进程留出一定的空间。Xms和Xmx需设置为相同的值,并防止在运行时调整堆内存大小,以免产生昂贵的开销。
  2. 通过启动项参数来增加filter和output工作线程数。Logstash正则解析极其消耗计算资源,如果业务中大量使用Logstash正则解析,可以设置线程数大于核数。
  3. 在启动项参数中配置pipeline.batch.size。该参数决定了Logstash每次调用ES bulk index API时传输的数据量。增大该值可以在一定范围内提高性能,但会增加额外的内存开销。用户应做好性能和内存之间的平衡。

10.3 自定义日志

表10-2 自定义日志方式对比

运维

11.1 资源选型

根据配置实体数、接口延迟时间、接口吞吐量等指标对系统资源进行了划分,并给出了使用场景。

表11-1 系统资源参考

表11-2 资源选型

优化

特性

描述

影响因素

注意事项

内存缓存配置

建议将 mem_cache_size 配置尽可能大,预留足够资源给操作系统和其他程序

CPU核心数量和服务器内存大小影响内存分配

需要根据服务器的实际情况和运行的其他程序进行调整

性能指标

Kong网关性能考量包括延时和吞吐量

路由和插件数量增加可能会增加延时

延时和吞吐量通常呈反比关系

插件基数

集群上启用的不同类型插件数量

每增加一个插件类型,会消耗更多CPU资源

影响请求处理速度

大请求/响应处理

处理大请求/响应时,Kong网关需缓存到磁盘

缓存请求/响应体大小

可能导致延时增加

11.2 Kong网关监控

表11-3 监控软件对比

高可用

12.1 Kong网关安全配置

网关层具有重要且独特的保护作用,目的是防止外部网络环境中的不安全因素蔓延到内部应用或企业网。对于Kong网关来说,其涉及安全的考量项主要有两个:一个是对后端应用的保护,另一个是对其本身Admin API的保护。 对于后端应用的保护策略,读者可以根据实际场景自主集成Kong网关提供的插件,也可以自定义插件。 这里我们着重讨论Kong网关的Admin API的保护策略。Admin API对外提供了RESTful接口,以便管理和配置服务、路由、插件、使用者以及凭据信息。其具有对Kong服务的完全控制权,因此可确保RESTful接口安全可靠,避免不必要的访问。下面我们提供4种方式对Admin API设置访问控制,包括对网络层、Kong API回路(Loopback)、自定义Nginx配置的访问控制。

安全领域

描述

实现方法

后端应用保护

保护内部应用或企业网免受外部网络环境中的不安全因素影响

使用或自定义Kong网关提供的插件进行集成保护

Admin API保护

保护对Kong服务具有完全控制权的RESTful接口,管理服务、路由等

设置访问控制,包括网络层、Kong API回路、自定义Nginx配置等方法

微服务

13.1 微服务简介

微服务12要素是由PaaS先驱Heroku公司CTO——Admin Wiggins提出的。他为微服务开发者提供了一组明确的指引。开发者遵循这些原则,就可以很容易地运行、扩展和部署微服务应用。微服务12要素具体包括如下内容。

要素编号

要素名称

描述

1

基准代码

一份基准代码,多份部署

2

依赖

显式声明依赖关系

3

配置

在环境中存储配置

4

后端服务

将后端服务当作附加资源

5

构建、发布、运行

严格分离构建、发布、运行步骤

6

进程

以一个或多个无状态进程运行应用

7

端口绑定

通过端口绑定提供服务

8

并发

通过进程模型进行扩展

9

可弃性

快速启动和优雅终止可最大化健壮性

10

开发环境与线上环境等价

尽可能保持开发、测试、预发布、线上等多套环境一致

11

日志

将日志看作事件流来管理

12

管理进程

将后台管理任务当作一次性进程运行

13.2 单体应用向微服务迁移

3.过渡策略

策略

方法

优点

缺点

冰激凌策略

将单体应用的组件分解到单独的服务,逐步过渡到微服务

低风险逐步迁移,不影响正常运行和用户体验

需要长周期,是渐进过程

乐高策略

保持老应用原样,新功能作为微服务构建

不需对原应用过多改造,快速构建新微服务

原应用问题仍存在,需新API支持微服务

核按钮策略

全部重写单体应用为微服务

从头开始重构,整体考量架构方案

高人力成本,从头开始,维护两应用

13.3 使用CI/CD流程促进微服务开发

图13-3 测试方案全景

13.4 基于Kong打造DevOps平台

图13-4 DevOps平台全局交互

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-12-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 yeedomliu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 思维导图
  • 前言
  • 全面了解
    • 1.1 网关简介
      • 1.2 Kong网关简介
        • 1.3 Kong网关基础组件
          • 1.4 Kong网关安装指南
            • 1.5 使用Kong网关搭建Web应用
              • 2.4 本章小结
              • Lua
                • 3.1 Lua入门与规范
                  • 3.2 数据类型
                  • OpenResty
                    • 4.2 OpenResty详解
                      • 4.4 OpenResty性能优化
                      • 部署
                        • 5.4 Kong网关部署
                        • 代理和鉴权
                          • 7.2 Kong网关代理示例
                            • 7.3 路由匹配规则
                              • snis属性
                                • 7.9 Kong网关鉴权
                                  • 获取plugins的id
                                    • 获取consumers的id
                                      • 允许匿名用户访问
                                      • LB
                                        • 8.1 负载均衡
                                          • 8.2 基于DNS的负载均衡
                                            • 8.5 健康检查
                                            • 插件
                                              • 9.1 Kong网关插件简介
                                                • 9.3 自定义Kong网关插件
                                                • 日志
                                                  • 10.3 自定义日志
                                                  • 运维
                                                    • 11.1 资源选型
                                                      • 11.2 Kong网关监控
                                                      • 高可用
                                                        • 12.1 Kong网关安全配置
                                                        • 微服务
                                                          • 13.1 微服务简介
                                                            • 13.2 单体应用向微服务迁移
                                                              • 13.3 使用CI/CD流程促进微服务开发
                                                                • 13.4 基于Kong打造DevOps平台
                                                                相关产品与服务
                                                                多因子身份认证
                                                                多因子身份认证(Multi-factor Authentication Service,MFAS)的目的是建立一个多层次的防御体系,通过结合两种或三种认证因子(基于记忆的/基于持有物的/基于生物特征的认证因子)验证访问者的身份,使系统或资源更加安全。攻击者即使破解单一因子(如口令、人脸),应用的安全依然可以得到保障。
                                                                领券
                                                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档