48

花椒直播Kong应用实践

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzUxMTcwOTM4Mg%3D%3D&%3Bmid=2247486408&%3Bidx=1&%3Bsn=a3445a978177d3053b7ad4e46e6e375c
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

vMrAf2Y.jpg!web

什么是Kong

Kong 是面向现代架构(混合云,混合组织)的下一代 API 网关平台,具有云原生、高性能,易用、可扩展等特性。

适用于 Api Gateway, Kubernetes Ingress, Service Mesh Sidecar 等场景。

主要特性有:

  • 云原生: 与平台无关,Kong 可以从裸机运行到 Kubernetes

  • 高性能: 背靠非阻塞通信的 nginx,性能自不用说

  • 插件机制: 提供众多开箱即用的插件,且有易于扩展的自定义插件接口,用户可以使用 Lua 自行开发插件

  • 熔断:可以通过插件实现熔断,避免系统雪崩

  • 日志: 可以记录通过 Kong 的 HTTP,TCP,UDP 请求和响应。

  • 鉴权: 权限控制,IP 黑白名单,同样是 OpenResty 的特性

  • SSL: Setup a Specific SSL Certificate for an underlying service or API.

  • 监控: Kong 提供了实时监控插件

  • 认证: 如数支持 HMAC, JWT, Basic, OAuth 2.0 等常用协议

  • 限流:可以通过插件实现单个服务某些接口的限流,避免服务过载导致不可用

  • REST API: 通过 Rest API 进行配置管理,从繁琐的配置文件中解放

  • 健康检查:自动检查,被动检查;节点不可用同步到所有的kong节点需要 1 - 2 秒

  • 动态路由:Kong 的背后是 OpenResty+Lua,所以从 OpenResty 继承了动态路由的特性

为什么使用Kong

目前我们需要解决的问题

  1. 统一入口: 服务端微服务框架中,接口权限验证,ip限制,限流等在各个服务中都单独实现。没有统一入口,不方便统一管理。

  2. 易用性,扩展性: 服务端技术栈主要是LNMP开发,目前在逐步转型到基于Spring Boot、Spring Clound 微服务技术栈上开发。这是一个灰度迁移的过程,我们需要Proxy能操作简单,管理方便。

  3. 持续集成发布: 互联网 2C 产品,用户无时不刻不在使用服务,同时产品还在不断的迭代,服务每时每刻都可以发布,所以必须要热部署能力,并且是自动化的。但是基于Spring Boot的服务启动 15 -30 秒,我们需要 Kong 的蓝绿发布功能。

Kong 可以完美的解决以上问题,解决方案如下:

  1. 统一入口: 可以作为微服务统一入口,将限流,权限验证,日志,ip 限制等统一实现

jYfyi2E.jpg!webavatar
  1. 易用性,扩展性:提供了Restful操作方式,并且有dashboard管理工具

    # 创建一个名称 hello 的 upstream

    curl -X POST http://localhost:8001/upstreams --data "name=hello"


    # 为 hello 添加两个负载均衡节点

    curl -X POST http://localhost:8001/upstreams/hello/targets --data "target=localhost:8080" --data "weight=100"


    curl -X POST http://localhost:8001/upstreams/hello/targets --data "target=localhost:8081" --data "weight=100"


    # 配置一个service

    curl -X POST http://localhost:8001/services --data "name=hello" --data "host=hello"


    # 为service 配置路由

    curl -X POST http://localhost:8001/routes --data "paths[]=/hello" --data "service.id={$service.id 配置上面service返回的}"

    dashboard工具截图

    mI3iumA.jpg!webavatar
  2. 持续集成发布:与 GitLab CI/CD 配合,代码提交代码库后,自动打包,运行测试用例,蓝绿部署。

    bUzUfiu.jpg!web

我们如何使用Kong

1

Kong集群

  1. 所有节点连接到数据中心

  • 使用 Postgresql 主从机制,保证数据库高可用,注意使用9.6以上版本

所有节点将周期性执行任务,同步数据最终一致

  • 配置选项: db_update_frequency (默认: 5 秒)

  • 每 db_update_frequency 秒,所有节点将从数据库中拉取所有更新,如果有同步到更新变化,将清理本地相关缓存。

  • 如果 Postgresql 数据库异常,节点使用原有数据还可以提供服务

节点有本地缓存,可以设置缓存过期时间

  • 配置选项: db_cache_ttl (default: 0s)

  • 当数据中心异常,依赖本地缓存依旧可以提供服务

支持动态扩容,参考上方架构图,Kong集群在Lvs后面

  • 新增节点,同步其他节点配置后,验证正常,加到到Lvs的RS里即可,就提供服务了

  • 删除节点,直接将 Lvs 的 RS 删除即可,他就不提供服务了

  • 修改节点配置,先从 Lvs 后摘除kong RS, 修改完成后重启,验证正常,放回到 Lvs 的 RS 里面

