API网关Kong学习笔记(二十四):在kubernetes中启用kong的插件

作者:李佶澳  更新时间:2019-05-20 14:50:16 +0800

  项目    kong    刷新

目录

说明

之前整理过插件的用法:基本使用方法认证插件安全插件。这里试验一下其它的插件。

注意这里使用的kong是1.0.3,之前使用的是0.14.1,有些插件的配置发生了变化,例如IP黑白名单插件ip-restriction中的IP列表,以前是用“,”间隔的字符串,现在是数组。

插件的启用方法和作用范围没有变,Kong Custom Resource Definitions:

  1. 全局插件,global: “true”,设置为启用后,对所有请求进行处理;

  2. 局部插件,global: “false”,设置为启用后,在ingress中用annotations绑定;

  3. 全局插件可以在任意namespace中创建,为了管理方便建议和kong-ingress-controller放在同一个namespace中,局部插件需要和用到它的ingress或者service在同一个namespaces中;

  4. 局部插件覆盖全局插件

相关笔记

2019-05-06 16:28:56:kong 1.1.x有了一个重大变换,实现了db-less模式,可以不使用数据库了,见笔记二十六:查看全部笔记如果是刚开始学习kong,直接从1.x开始,0.x已经不再维护,0.15是0.x的最后一个版本。

前19篇笔记是刚开始接触kong时记录的,使用的版本是0.14.1,当时对kong一知半解,笔记比较杂乱。第二十篇开始是再次折腾时的笔记,使用的版本是1.0.3,笔记相对条理一些。

从0.x到1.x需要关注的变化有:

  1. 插件全部使用pdk
  2. 0.x中不鼓励使用的特性都被移除了;
  3. 全部使用kong.db,以前独立的dao彻底清除,代码简洁清晰了。

日志插件

file-log,在kubernetes中创建KongPlugin:

apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: echo-file-log
  namespace: demo-echo
  labels:
    global: "false"
disabled: false  # optional
plugin: file-log
config:
  path: /tmp/req.log
  reopen: true
$ ./kubectl.sh -n demo-echo get kp -o wide
NAME                  PLUGIN-TYPE      AGE   DISABLED   CONFIG
echo-file-log         file-log         1m    false      map[path:/tmp/req.log reopen:true]

在ingress中设置绑定:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    plugins.konghq.com: echo-file-log
  ...

发起请求后,可以带对应的kong中看到日志:

sh-4.2# ls /tmp/
ks-script-h2MyUP  req.log  yum.log
sh-4.2# cat /tmp/req.log
{"latencies":{"request":8,"kong":6,"proxy":2},"service":{"host":"demo-echo.echo.80","created_at"
:1552460203,"connect_timeout":60000,....

日志格式见kong plugin: file-log

关联ID

correlation-id,在kubernetes中创建KongPlugin:

apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: echo-correlation-id
  namespace: demo-echo
  labels:
    global: "false"
disabled: false  # optional
plugin: correlation-id
config:
  header_name: kong-correlation-id
  generator: uuid
  echo_downstream: true
$ ./kubectl.sh -n demo-echo get kp -o wide
echo-correlation-id   correlation-id   22s   false      map[echo_downstream:true generator:uuid#counter header_name:kong-correlation-id]

在ingress中设置绑定:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    plugins.konghq.com: echo-correlation-id

发起请求,可以看到请求头增加了一个关联ID:

$ curl   -H "host: echo.com"  -H "User-Agent: curl/7.54.1"  10.10.64.58:8000
...
Request Headers:
	accept=*/*
	connection=keep-alive
	host=172.16.129.47:8080
	kong-correlation-id=1d1a97d3-13af-4ec0-8462-f63757c8ec00
	user-agent=curl/7.54.1
	x-forwarded-for=10.255.3.1
	x-forwarded-host=echo.com
	x-forwarded-port=8000
	x-forwarded-proto=http
	x-real-ip=10.255.3.1
...

监控数据

prometheus,在kubernetes中创建KongPlugin:

apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: echo-prometheus
  namespace: demo-echo
  labels:
    global: "false"
disabled: false  # optional
plugin: prometheus
$ ./kubectl.sh -n demo-echo get kp -o wide
echo-prometheus       prometheus       4s    false

在ingress中设置绑定:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    plugins.konghq.com: echo-prometheus

然后访问kong的admin接口IP:admin端口/metrics,注意必须是用admin端口,并且只能获取经过当前的kong处理的请求的数据。

在部署的时候,一般是把kong的管理平面和数据平面严格分开:管理平面的kong只开启管理端口,不处理数据请求;数据平面的kong只开放数据端口,admin端口不开启。 但这样就无妨从数据平面获取prometheus格式的监控数据,可以在数据平面的kong的配置文件nginx-kong.conf中添加下面代码,暴露一个专门提供监控数据的端口:

server {
    server_name kong_prometheus_exporter;
    listen 0.0.0.0:9542; # can be any other port as well

    location / {
        default_type text/plain;
        content_by_lua_block {
            local serve = require "kong.plugins.prometheus.serve"
            serve.prometheus_server()
        }
    }
}

也可以加载nginx模板中,默认的template是kong/templates中的nginx.luanginx_kong.lua,直接修改这两个文件也是比较方便的做法。

然后直接访问数据平面的”IP:9542/metrics”:

$ curl 127.0.0.1:9542/metrics
# HELP kong_bandwidth Total bandwidth in bytes consumed per service in Kong
# TYPE kong_bandwidth counter
kong_bandwidth{type="egress",service="demo-echo.echo.80"} 923
kong_bandwidth{type="ingress",service="demo-echo.echo.80"} 71
# HELP kong_datastore_reachable Datastore reachable from Kong, 0 is unreachable
# TYPE kong_datastore_reachable gauge
kong_datastore_reachable 1
# HELP kong_http_status HTTP status codes per service in Kong
# TYPE kong_http_status counter
kong_http_status{code="200",service="demo-echo.echo.80"} 1
# HELP kong_latency Latency added by Kong, total request time and upstream latency for each service in Kong
# TYPE kong_latency histogram
kong_latency_bucket{type="kong",service="demo-echo.echo.80",le="00025.0"} 1
kong_latency_bucket{type="kong",service="demo-echo.echo.80",le="00030.0"} 1
kong_latency_bucket{type="kong",service="demo-echo.echo.80",le="00040.0"} 1
kong_latency_bucket{type="kong",service="demo-echo.echo.80",le="00050.0"} 1
kong_latency_bucket{type="kong",service="demo-echo.echo.80",le="00060.0"} 1
kong_latency_bucket{type="kong",service="demo-echo.echo.80",le="00070.0"} 1
...

如果出错在error.log中有下日志:

2019/03/19 15:27:48 [error] 1217#1217: *100 lua entry thread aborted: runtime error: /usr/share/lua/5.1/kong/plugins/prometheus/serve.lua:3: module 'kong.tools.responses' not found:No LuaRocks module found for kong.tools.responses
no field package.preload['kong.tools.responses']
no file '/usr/lib64/lua/5.1/kong/tools/responses.lua'
no file '/usr/lib64/lua/5.1/kong/tools/responses/init.lua'
...

可能是因为系统上安装的kong-plugin-promethues版本太旧,依赖版本在kong1.0.3的kong-1.0.3-0.rockspec文件中设置,修改一些版本譬如0.3.2然后重新安装make install:

"kong-prometheus-plugin ~> 0.3",

我遇到了系统上kong-plugin-promethues代码和kong不匹配的问题,但是把kong-prometheus-plugin调整到0.3.2,重新安装之后在改回0.3,并将插件删除重新安装后,发现安装的代码是匹配的,问题没有复现,比较蹊跷。

IP黑白名单

IP Restriction

从echo服务的返回内容中找到kong看到的客户端IP10.255.3.1

$ curl   -H "host: echo.com"  -H "User-Agent: curl/7.54.1"  10.10.64.58:8000/

Request Headers:
	accept=*/*
	connection=keep-alive
	host=172.16.129.47:8080
	kong-correlation-id=eb885d41-dc67-4169-a3c4-6f27f4207d90#2
	user-agent=curl/7.54.1
	x-forwarded-for=10.255.3.1
	x-forwarded-host=echo.com
	x-forwarded-port=8000
	x-forwarded-proto=http
	x-real-ip=10.255.3.1

在kubernetes中创建KongPlugin:

apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: echo-ip-restriction
  namespace: demo-echo
disabled: false  # optional
plugin: ip-restriction
config:
#   whitelist:     # 黑名单和白名单只能选一
  blacklist: [1.1.1.1,10.255.3.1]
$ ./kubectl.sh -n demo-echo get kp -o wide
echo-ip-restriction   ip-restriction   4d    false      map[blacklist:[1.1.1.1 10.255.3.1]]

在ingress中设置绑定:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    plugins.konghq.com: echo-ip-restriction
...

这时候再访问,发现被禁止访问:

$ curl   -H "host: echo.com"  -H "User-Agent: curl/7.54.1"  10.10.64.58:8000/
{"message":"Your IP address is not allowed"}%

请求速率限制

rate-limiting,在kubernetes中创建KongPlugin:

apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: echo-req-rate-limit
  namespace: demo-echo
  labels:
    global: "false"
disabled: false  # optional
plugin: rate-limiting
config:
  second: 1
  limit_by: ip
  policy: local  #local,cluster,redis
$ ./kubectl.sh -n demo-echo get kp -o wide
echo-req-rate-limit   rate-limiting    8s    false      map[limit_by:ip policy:local second:1]

在ingress中设置绑定:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    plugins.konghq.com: echo-req-rate-limit
...

这时候频繁发起请求会发现,超过速率限制后,被限制访问:

$ curl -v  -H "host: echo.com"  -H "User-Agent: curl/7.54.1"  10.10.64.58:8000/
*   Trying 10.10.64.58...
* TCP_NODELAY set
* Connected to 10.10.64.58 (10.10.64.58) port 8000 (#0)
> GET / HTTP/1.1
> host: echo.com
> Accept: */*
> User-Agent: curl/7.54.1
>
< HTTP/1.1 429 Too Many Requests
< Date: Tue, 19 Mar 2019 09:19:41 GMT
< Content-Type: application/json; charset=utf-8
< Connection: keep-alive
< Content-Length: 37
< X-RateLimit-Remaining-second: 0
< X-RateLimit-Limit-second: 1
< Server: kong/1.0.3
<
* Connection #0 to host 10.10.64.58 left intact
{"message":"API rate limit exceeded"}%

调用链路跟踪

部署一个单机版的Zipkin

docker run -d -p 9411:9411 openzipkin/zipkin

在浏览器用地址http://IP:9411/zipkin/查看zipkin中的数据。

Zipkin,在kubernetes中创建KongPlugin:

apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: echo-http-zipkin-trace
  namespace: demo-echo
  labels:
    global: "false"
enabled: true  # optional
plugin: zipkin
config:
  http_endpoint: "http://10.10.173.203:9411/api/v2/spans"
  sample_ratio: 1  # 不带tracid的请求的采样比率,1是100%,全部采集
$ ./kubectl.sh -n demo-echo get kp -o wide
echo-http-zipkin-trace   zipkin   8s   map[http_endpoint:http://10.10.173.203:9411/api/v2/spans sample_ratio:1]

在ingress中设置绑定:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    plugins.konghq.com: echo-http-zipkin-trace
...

这时候发起请求,会发现kong在请求头中打上了tarceid和spanid,x-b3-parentspanid、x-b3-spanid、x-b3-traceid、x-b3-sampled:

$ curl -H "host: echo.com"  -H "User-Agent: curl/7.54.1"  10.10.64.58:8000/ddddddd
...
Request Headers:
	accept=*/*
	connection=keep-alive
	host=172.16.129.47:8080
	kong-correlation-id=4f34701a-fb47-4ee1-8884-657130b4353a#10
	user-agent=curl/7.54.1
	x-b3-parentspanid=e357326aaa445213
	x-b3-sampled=0
	x-b3-spanid=98cffa4b4f60b8c5
	x-b3-traceid=ddda77bee1ef08eb686ca5006aa8b3a0
	x-forwarded-for=10.255.3.1
	x-forwarded-host=echo.com
	x-forwarded-port=8000
	x-forwarded-proto=http
	x-real-ip=10.255.3.1
...

这里直接用curl发起的请求是没有自带traceID的,kong在转发的请求的时候会设置traceID。因为对于这种不带traceID的请求,前面配置的采样比是1,所以每个请求的信息都被发送到了zipkin。

在zipkin中能看到下面的信息:

用zipkin查看kong的调用链延迟信息

参考

  1. Kong Custom Resource Definitions
  2. kong plugin: file-log
  3. kong plugins

站长微信(朋友圈有精华,一般不闲聊)

推荐阅读

Copyright @2011-2019 All rights reserved. 转载请添加原文连接,合作请加微信lijiaocn或者发送邮件: [email protected],备注网站合作

友情链接:  李佶澳的博客  小鸟笔记  软件手册  编程手册  运营手册  爱马影视  网络课程  奇技淫巧  课程文档  精选文章  发现知识星球  百度搜索 谷歌搜索