插件介绍
kong内部使用openrestry作为反向代理,其可通过lua扩展nginx功能,官方已编写了大量的插件,如用于限流处理的Rate Limiting插件,用于IP黑白名单限制的IP Restriction插件,更多插件详见Kong Hub插件中心。
测试用例
测试用例1
echo测试用例可以返回服务器与客户端访问信息,便于我们调试并观察。
% kubectl create namespace demo
% kubectl run echo --image=googlecontainer/echoserver:1.10
% kubectl expose deploy echo --port=8080 --target-port=8080
% kubectl create -f - <
访问测试:
% kubectl get ing echo
NAME HOSTS ADDRESS PORTS AGE
echo * 134.194.18.11 80 1m
% curl 134.194.18.11:30569/echo
...
Request Information:
client_address=10.128.2.246
method=GET
real path=/
query=
request_version=1.1
request_scheme=http
request_uri=http://134.194.18.11:8080/
Request Headers:
accept=*/*
connection=keep-alive
host=134.194.18.11:30569
user-agent=curl/7.29.0
x-forwarded-for=10.131.2.1
x-forwarded-host=134.194.18.11
x-forwarded-port=8000
x-forwarded-proto=http
x-real-ip=10.131.2.1
...
测试用例2
httpbin测试用例主要用于观察http header头部响应信息,使用如下命令创建:
% kubectl run httpbin --image=kennethreitz/httpbin
% kubectl expose deploy httpbin --port=80
% kubectl apply -f - <
访问测试:
% kubectl get ing httpbin
NAME HOSTS ADDRESS PORTS AGE
httpbin * 134.194.18.11 80 1m
% curl -I 134.194.18.11:30569/bar/status/200
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
Server: gunicorn/19.9.0
Date: Mon, 23 Sep 2019 09:50:56 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-Kong-Upstream-Latency: 3
X-Kong-Proxy-Latency: 1
Via: kong/1.3.0
使用插件
注意:Kong插件可设置在Service、Ingress(Route)、Global(全局)上。
在Service处设置插件
注意:本节使用rate-limiting插件来做访问限流处理,如示例限制每IP每分钟只能进行5次访问。
通过CRD:KongPlugin创建一个rate-limiting的插件。注意:因示例以db-less模式安装kong,故policy需设置为local。
% kubectl apply -f - <
更新Service添加plugins.konghq.com注释:
% kubectl patch svc httpbin \
-p '{"metadata":{"annotations":{"plugins.konghq.com": "rl-by-ip\n"}}}'
% kubectl get svc echo -o yaml|more
...
apiVersion: v1
kind: Service
metadata:
annotations:
plugins.konghq.com: |
rl-by-ip
...
访问测试:
## 通过ingress访问:
# 连续访问5次:
% curl -I 134.194.18.11:30569/bar/status/200
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
Server: gunicorn/19.9.0
Date: Tue, 24 Sep 2019 02:26:11 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
X-RateLimit-Limit-minute: 5 # 每分钟允许访问5次
X-RateLimit-Remaining-minute: 0 # 剩余可访问次数为0
X-Kong-Upstream-Latency: 2
X-Kong-Proxy-Latency: 0
Via: kong/1.3.0
# 后续访问失败
% curl -I 134.194.18.11:30569/bar/status/200
HTTP/1.1 429 Too Many Requests # 访问失败
Date: Tue, 24 Sep 2019 02:26:12 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-Length: 37
X-RateLimit-Limit-minute: 5
X-RateLimit-Remaining-minute: 0
Server: kong/1.3.0
## 通过svc访问:
# 不经过ingress,通过svc访问无限流:
% curl -I httpbin.demo.svc.cluster.local/status/200
HTTP/1.1 200 OK
Server: gunicorn/19.9.0
Date: Tue, 24 Sep 2019 02:28:55 GMT
Connection: keep-alive
Content-Type: text/html; charset=utf-8
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Content-Length: 0
注意:
- 在service上添加plugins.konghq.com注释后,kong ingress control会动态更新kong网关,而后kong插件在ingress处得以实施,其不影响service访问;
- 对于rate-limiting插件,以db-less模式部署时其计数信息存储在内存中,故若部署多个kong实例的话,每实例对于计数信息是独占的,故对于限流处理是不严格的,详情参考官方手册;
- 本例是通过NodePort方式暴露kong网关供集群外访问,故kong网关所面对的真实客户端IP可能是非我们所预期的。如使用OKD的redhat/openshift-ovs-networkpolicy网络插件,kong网关所见的是真实客户端IP为节点上tun0的IP地址,此时不论从哪个客户端访问服务,其共享限流处理,一个解决方法是通过HostNetwork方式将kong暴露到集群外部;
# 使用echo应用来验证以上所述,如从任何客户端访问此地址可发现真实IP均为主机上的tun0网卡IP
% curl 134.194.18.11:30569/echo
...
Request Headers:
accept=*/*
connection=keep-alive
host=134.194.18.11:30569
user-agent=curl/7.29.0
x-forwarded-for=10.131.2.1 # 应用所见到的真实客户端IP地址
x-forwarded-host=134.194.18.11
x-forwarded-port=8000
x-forwarded-proto=http
x-real-ip=10.131.2.1 # 应用所见到的真实客户端IP地址
...
% ip a|grep 10.131.2.1
inet 10.131.2.1/23 brd 10.131.3.255 scope global tun0
在Ingress处设置插件
本节使用IP Restriction对客户端做IP白名单访问限制。
如上所见,通过NodePort暴露的kong网关,其面对的客户端IP地址为每K8S节点上的tun0网卡地址,故此时对IP做黑白名单访问限制并非如我们预期的那样,但对于本文来说,重点不在此插件用途上。
如下限制仅可通过134.194.18.11这台主机访问httpdbin服务,创建插件如下所示。注意:此处白名单IP地址为tun0网卡上的地址。
% kubectl apply -f - <
上节在Service处添加了插件注释,此处将在Ingress处添加插件注释:
% kubectl patch ing httpbin \
-p '{"metadata":{"annotations":{"plugins.konghq.com": "ip-restriction\n"}}}'
最后,通过不同的节点访问可发现仅能从134.194.18.11访问:
# 可访问
% curl -I 134.194.18.11:30569/bar/status/200
HTTP/1.1 200 OK
...
# 被墙,无法访问
% curl -I 134.194.18.9:30569/bar/status/200
HTTP/1.1 403 Forbidden
配置Global全局插件
全局插件影响kong网关上的所有服务,如下配置全局插件对所有API做限流处理。
% kubectl apply -f - <
上面已在httpbin的service做了每分钟5次限流处理,而echo并为做任何限流处理,此时访问观察可有如下发现:
# 全局策略在echo ingress上生效:
% curl -I 134.194.18.11:30569/echo
...
X-RateLimit-Limit-minute: 150
X-RateLimit-Remaining-minute: 149
...
# 全局策略优先级较低,故在ingress、service上设置的同类型插件优先级高。
% curl -I 134.194.18.11:30569/bar/status/200
...
X-RateLimit-Limit-minute: 5
X-RateLimit-Remaining-minute: 4
...
参考文档
- kong插件中心:https://docs.konghq.com/hub/;
- kubernetes-ingress-controller文档:https://github.com/Kong/kuber...;
- using-kongplugin-resource.md:https://github.com/Kong/kuber...;