KubeSphere默认使用Kubernetes社区提供的Nginx Ingress做为网关,可以对Http流量进行路由分发,实现外部流量进入集群的功能。但是如果要使用更高级的功能时,仍然显得不足。如GRPC功能的支持、Jwt安全组件的使用、通过网关提供熔断限流的功能等。

此时可以借助于Kong网关插件,可以与KubeSphere平台无缝连接使用,极大地满足了不同场景使用需求。

通过helm安装

$ helm repo add kong https://charts.konghq.com
$ helm repo update

# Helm 3
$ helm install kong/kong --generate-name --set ingressController.installCRDs=false

检查Pod运行正常

➜  ~ k get po
NAME                                    READY   STATUS    RESTARTS   AGE
kong-1614586361-kong-79d4d8b794-2wrnf   2/2     Running   0          17h
➜  ~ k get svc
NAME                         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
kong-1614586361-kong-proxy   NodePort    10.233.19.226   <none>        80:30615/TCP,443:32362/TCP   17h

访问kong svc,因未配置路由,404

➜  ~ curl -I ssa3:30615

HTTP/1.0 404 Not Found
Date: Tue, 02 Mar 2021 01:33:24 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 48
X-Kong-Response-Latency: 0
Server: kong/2.2.1
Connection: close

部署echo-server作为负载,用于测试

$ kubectl apply -f https://bit.ly/echo-service
service/echo created
deployment.apps/echo created

配置路由

在KubeSphere的界面上添加Router

添加上Router后,默认会使用Nginx Ingress;

加上Annotation,使用Kong网关:

kubernetes.io/ingress.class: kong

根据路由来访问,正确实现路由功能

➜  ~ curl ssa3:30615/foo


Hostname: echo-85fb7989cc-9dcjt

Pod Information:
	node name:	ssa3
	pod name:	echo-85fb7989cc-9dcjt
	pod namespace:	kong
	pod IP:	10.233.64.120

Server values:
	server_version=nginx: 1.12.2 - lua: 10010

Request Information:
	client_address=10.233.64.119
	method=GET
	real path=/foo
	query=
	request_version=1.1
	request_scheme=http
	request_uri=http://ssa3:8080/foo

Request Headers:
	accept=*/*
	connection=keep-alive
	host=ssa3:30615
	user-agent=curl/7.64.1
	x-forwarded-for=10.233.64.1
	x-forwarded-host=ssa3
	x-forwarded-path=/foo
	x-forwarded-port=80
	x-forwarded-proto=http
	x-real-ip=10.233.64.1

Request Body:
	-no body in request-

使用Kong的插件来实现限流

Kong通过kongplugin CRD来实现插件的功能。

定义一个限流插件:

规则:一分钟只允许访问5次

$ echo "
apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: rl-by-ip
config:
  minute: 5
  limit_by: ip
  policy: local
plugin: rate-limiting
" | kubectl apply -f -
kongplugin.configuration.konghq.com/rl-by-ip created

插件定义好后,有两种方式使用该插件:

  • 给 Ingress打annotation
  • 给service打annotation

给service打上该annotaton:

➜  ~ k annotate svc/echo konghq.com/plugins=rl-by-ip
service/echo annotated

访问时,可以看到限流信息: 在最近一分钟里,已经访问1次,剩余4次

➜  ~ curl -I ssa3:30615/foo
HTTP/1.0 200 OK
Content-Type: text/plain; charset=UTF-8
Date: Tue, 02 Mar 2021 02:15:06 GMT
Server: echoserver
X-RateLimit-Remaining-Minute: 4
X-RateLimit-Limit-Minute: 5
RateLimit-Remaining: 4
RateLimit-Limit: 5
RateLimit-Reset: 54
X-Kong-Upstream-Latency: 1
X-Kong-Proxy-Latency: 1
Via: kong/2.2.1
Connection: close

多次访问后,访问拒绝

返回429状态码,“Too Many Requests”

➜  ~ curl -I ssa3:30615/foo
HTTP/1.0 429 Too Many Requests
Date: Tue, 02 Mar 2021 02:15:20 GMT
Content-Type: application/json; charset=utf-8
Retry-After: 40
Content-Length: 41
X-RateLimit-Remaining-Minute: 0
X-RateLimit-Limit-Minute: 5
RateLimit-Remaining: 0
RateLimit-Limit: 5
RateLimit-Reset: 40
X-Kong-Response-Latency: 1
Server: kong/2.2.1
Connection: close

限流功能正常。

总结

Kong网关有丰富的社区

Kong网关提供商业付费版,及免费开源社区版。

项目地址:https://github.com/Kong/kubernetes-ingress-controller

文档: https://docs.konghq.com/kubernetes-ingress-controller/1.1.x/deployment/k4k8s/

更多插件: https://docs.konghq.com/kubernetes-ingress-controller/1.1.x/guides/getting-started/

Zack 更新太快了,学不动了 🤣

你好,请问这种方案下,KubeSphere界面上应该是看不到的kong的域名和端口的吧?只能通过命令行查看?

界面上不会直接显示域名和端口;Kong Service是NodePort的,通过节点IP来访问。