Kong API Gateway 落地 Kubernetes 实践(三):自定义插件

1,402 阅读3分钟

经过上一篇,加上自己尝试的话,基本上会对 Kong 插件的使用方式有个印象了。接下来,我们来说说自定义插件。

当现成的插件满足不了我们的需求,我们就要实现自己的插件,然后借这个机会,把整个自定义插件的开发,发布流程记录下。

资料

首先是基础的 Plugin Development GuidePlugin Development Kit,这两篇只是给了我们插件内部实现的文档。接着强烈推荐 Setting up custom plugin in Kubernetes environment,这篇特别适合不熟悉 lua 的开发者,其中也给了一个非常好的 demo 。

新插件代码

插件需求:我尝试使用 Kong Proxy Cache(请求缓存插件)后发现产生了一个疑问:缓存的命中率如何?

从监控上,我能看到所有请求的统计情况,但是我看不出有多少请求是命中了缓存的,可能是那些时延比较低的请求,但是不够精确和量化。我就想如果能在监控信息中夹带是否命中的数据,那么在监控展示时,根据这个数据过滤,然后就能得到准确的命中率了。

插件实现思路:观察 Kong grafana 监控,我们注意到请求的监控数据条目是 kong_http_status。直接的想法是,要是在这个 Prometheus 条目上增加名为 “cache” 的 tag 就好了。

然后我们顺着这个想法找到 Prometheus Plugin 源码,修改源码,详见:github.com/yuyulei/blo…

我们主要改动的地方有:

  • 修改 plugin 的命名,一定要跟原来不一样。
// in handler.lua file

-- local prometheus = require "kong.plugins.prometheus.exporter"
local prometheus = require "kong.plugins.caoliao-prometheus.exporter"
  • 增加自定义 tag: cache。
  metrics.status = prometheus:counter("http_status",
        "HTTP status codes per service/route in Kong",
        -- {"service", "route", "code"})
        {"service", "route", "code", "cache"})
    labels_table[4] = "Unknown"
    if message.response.headers["x-cache-status"] then 
      labels_table[4] = message.response.headers["x-cache-status"]
    end

我们在这里需要注意的是:插件的执行顺序。根据我们的需求,监控插件需要判断出哪些请求命中了缓存,哪些没有命中,所以必须安排在缓存插件之后执行。

简单解释下 HTTP header: x-cache-status。该 header 是经过缓存插件后附加到 response Header 上。其中取值有:Hit(命中),Miss(未命中),Bypass(不考虑缓存),Refresh(缓存超时)。我们不在乎具体取值是什么,如果发现 header 中有 “x-cache-status” ,就在该请求的监控条目中设置 cache tag。

集成新插件

我们接下来需要将新插件集成到 Kong 网关中。我觉得,在 Kong Ingress Controller(K8s 集群)环境下集成插件比原生 Kong 环境更方便。

先将代码以 configMap 的形式录入到 K8s 集群,

kubectl create cm kong-plugin-caoliao-prometheus --from-file=caoliao-prometheus -n kong

然后修改 KIC deployment,

      - env:
        - name: KONG_PLUGINS
          value: bundled,caoliao-prometheus
        - name: KONG_LUA_PACKAGE_PATH
          value: /opt/?.lua;;

        volumeMounts:
        - mountPath: /opt/kong/plugins/caoliao-prometheus
          name: kong-plugin-caoliao-prometheus

      volumes:
        - configMap:
            name: kong-plugin-caoliao-prometheus
          name: kong-plugin-caoliao-prometheus

如上如升级网关即可。

监控展示

设计 3 条 Metrics Query,分别是命中缓存的请求 RPS,总请求 RPS 以及命中率。

61bqNd.md.jpg

总结

我们通过小小修改了 Kong Prometheus Plugin 源码,走完了自定义插件从开发到集成发布的全过程。Kong 的很多插件,我们都是可以找到源码的,如果是和我一样不熟悉 lua 的开发者,我建议优先考虑在源码的基础上改进,而不要自己造轮子。

另外,Kong 还支持 golang 插件,有机会我也想尝试下。