支持 gRPC

# /etc/kong/kong.conf

proxy_listen = 0.0.0.0:8000, 0.0.0.0:8443 ssl, 0.0.0.0:9080 http2

服务监控

  • 使用prometheus,grafana和Kong天然配合

    BJBRf2m.jpg!web

注意事项

  1. kong/templates/nginx_kong.lua 模板文件统一

  2. 对于kong日志要做好切割,我们使用 logrotate

2

Kong插件

  • kong的插件功能很多其内置了很多包括认证,限流,日志等相关插件,当然也可以自定义插件,加载成功后就可以在这个界面进行添加使用

AfYB3qI.jpg!webavatar
  • 不同的插件有不同的参数,需要进行设定,设定完成后就会启用

    例如:这是内置的 key-auth 插件,作用是进行api认证,设定 key 之后只有认证通过的才能访问

  • 自定义开发和部署,根据业务需要开发插件

基本流程

1.下载模板

base简单版

simple-plugin

├── handler.lua

└── schema.lua

advanced高级版

complete-plugin

├── api.lua

├── daos.lua

├── handler.lua

├── migrations

│ ├── cassandra.lua

│ └── postgres.lua

└── schema.lua

必要文件就是 handler.lua 和 schema.lua

2.  修改 handler.lua 文件,有很多函数,自定义逻辑就是在这些函数中写kong会在一些特定阶段调用对应的函数

local BasePlugin = require "kong.plugins.base_plugin"


-- The actual logic is implemented in those modules

local access = require "kong.plugins.my-custom-plugin.access"

local body_filter = require "kong.plugins.my-custom-plugin.body_filter"


local CustomHandler = BasePlugin:extend()


function CustomHandler:new()

CustomHandler.super.new(self, "my-custom-plugin")

end


function CustomHandler:access(config)

CustomHandler.super.access(self)


-- Execute any function from the module loaded in `access`,

-- for example, `execute()` and passing it the plugin's configuration.

access.execute(config)

end


function CustomHandler:body_filter(config)

CustomHandler.super.body_filter(self)


-- Execute any function from the module loaded in `body_filter`,

-- for example, `execute()` and passing it the plugin's configuration.

body_filter.execute(config)

end


return CustomHandler


3. 修改 schema.lua 文件,主要是配置一些参数,以及参数检查

return {

no_consumer = true, -- this plugin will only be applied to Services or Routes,

fields = {

-- Describe your plugin's configuration's schema here.

},

self_check = function(schema, plugin_t, dao, is_updating)

-- perform any custom verification

return true

end

}

4. 配置部署

插件文件在

/data/kong/plugins/simple-plugin/

则配置kong.conf

lua_package_path = /data/?.lua;($default);

plugins = bundled,simple-plugin

然后重新reload kong 如果lua插件没有错误,就可以在后台看到加载出来了

线上碰到问题

  1. 返回的内容太大,需要加大 buffer(upstream response cache error) 修改配置

    nginx_proxy_proxy_buffer_size=128k

    nginx_proxy_proxy_buffers=4 256k

    nginx_proxy_proxy_busy_buffers_size=256k

  2. 需要注意配置属性

  • strip_path 属性

如果设置为 true, paths 设置有值,那么请求将会被替换掉

{ "paths": ["/service"], "strip_path": true, "service": { "id": "..." }}

请求:GET /service/path/to/resource HTTP/1.1Host: …

Proxy: GET /path/to/resource HTTP/1.1


{ "paths": ["/version/\d+/service"], "strip_path": true, "service": { "id": "..." }}

请求:GET /version/1/service/path/to/resource HTTP/1.1

Proxy: GET /path/to/resource HTTP/1.1

  • preserve_host属性

如果设置为 true,代理后仍然保留 header 请求 host

请求:GET / HTTP/1.1Host: service.com

Proxy: GET / HTTP/1.1Host: service.com


设置为false,将不保留header host

GET / HTTP/1.1Host: service.com

GET / HTTP/1.1Host: <my-service-host.com>

总结

Kong 是行业内较为成熟的网关开源产品,无论是性能,易用,扩展方面都表现不错。

Kong 就是服务治理的翅膀,可以更优雅,更便捷,更智能的实现服务降级,熔断,流量调度等工作。

让我们在自建 Kunernetes 私有云,Hulk云,阿里云等复杂的架构中任意翱翔。

本文转载自花椒技术

i6raArj.png!web
b6bMBjv.png!web

360技术公众号

技术干货|一手资讯|精彩活动

扫码关注我们


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK