0
点赞
收藏
分享

微信扫一扫

kong 自建一个具有健康检查功能的http/tcp负载均衡器,配置流量权重,自动/手动目标健康,流量统一认证、鉴权、限流限速、修正,监控、日志等功能


​​

全栈工程师开发手册 (作者:栾鹏)
​​ 架构系列文章​​

Kong

目前kong的最新版为2.2,官方git在https://github.com/Kong/kong,下面是一个kong的简单结构

kong 自建一个具有健康检查功能的http/tcp负载均衡器,配置流量权重,自动/手动目标健康,流量统一认证、鉴权、限流限速、修正,监控、日志等功能_http

kong的基础结构包含upstream(负载均衡器)、target(目标机器)、service(流量入口)、route(引流规则)。流量如果符合route规则,就会引入到service,进而流入到绑定的upstream。再根据upstream配置的负载均衡策略,流入到健康的target。

kong包含无数据库模式,是为了更方便运维管理。不过很多操作会被限制,所以这里还是推荐有数据库模式,数据库只需要运维的一个postgresql就可以。

因为我们是在k8s中使用,这里介绍下k8s中如何部署kong,只需要运行

kubectl apply -f all-in-one-postgres-test.yaml

文件在https://github.com/626626cdllp/k8s

如果自己已经存在pg数据库,可以将文件的相关部分去掉。

kong 自建一个具有健康检查功能的http/tcp负载均衡器,配置流量权重,自动/手动目标健康,流量统一认证、鉴权、限流限速、修正,监控、日志等功能_http_02

部署的容器会监听8000端口(http代理),8001端口(admin操作接口),5555端口(tcp流代理),8443端口(https代理)。在service侧,这些端口被映射为了80->8000,8001->8001,5555->5555,443->8443。

伸缩高可用

基于后端数据库模式,kong的控制平面和数据平面分开部署,可以单独增加kong的数据平面来实现横向扩展。当部署多个kong ingress controller时,多个kong ingress controller之间会选举出leader。同一时间只有leader能配置kong的规则,并且leader失效后会自动选主。

http负载均衡代理

部署好了以后就可以进行配置了。先来说说如何配置http/https 7层代理。按照前面的结构逻辑,我们需要先配置一个upstream,使用随机负载策略,然后再创建一个service与该upstream绑定。

curl --location --request POST 'http://127.0.0.1:8001/upstreams' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "test_upstreams",
"algorithm":"round-robin"
}'
curl --location --request POST 'http://127.0.0.1:8001/services' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "test_services",
"host":"test_upstreams",
"retries":5,
"protocol":"http"
}'

下面需要配置的就是首部的route和尾部的target,假设原有test.com域名下有ip 1.1.1.1:8080和2.2.2.2:8080,现在我们配置test.com到kong proxy的ip,并希望访问test.com的流量能代理到1.1.1.1或2.2.2.2上。那么我们配置route为

curl --location --request POST 'http://127.0.0.1:8001/routes' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "test_routes",
"hosts":["test.com"],
"protocols":["http"],
"service": {"name":"test_services"}
}'

因为http有标准的协议,匹配的方法有很多,比如可以根据host(实际为http header中的location字段),协议(http、https),path(/,/index)等来对不同的流量进行不同的代理。

配置target示例如下,你可以按自己的需要定制权重参数。

curl --location --request POST 'http://127.0.0.1:8001/upstreams/test_upstreams/targets' \
--header 'Content-Type: application/json' \
--data-raw '{
"target": "1.1.1.1:8080",
"weight":1
}'

curl --location --request POST 'http://127.0.0.1:8001/upstreams/test_upstreams/targets' \
--header 'Content-Type: application/json' \
--data-raw '{
"target": "2.2.2.2:8080",
"weight":1
}'

这样再访问 test.com 就可以正常访问对应的ip了。健康检查在后面统一介绍。

tcp负载均衡
而除了http,还有在tcp层的流量代理需求。我们知道tcp在http层以下,能明确标准获取的是源ip、目的ip、源端口、目的端口。所以通过匹配规则对tcp流量进行代理比较限制。

curl --location --request GET 'http://127.0.0.1:8001/routes' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "test_routes",
"sources":[{"ip":"172.16.160.7","port":9000}],
"protocols":["tcp","udp"],
"service": {"name":"test_services"}
}'

tcp代理的匹配规则只能是源ip或源ip网段,目的ip或目的ip网段。所在使用起来会有些局限。可以跟你情况选择,或者部署多个kong集群,每个kong来代理不同的tcp,灵活使用。

健康检查

