第四章:Kong的江湖武功秘籍 🎯
自定义插件开发:打造专属”必杀技”
Kong的插件系统是其最强大的特性之一,但有时预置的插件可能无法满足你的特定需求。这时,开发自定义插件就成为了必要的技能。
插件开发基础
Kong插件使用Lua语言开发,基于OpenResty平台。开发插件前,你需要了解:
- Lua基础语法:变量、函数、表等
- Kong插件框架:生命周期、配置架构等
- OpenResty概念:请求处理阶段、共享内存等
插件结构
一个典型的Kong插件包含以下文件:
my-custom-plugin/├── handler.lua # 插件逻辑├── schema.lua # 配置验证└── api.lua # 管理API (可选)
创建你的第一个插件
让我们创建一个简单的插件,它会在响应头中添加一个自定义头部:
- 创建插件目录:
mkdir -p /usr/local/share/lua/5.1/kong/plugins/header-modifier
- 创建schema.lua:
-- schema.luareturn { name = "header-modifier", fields = { { config = { type = "record", fields = { { header_name = { type = "string", required = true } }, { header_value = { type = "string", required = true } } } }} }}
- 创建handler.lua:
-- handler.lualocal HeaderModifierHandler = {}
HeaderModifierHandler.PRIORITY = 1000HeaderModifierHandler.VERSION = "1.0.0"
function HeaderModifierHandler:header_filter(conf) kong.response.set_header(conf.header_name, conf.header_value)end
return HeaderModifierHandler
- 启用插件:
在Kong配置文件中添加:
plugins = bundled,header-modifier
- 应用插件:
curl -X POST http://localhost:8001/services/example-service/plugins \ --data "name=header-modifier" \ --data "config.header_name=X-Custom-Header" \ --data "config.header_value=Hello-World"
高级插件开发技巧
- 访问请求和响应:
-- 获取请求信息local host = kong.request.get_host()local headers = kong.request.get_headers()local query = kong.request.get_query()local body = kong.request.get_body()
-- 修改响应kong.response.set_status(200)kong.response.set_header("X-Custom", "value")
- 缓存和共享数据:
-- 使用Kong缓存local cache = kong.cachelocal value, err = cache:get("my_key", nil, function() -- 这个函数只在缓存未命中时执行 return "cached_value"end)
- 日志记录:
kong.log.info("这是一条信息日志")kong.log.err("这是一条错误日志")
- 错误处理:
return kong.response.exit(403, { message = "未授权访问" })
插件测试
测试是插件开发的重要部分:
-- spec/my-plugin/01-unit_spec.luadescribe("my-plugin", function() it("does something", function() -- 测试代码 assert.equal(1, 1) end)end)
运行测试:
bin/busted -v spec/my-plugin
Kong的认证体系:OAuth2、JWT等高级玩法
Kong提供了多种认证机制,从简单的API密钥到复杂的OAuth2流程。让我们深入了解这些高级认证方案。
OAuth 2.0
OAuth 2.0是一个授权框架,允许第三方应用获取对用户资源的有限访问权限。
配置OAuth 2.0插件
curl -X POST http://localhost:8001/services/example-service/plugins \ --data "name=oauth2" \ --data "config.scopes=email,profile" \ --data "config.mandatory_scope=true" \ --data "config.enable_authorization_code=true" \ --data "config.enable_client_credentials=true" \ --data "config.global_credentials=false"
创建OAuth应用
curl -X POST http://localhost:8001/consumers/example-user/oauth2 \ --data "name=My Application" \ --data "client_id=SOME-CLIENT-ID" \ --data "client_secret=SOME-CLIENT-SECRET" \ --data "redirect_uris=https://example.com/callback"
OAuth 2.0流程
- 授权码流程(最常用):
# 1. 重定向用户到授权页面https://kong:8443/oauth2/authorize?response_type=code&client_id=SOME-CLIENT-ID&scope=email&redirect_uri=https://example.com/callback
# 2. 用户授权后,使用授权码交换令牌curl -X POST https://kong:8443/oauth2/token \ --data "grant_type=authorization_code" \ --data "client_id=SOME-CLIENT-ID" \ --data "client_secret=SOME-CLIENT-SECRET" \ --data "code=AUTHORIZATION_CODE" \ --data "redirect_uri=https://example.com/callback"
- 客户端凭证流程(服务器间通信):
curl -X POST https://kong:8443/oauth2/token \ --data "grant_type=client_credentials" \ --data "client_id=SOME-CLIENT-ID" \ --data "client_secret=SOME-CLIENT-SECRET" \ --data "scope=email"
JWT认证
JWT(JSON Web Token)是一种紧凑的、自包含的方式,用于在各方之间安全地传输信息。
配置JWT插件
curl -X POST http://localhost:8001/services/example-service/plugins \ --data "name=jwt" \ --data "config.claims_to_verify=exp" \ --data "config.key_claim_name=kid"
为消费者创建JWT凭证
curl -X POST http://localhost:8001/consumers/example-user/jwt \ --data "algorithm=HS256" \ --data "key=my-key" \ --data "secret=my-secret"
使用JWT
- 生成令牌(使用第三方工具或库)
- 在请求中使用令牌:
curl -i http://localhost:8000/api \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
多因素认证
对于需要更高安全性的场景,可以组合多个认证插件:
# 首先应用基本认证curl -X POST http://localhost:8001/services/secure-service/plugins \ --data "name=basic-auth" \ --data "config.hide_credentials=true"
# 然后应用IP限制curl -X POST http://localhost:8001/services/secure-service/plugins \ --data "name=ip-restriction" \ --data "config.whitelist=192.168.1.1,192.168.1.2"
自定义认证逻辑
对于特殊的认证需求,可以开发自定义认证插件:
-- 自定义认证插件示例function CustomAuthHandler:access(conf) -- 获取认证头 local auth_header = kong.request.get_header("Authorization")
if not auth_header then return kong.response.exit(401, { message = "未授权" }) end
-- 自定义验证逻辑 if not is_valid_token(auth_header) then return kong.response.exit(403, { message = "无效令牌" }) end
-- 设置已认证的消费者 kong.service.request.set_header("X-Consumer-ID", consumer_id)end
微服务治理:服务发现、负载均衡、熔断降级
随着微服务架构的普及,API网关在服务治理中扮演着关键角色。Kong提供了多种工具来管理微服务生态系统。
服务发现
服务发现允许Kong动态找到上游服务的位置,而不需要硬编码IP地址。
使用DNS服务发现
curl -X POST http://localhost:8001/services \ --data "name=example-service" \ --data "host=example-service.internal" \ --data "port=80"
Kong会自动解析DNS记录,支持SRV和A记录。
集成Consul服务发现
使用Kong的Consul插件:
curl -X POST http://localhost:8001/services/example-service/plugins \ --data "name=consul" \ --data "config.host=consul.internal" \ --data "config.port=8500" \ --data "config.connect_timeout=1000" \ --data "config.register_service=true" \ --data "config.service_name=example-service"
负载均衡
Kong提供了多种负载均衡策略,帮助分配流量到多个上游实例。
上游配置
# 创建上游curl -X POST http://localhost:8001/upstreams \ --data "name=example-upstream"
# 添加目标curl -X POST http://localhost:8001/upstreams/example-upstream/targets \ --data "target=service1.internal:80" \ --data "weight=100"
curl -X POST http://localhost:8001/upstreams/example-upstream/targets \ --data "target=service2.internal:80" \ --data "weight=50"
# 使用上游curl -X POST http://localhost:8001/services \ --data "name=load-balanced-service" \ --data "host=example-upstream"
负载均衡算法
Kong支持多种负载均衡算法:
- 轮询(默认):依次将请求分配给每个目标
- 加权轮询:根据权重分配请求
- 一致性哈希:基于特定请求属性(如IP或头部)将相似请求发送到同一目标
curl -X PATCH http://localhost:8001/upstreams/example-upstream \ --data "hash_on=header" \ --data "hash_on_header=x-user-id" \ --data "hash_fallback=ip"
熔断与降级
熔断器模式可以防止级联故障,保护系统稳定性。
使用健康检查
curl -X PATCH http://localhost:8001/upstreams/example-upstream \ --data "healthchecks.active.healthy.interval=5" \ --data "healthchecks.active.healthy.successes=2" \ --data "healthchecks.active.unhealthy.interval=5" \ --data "healthchecks.active.unhealthy.http_failures=2" \ --data "healthchecks.active.type=http" \ --data "healthchecks.active.http_path=/health"
实现熔断
使用Kong的circuit-breaker插件(社区插件):
curl -X POST http://localhost:8001/services/example-service/plugins \ --data "name=circuit-breaker" \ --data "config.error_threshold=50" \ --data "config.window_size=10" \ --data "config.min_calls=5"
降级策略
当服务不可用时,可以使用request-termination插件提供降级响应:
curl -X POST http://localhost:8001/services/example-service/plugins \ --data "name=request-termination" \ --data "config.status_code=503" \ --data "config.message=服务暂时不可用,请稍后再试" \ --data "config.content_type=application/json"
结合Kong的路由优先级和条件逻辑,可以实现更复杂的降级策略。
Kong Gateway Enterprise:商业版的独特功能
Kong Gateway Enterprise是Kong的商业版本,提供了许多开源版本没有的高级功能。
开发者门户
开发者门户是一个自助服务平台,允许API消费者发现、测试和订阅API。
主要功能:
- API目录和文档
- 交互式API测试
- 自助服务注册和密钥管理
- 使用分析和报告
- 自定义品牌和主题
配置示例:
# 启用开发者门户curl -X PATCH http://localhost:8001/workspaces/default \ --data "config.portal=true" \ --data "config.portal_auto_approve=true"
# 发布服务到门户curl -X PATCH http://localhost:8001/services/example-service \ --data "tags=portal"
Kong Manager
Kong Manager是一个图形用户界面,用于管理Kong Gateway的所有方面。
主要功能:
- 服务、路由和插件管理
- 消费者和凭证管理
- 健康监控和警报
- 多工作区支持
- 基于角色的访问控制
Kong Vitals
Kong Vitals提供了关于API流量和性能的实时分析。
主要指标:
- 请求量和延迟
- 错误率和状态码分布
- 缓存命中率
- 按消费者、服务和路由的细分数据
启用Vitals:
# 在kong.conf中设置vitals = on
高级安全功能
OpenID Connect
企业版提供了完整的OpenID Connect实现:
curl -X POST http://localhost:8001/services/example-service/plugins \ --data "name=openid-connect" \ --data "config.issuer=https://auth.example.com" \ --data "config.client_id=YOUR_CLIENT_ID" \ --data "config.client_secret=YOUR_CLIENT_SECRET" \ --data "config.scopes=openid,email,profile"
高级速率限制
企业版提供了更强大的速率限制功能:
curl -X POST http://localhost:8001/services/example-service/plugins \ --data "name=rate-limiting-advanced" \ --data "config.limit=10" \ --data "config.window_size=60" \ --data "config.sync_rate=10" \ --data "config.namespace=example"
企业级插件
- Kafka日志:将日志发送到Kafka集群
- Vault:与HashiCorp Vault集成,安全存储敏感信息
- LDAP认证:与企业目录服务集成
- Canary Release:支持金丝雀发布和A/B测试
多工作区和团队
企业版支持多工作区,允许不同团队在同一Kong实例上独立工作:
# 创建新工作区curl -X POST http://localhost:8001/workspaces \ --data "name=team-a"
# 在特定工作区中创建服务curl -X POST http://localhost:8001/team-a/services \ --data "name=team-a-service" \ --data "url=http://team-a-backend.internal"
混合模式部署
企业版提供了更强大的混合模式部署支持:
控制平面 ←→ 数据平面1 ↘→ 数据平面2 ↘→ 数据平面3
这种架构允许集中管理配置,同时在多个数据中心部署数据平面节点。
小结与练习
在本章中,我们探索了Kong的高级功能:
- 自定义插件开发
- 高级认证机制
- 微服务治理工具
- Kong Gateway Enterprise的独特功能
练习
- 开发一个自定义插件,在请求头中添加当前时间戳
- 配置OAuth 2.0认证,并测试授权码流程
- 设置一个具有健康检查和负载均衡的上游服务
- 如果可能,尝试Kong Enterprise的开发者门户功能
在下一章中,我们将通过实际案例,将所学知识应用到真实场景中。
温馨提示:本教程是系列内容的一部分,请继续阅读下一章节,逐步掌握Kong的各项功能。