1、Kong的概述
Kong是一个clould-native、快速的、可扩展的、分布式的微服务抽象层(也称为API网关、API中间件或在某些情况下称为服务网格)框架。Kong作为开源项目在2015年推出,它的核心价值是高性能和可扩展性。Kong被广泛用于从初创企业到全球5000家公司以及政府组织的生产环境中。
如果构建Web、移动或IoT(物联网)应用,可能最终需要使用通用的功能来实现这些应用。Kong充当微服务请求的网关(或侧车),通过插件能够提供负载平衡、日志记录、身份验证、速率限制、转换等能力。
2、功能特性
- 云本土化(Cloud-Native):Kong可以在Kubernetes或物理环境上运行;
- 动态负载平衡(Dynamic Load Balancing):跨多个上游服务的负载平衡业务。
- 基于哈希的负载平衡(Hash-based Load Balancing):一致的散列/粘性会话的负载平衡。
- 断路器(Circuit-Breaker):智能跟踪不健康的上游服务。
- 健康检查(Health Checks):主动和被动监控您的上游服务。
- 服务发现(Service Discovery):解决如Consul等第三方DNS解析器的SRV记录。
- 无服务器(Serverless):从Kong中直接调用和保证AWS或OpenWhisk函数安全。
- WebSockets:通过WebSockets与上游服务进行通信。
- OAuth2.0:轻松的向API中添加OAuth2.0认证。
- 日志记录(Logging):通过HTTP、TCP、UDP记录请求或者相应的日志,存储在磁盘中。
- 安全(Security):ACL,Bot检测,IPs白名单/黑名单等。
- 系统日志(Syslog):记录信息到系统日志。
- SSL:为基础服务或API设置特定的SSL证书。
- 监视(Monitoring):能够实时对关键负载和性能指标进行监控。
- 转发代理(Forward Proxy):使端口连接到中间透明的HTTP代理。
- 认证(Authentications):支持HMAC,JWT和BASIC方式进行认证等等。
- 速率限制(Rate-limiting):基于多个变量的阻塞和节流请求。
- 转换(Transformations):添加、删除或操作HTTP请求和响应。
- 缓存(Caching):在代理层进行缓存和服务响应。
- 命令行工具(CLI):能够通过命令行控制Kong的集群。
- REST API:可以通过REST API灵活的操作Kong。
- GEO复制:在不同的区域,配置总是最新的。
- 故障检测与恢复(Failure Detection & Recovery):如果Cassandra节点失效,Kong并不会受影响。
- 群集(Clustering):所有的Kong节点会自动加入群集,并更新各个节点上的配置。
- 可扩展性(Scalability):通过添加节点,实现水平缩放。
- 性能(Performance):通过缩放和使用Nigix,Kong能够轻松处理负载。
- 插件(Plugins):基于插件的可扩展体系结构,能够方便的向Kong和API添加功能。
3、使用Helm在Kubernetes上部署Kong
3.1 前置条件
- 已有Kubernetes 1.6+环境;
- 已部署helm客户端和tiller服务端(请参考:docs.helm.sh/using_helm/…):
- 在Kubernetes中创建了具备足够权限访问权限的service account;
- 并通过此service account在Kubernetes部署了tiller服务端(请参考:docs.helm.sh/using_helm/…)。
3.2 Helm char配置
| 参数 | 说明 | 默认值 |
|---|---|---|
| image.repository | Kong image | kong |
| image.tag | Kong image version | 0.14.1 |
| image.pullPolicy | Image pull policy | IfNotPresent |
| image.pullSecrets | Image pull secrets | null |
| replicaCount | Kong instance count | 1 |
| admin.useTLS | Secure Admin traffic | true |
| admin.servicePort | TCP port on which the Kong admin service is exposed | 8444 |
| admin.containerPort | TCP port on which Kong app listens for admin traffic | 8444 |
| admin.nodePort | Node port when service type is NodePort |
|
| admin.type | k8s service type, Options: NodePort, ClusterIP, LoadBalancer | NodePort |
| admin.loadBalancerIP | Will reuse an existing ingress static IP for the admin service | null |
| admin.loadBalancerSourceRanges | Limit admin access to CIDRs if set and service type is LoadBalancer |
[] |
| admin.ingress.enabled | Enable ingress resource creation (works with proxy.type=ClusterIP) | false |
| admin.ingress.tls | Name of secret resource, containing TLS secret | |
| admin.ingress.hosts | List of ingress hosts. | [] |
| admin.ingress.path | Ingress path. | / |
| admin.ingress.annotations | Ingress annotations. See documentation for your ingress controller for details | {} |
| proxy.useTLS | Secure Proxy traffic | true |
| proxy.servicePort | TCP port on which the Kong Proxy Service is exposed | 8443 |
| proxy.containerPort | TCP port on which the Kong app listens for Proxy traffic | 8443 |
| proxy.nodePort | Node port when service type is NodePort |
|
| proxy.type | k8s service type. Options: NodePort, ClusterIP, LoadBalancer | NodePort |
| proxy.loadBalancerSourceRanges | Limit proxy access to CIDRs if set and service type is LoadBalancer |
[] |
| proxy.loadBalancerIP | To reuse an existing ingress static IP for the admin service | |
| proxy.ingress.enabled | Enable ingress resource creation (works with proxy.type=ClusterIP) | false |
| proxy.ingress.tls | Name of secret resource, containing TLS secret | |
| proxy.ingress.hosts | List of ingress hosts. | [] |
| proxy.ingress.path | Ingress path. | / |
| proxy.ingress.annotations | Ingress annotations. See documentation for your ingress controller for details | {} |
| env | Additional Kong configurations | |
| runMigrations | Run Kong migrations job | true |
| readinessProbe | Kong readiness probe | |
| livenessProbe | Kong liveness probe | |
| affinity | Node/pod affinities | |
| nodeSelector | Node labels for pod assignment | {} |
| podAnnotations | Annotations to add to each pod | {} |
| resources | Pod resource requests & limits | {} |
| tolerations | List of node taints to tolerate | [] |
3.3 安装Chart
通过执行如下的命令,在Kubernetes中部署Kong:
$ helm install --name my-release stable/kong
3.4 验证Kong(命令行)
通过执行下面的命令,进入Kong的容器:
kubectl exec -it my-release-kong-d448dc869-fblbk sh
并在kong中执行如下的命令:
curl http://localhost:8001
如果kong正常运行的话,应该会返回一些内容。
3.5 验证Kong(客户端)
另外,也可以安装一个Kong的客户端来验证。在安装有Docker引擎的操作系统上执行如下的命令:
docker run -d -p 8080:8080 pgbi/kong-dashboard start --kong-url http://10.0.32.172:31177
通过docker安装一个Kong-Dashboard,安装完成后,通过浏览器访问:

4、使用
在此部分将会向kong添加一个API,为了做到这一点,首先需要往Kong中添加一个服务。我们将创建一个指向Mockbin API的服务,Mockbin是一个“echo”类型的公共网站,它将返回的请求作为响应返回给请求者。通过此示例有助于了解Kong是如何代理API请求。在开始对服务进行请求之前,需要为服务添加一个路由。路由指定在到达Kong之后如何向服务发送请求,单个服务可以有多个路由。在配置了服务和路由之后,就能够通过Kong对服务进行请求。Kong公开了RESTful Admin API:8001,Kong的配置(包括添加服务和路由)是通过对该API的请求进行的。
4.1 注册服务
服务实体是上游服务中的每一个抽象。服务的示例将是数据转换微服务、计费API等。服务的主要属性是它的URL(其中Kong应该代理流量),它可以被设置为单个字符串或单独指定它的协议、主机、端口和路径。
通过执行下面的命令,将名称为example-servic,地址为url=http://mockbin.org的服务注册到Kong上。
$ curl -i -X POST \
--url http://localhost:8001/services/ \
--data 'name=example-service' \
--data 'url=http://mockbin.org'
执行命令后,返回的结果类似下面的内容:
HTTP/1.1 201 Created
Content-Type: application/json
Connection: keep-alive
{
"host":"mockbin.org",
"created_at":1519130509,
"connect_timeout":60000,
"id":"92956672-f5ea-4e9a-b096-667bf55bc40c",
"protocol":"http",
"name":"example-service",
"read_timeout":60000,
"port":80,
"path":null,
"updated_at":1519130509,
"retries":5,
"write_timeout":60000
}
4.2 创建路由
路由实体定义用来匹配客户端请求的规则。每个路由都与一个服务相关联,并且一个服务可能具有与其相关的多个路由。匹配给定路由的每个请求都将被代理到其关联的服务。通过路由和服务的组合(以及它们之间的关注点分离)提供了强大的路由机制,通过这种机制,可以在Kong中定义细粒度入口点,从而实现基础设施的不同上游服务。
$ curl -i -X POST \
--url http://localhost:8001/services/example-service/routes \
--data 'hosts[]=example.com'
返回结果如下所示:
HTTP/1.1 201 Created
Content-Type: application/json
Connection: keep-alive
{
"created_at":1519131139,
"strip_path":true,
"hosts":[
"example.com"
],
"preserve_host":false,
"regex_priority":0,
"updated_at":1519131139,
"paths":null,
"service":{
"id":"79d7ee6e-9fc7-4b95-aa3b-61d2e17e7516"
},
"methods":null,
"protocols":[
"http",
"https"
],
"id":"f9ce2ed7-c06e-4e16-bd5d-3a82daef3f9d"
}
在为服务创建好路由后,Kong就做好对外提供了此服务的准备。
4.3 通过Kong转达对于服务的请求
发出以下curl请求,以验证Kong是否正确地将请求转发给服务。注意,缺省情况下,Kong处理端口上的代理请求:8000:
$ curl -i -X GET \
--url http://localhost:8000/ \
--header 'Host: example.com'
成功的响应意味着Kong将http://localhost:8000发出的请求转发到在步骤#1中配置的url(https://mockbin.org),并将返回响应结果。通过在curl请求中定义的头,Kong知道如何做的这一点:
- Host: <given host>
参考资料
1.《Route Object》地址:https://docs.konghq.com/0.13.x/admin-api/#route-object;
2.《Configuring a Service》地址:https://docs.konghq.com/0.14.x/getting-started/configuring-a-service/
3.《Kong and Kong Enterprise on Kubernetes》地址:https://docs.konghq.com/install/kubernetes/?_ga=2.256537099.1475189429.1544400620-1563374863.1537379250
作者简介:
季向远,北京神舟航天软件技术有限公司。本文版权归原作者所有。