上面介绍了怎么配置http/tcp代理和流量负载均衡。还有一个我们需要的就是负载均衡器能自动进行健康检查,或者支持手动配置目标是否健康。

健康检查是配置在负载均衡器upstreams中的,通过healthchecks字段来配置的,示例如下:

{
"name": "tcp-upstreams",
"algorithm":"round-robin",
"healthchecks":{
"active":{
"http_path":"/",
"timeout": 30,
"type": "tcp",
"healthy": {
"http_statuses": [200, 302],
"interval": 60,
"successes": 1
},
"unhealthy": {
"http_statuses": [429, 404, 500, 501, 502, 503, 504, 505],
"tcp_failures": 1,
"timeouts": 30,
"http_failures": 1,
"interval": 60
}
},
"passive": {
"unhealthy": {
"http_failures": 253,
"http_statuses": [429, 500, 503],
"tcp_failures": 2,
"timeouts": 60
},
"type": "tcp",
"healthy": {
"successes": 1,
"http_statuses": [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308]
}
}
}
}

主动检查

active是主动检查,就是kong会定时发送请求去检查target是否健康,如果满足健康标准就设置为healthy,如果满足非健康标准就设置为unhealthy,主动检查分为http/https和tcp检查方式。http可配置比较流量,可以根据范文路径的返回状态码或连接响应时长来判断,tcp比较局限,只能配置连接是否超时或者失败来判断

被动检查

passive是被动检查,就是kong本身并不发起流量,只在有流量时,根据流量的范文响应情况确定目标是否健康。这样能减少kong的部分负担,但是也存在target损坏后第一次流量接入是不知道的,而且这种情况下target标记为非健康,就会一直保持非健康状态,除非手动标记为健康。手动标记健康的方法为

curl --location --request POST 'http://127.0.0.1:8001/upstreams/test_upstreams/targets/xx.xx.xx.xx:xx/healthy' \
--header 'Content-Type: application/json' \
--data-raw '{
"target": "xx.xx.xx.xx:xx",
"weight":1
}'

如果 upstream 下的所有 target 都不健康,那么Kong会返回 503 Service Unavailable

插件

插件在kong网关架构中的位置是这样的。

kong 自建一个具有健康检查功能的http/tcp负载均衡器,配置流量权重,自动/手动目标健康,流量统一认证、鉴权、限流限速、修正,监控、日志等功能_tcp_03

既然能统一代理流量,那就可以统一进行流量管理了。Kong是一个OpenResty应用,支持lua写的插件,官方提供了很多功能层的插件:

  • 身份认证插件:Kong提供了Basic Authentication、Key authentication、OAuth2.0 authentication、HMAC authentication、JWT、LDAP authentication认证实现。
  • 安全控制插件:ACL(访问控制)、CORS(跨域资源共享)、动态SSL、IP限制、爬虫检测实现。
    流量控制插件:请求限流(基于请求计数限流)、上游响应限流(根据upstream响应计数限流)、请求大小限制。限流支持本地、Redis和集群限流模式。
  • 分析监控插件:Galileo(记录请求和响应数据,实现API分析)、Datadog(记录API Metric如请求次数、请求大小、响应状态和延迟,可视化API Metric)、Runscope(记录请求和响应数据,实现API性能测试和监控)。
  • 协议转换插件:请求转换(在转发到upstream之前修改请求)、响应转换(在upstream响应返回给客户端之前修改响应)。
  • 日志应用插件:TCP、UDP、HTTP、File、Syslog、StatsD、Loggly等。
    这些插件控制着上行/下行流量,识别/修改/监控/模拟流量。当然你完全可以编写自己的插件来满足对流量的控制

这里开源了三个新插件如果需要可以参考:

1、后端通过cookie来控制前端请求转发到两个upstream上。
2、修改http响应的header头,满足对流量后续的识别。

3、检修prometheus的插件,满足更多监控数据的采集。

API网关对比

下面给一个微服务网关的对比,选择网关的首要就是能不能满足自己的需求。

kong 自建一个具有健康检查功能的http/tcp负载均衡器,配置流量权重,自动/手动目标健康,流量统一认证、鉴权、限流限速、修正,监控、日志等功能_健康检查_04

kong 自建一个具有健康检查功能的http/tcp负载均衡器,配置流量权重,自动/手动目标健康,流量统一认证、鉴权、限流限速、修正,监控、日志等功能_网关_05


kong 自建一个具有健康检查功能的http/tcp负载均衡器,配置流量权重,自动/手动目标健康,流量统一认证、鉴权、限流限速、修正,监控、日志等功能_http_06


举报
0 条评论