Kong 微服务网关在 Kubernetes 的实践

标签: kong 微服务 网关 | 发表时间:2020-08-22 00:41 | 作者:灵雀云
出处:http://weekly.dockone.io

来源:分布式实验室
译者:qianghaohao

本文主要介绍将 Kong 微服务网关作为 Kubernetes 集群统一入口的最佳实践,之前写过一篇文章使用 Nginx Ingress Controller 作为集群统一的流量入口:使用 Kubernetes Ingress 对外暴露服务,但是相比于 Kong Ingress Controller来说,Kong 支持的功能更加强大,更适合微服务架构:

◾拥有庞大的插件生态,能轻易扩展 Kong 支持的功能,比如 API 认证,流控,访问限制等;

◾Kong 服务本身和 Admin 管理 API 都集成在一个进程,通过端口区分两者,简化了部署的复杂度;

◾Kong 节点的配置统一持久化到数据库,所有节点通过数据库共享数据,在 Ingress 更新后能实时同步到各个节点,而 Nginx Ingress Controller 是通过重新加载机制响应 Ingress 更新,这种方式代价比较大,可能会导致服务的短暂中断;

◾Kong 有成熟的第三方管理 UI 和 Admin 管理 API 对接,从而能可视化管理 Kong 配置。

本文先介绍 Kong 微服务网关在 Kubernetes 的架构,然后进行架构实践,涉及到的话题有:

1 Kong 微服务网关在 Kubernetes 的架构

Kubernetes 简化了微服务架构,以 Service 为单位,代表一个个微服务,但是 Kubernetes 集群整个网络对外是隔离的,在微服务架构下一般需要一个网关作为所有 API 的入口,在 Kubernetes 中架构微服务同样也需要一个网关,作为集群统一的入口,作为服务消费方和提供方的交互中间件。Kong 可以充当这一网关角色,为集群提供统一的外部流量入口,集群内部 Service 之间通信通过 Service 名称调用:



那么 Kong 是如何在 Kubernetes 集群上跑起来?具体机制是什么样的?

Kong 作为服务接入层,不仅提供了外部流量的接收转发,而且其本身还提供了 Admin 管理 API,通过 Admin 管理 API 实现 Kong 的路由转发等相关配置,这两项功能都是在一个进程中实现。

Kubernetes 中 Kong 以 Pod 形式作为节点运行,Pod 通过 Deployment 或者 DaemenSet 管理。所有 Kong 节点共享一个数据库,因此通过 Admin API 配置,所有节点都能同步感知到变化。既然 Kong 以 Pod 的形式运行在 Kubernetes 集群中,那么其本身需要对外暴露,这样外部流量才能进来,在本地可以 nodePort 或者 hostNetwork 对外提供服务,在云平台一般通过 LoadBalancer 实现。一般的部署最佳实践是将 Kong 的 Admin 管理功能独立出来一个 Pod,专门作为所有其他节点的统一配置管理,不对外提供流量转发服务,只提供配置功能,而其他 Kong 节点专门提供流量转发功能。

说一说 Kong Ingress Controller:其实没有 Kong Ingress Controller 也完全够用,其存在的意义是为了实现 Kubernetes Ingress 资源对象。我们知道 Ingress 只不过是定义了一些流量路由规则,但是光有这个路由规则没用,需要 Ingress Controller 来将这些路由规则转化成相应代理的实际配置,比如 Kong Ingress Controller 就可以将 Ingress 转化成 Kong 的配置。与 Nginx Ingress Controller 不同,Kong Ingress Controller 不对外提供服务,只作为 Kubernetes Ingress 资源的解析转化服务,将解析转化的结果(Kong 的配置:比如 Service、Route 实体等)通过与 Kong Admin API 写入 Kong 数据库,所以 Kong Ingress Controller 需要和 Kong Admin API 打通。所以当我们需要配置 Kong 的路由时,既可以通过创建 Kubernetes Ingress 实现,也可以通过 Kong Admin API 直接配置。



2 Helm 部署 Kong

说明:本地集群部署,为了方便 Kong Proxy 和 Kong Admin 没有独立开,共用一个进程,同时提供流量转发和 Admin 管理 API。

使用 Helm 官方 Chart:stable/kong[3],由于我是在本地裸机集群部署,很多云的功能不支持,比如:LoadBalancer、PV、PVC 等,所以需要对 Chart 的 values 文件做一些定制化以符合本地需求:

1、由于本地裸机集群不支持 LoadBalancer,所以采用 nodePort 方式对外暴露 Kong proxy 和 Kong admin 服务,Chart 默认是 nodePort 方式,在这里自定义下端口:Kong proxy 指定 nodePort 80 和 443 端口,Kong Admin 指定 8001 端口:Values.proxy.http.nodePort: 80 Values.proxy.tls.nodePort: 443, Values.admin.nodePort: 8001;

注意:默认 Kubernetes nodePort 端口范围是 30000~32767,手动分配该范围之外的端口会报错!该限制可以调整,具体见之前文章:《Kubernetes 调整 nodePort 端口范围[4]》。

2、启用 Kong admin 和 Kong proxy Ingress,部署时会创建相应的 Ingress 资源,实现服务对外访问:Values.admin.ingress.enabled: true, Values.proxy.ingress.enabled: true,另外还得设置对外访问的域名(没有域名的话可以随便起个域名,然后绑 /etc/hosts 访问):Values.admin.ingress.hosts: [admin.kong.com], Values.proxy.ingress.hosts: [proxy.kong.com];

3、作为练习,为了方便,Kong admin 改用监听 HTTP 8001 端口:Values.admin.useTLS: false, .Values.admin.servicePort: 8001, .Values.admin.containerPort: 8001。另外也需要将 Pod 探针协议也改为 HTTP:Values.livenessProbe.httpGet.scheme: HTTP, Values.readinessProbe.httpGet.scheme: HTTP;

4、Kong proxy Ingress 启用 HTTPS,这样后续 kong 就可以同时支持 HTTP 和 HTTP 代理了,这里展开下具体过程:

创建 TLS 证书:域名为 proxy.kong.com:
openssl req -x509 -nodes -days 65536 -newkey rsa:2048 -keyout proxy-kong.key -out proxy-kong.crt -subj "/CN=proxy.kong.com/O=proxy.kong.com"  


使用生成的证书创建 Kubernetes Secret 资源:
kubectl create secret tls proxy-kong-ssl --key proxy-kong.key --cert proxy-kong.crt -n kong  


编辑 values 文件启用 Kong Proxy Ingress tls,引用上面创建的 Secret:Values.proxy.ingress.tls:
- hosts:  
  - proxy.kong.com
  secretName: proxy-kong-ssl


5、启用 Kong Ingress Controller,默认是不会部署 Kong Ingress Controller:ingressController.enabled: true;

6、由于本地裸机环境不支持 PV 存储,所以在部署时禁用 Postgres 数据持久化:helm 安装时指定 --set postgresql.persistence.enabled=false,这样 Postgres 存储会使用 emptyDir 方式挂载卷,在 Pod 重启后数据会丢失,本地自己玩的话可以先这么搞。当然要复杂点的话,可以自己再搭个 nfs 支持 PV 资源对象。

定制后的 values 文件在这里: https://raw.githubusercontent. ... s.yml

Helm 部署:
helm install stable/kong --name kong --set postgresql.persistence.enabled=false -f https://raw.githubusercontent.com/qhh0205/helm-charts/master/kong-values.yml --namespace kong  


验证部署:
[root@master kong]# kubectl get pod -n kong                            
NAME                                   READY   STATUS      RESTARTS   AGE
kong-kong-controller-76d657b78-r6cj7   2/2     Running     1          58s
kong-kong-d889cf995-dw7kj              1/1     Running     0          58s
kong-kong-init-migrations-c6fml        0/1     Completed   0          58s
kong-postgresql-0                      1/1     Running     0          58s

[root@master kong]# kubectl get ingress -n kong
NAME              HOSTS            ADDRESS   PORTS     AGE
kong-kong-admin   admin.kong.com             80        84s
kong-kong-proxy   prox.kong.com              80, 443   84s


curl 测试试:

[root@master kong]# curl -I http://admin.kong.com         
HTTP/1.1 200 OK
Content-Type: application/json
...

[root@master kong]# curl http://proxy.kong.com
{"message":"no Route matched with those values"
}

3 部署 Konga

上面已经将整个 Kong 平台运行在了 Kubernetes 集群,并启用了 Kong Ingress Controller,但是目前做 Kong 相关的路由配置只能通过 curl 调 Kong Admin API,配置起来不是很方便。所以需要将针对 Kong 的 UI 管理服务 Konga 部署到集群,并和 Kong 打通,这样就可以可视化做 Kong 的配置了。由于 Konga 的部署很简单,官方也没有 Chart,所以我们通过 yaml 文件创建相关资源。

为了节省资源,Konga 和 Kong 共用一个 Postgresql,Konga 和 Kong 本身对数据库资源占用很少,所以两个同类服务共用一个数据库是完全合理的。下面为 Kubernetes 资源文件,服务对外暴露方式为 Kong Ingress,域名设为(名字随便起的,绑 host 访问):konga.kong.com:

数据库密码在前面安装 Kong 时 Chart 创建的 Secret 中,获取方法:
kubectl get secret kong-postgresql -n kong -o yaml | grep password | awk -F ':' '{print $2}' | tr -d ' ' | base64 -d  

konga.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: konga
name: konga
spec:
replicas: 1
selector:
matchLabels:
  app: konga
strategy:
rollingUpdate:
  maxSurge: 1
  maxUnavailable: 1
type: RollingUpdate
template:
metadata:
  labels:
    app: konga
spec:
  containers:
  - env:
    - name: DB_ADAPTER
      value: postgres
    - name: DB_URI
      value: "postgresql://kong:K9IV9pHTdS@kong-postgresql:5432/konga_database"
    image: pantsel/konga
    imagePullPolicy: Always
    name: konga
    ports:
    - containerPort: 1337
      protocol: TCP
  restartPolicy: Always

---
apiVersion: v1
kind: Service
metadata:
name: konga
spec:
ports:
- name: http
port: 1337
targetPort: 1337
protocol: TCP
selector:
app: konga

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: konga-ingress
spec:
rules:
- host: konga.kong.com
http:
  paths:
  - path: /
    backend:
      serviceName: konga
      servicePort: 1337


kubectl 部署 Konga:
kubectl create -f konga.yml -n kong

部署完成后绑定 host 将 konga.kong.com 指向集群节点 IP 即可访问:



接下来随便注册个账号,然后配置连接到 Kong Admin 地址,由于都在集群内部,所以直接用 Kong Admin 的 ServiceName 端口号连就可以:



连接没问题后,主页面会显示 Kong 相关的全局信息:

4 示例:通过 Konga 配置对外访问 Kubernetes Dashboard

之前我们基于 Nginx Ingress Controller 对外暴露 Kubernetes Dashboard,现在我们基于集群中 Kong 平台配置对外访问,通过 Konga 可视化操作。

通过 Konga 配置服务对外访问只需要两步:

1.创建一个对应服务的 Service(不是 Kubernetes 的 Servide,是 Kong 里面 Service 的概念:反向代理上游服务的抽象);

2.创建对应 Service 的路由。

下面以配置 Kubernetes dashboard 服务对外访问为例,对外域名设为 dashboard.kube.com(名字随便起的,绑 host 访问)。

创建 Kong Service:



创建服务路由:





配置完成,浏览器测试访问: https://dashboard.kube.com

相关 [kong 微服务 网关] 推荐:

Kong 微服务网关在 Kubernetes 的实践

- - DockOne.io
译者:qianghaohao. 本文主要介绍将 Kong 微服务网关作为 Kubernetes 集群统一入口的最佳实践,之前写过一篇文章使用 Nginx Ingress Controller 作为集群统一的流量入口:使用 Kubernetes Ingress 对外暴露服务,但是相比于 Kong Ingress Controller来说,Kong 支持的功能更加强大,更适合微服务架构:.

API 网关 Kong

- - IT瘾-tuicool
所谓网关,主要作用就是连接两个不同网络的设备,而今天所讲的 API 网关是指承接和分发客户端所有请求的网关层. 最初是单体服务时,客户端发起的所有请求都可以直接请求到该服务,但随着产品用户越来越多,单体应用存在显而易见的单点问题,除此之外,当单体应用大小升至几个 G 时,持续发布将会非常缓慢,所以服务的拆分成为了必然趋势.

基于kong的微服务解决方案 | kong

- -
最近处理了几个客户的需求,需求有相似之处,解决方案迭代几次以后也具备了一定的复制性. 目前应用用springboot写的,以业务分块,大概形成了几十个(30+)部署单元;每个部署单元都是独立的jar,其中每个包含十个左右的endpoints. 目前用了eureka和zuul做服务注册/发现以及负载均衡;在整体部署规模超过200个jvm之后,出现了一些问题.

基于Kong网关的管理平台Konga(9.9)

- - 人月神话的BLOG
在年中我们重新修订了ESB服务总线和API网关的产品规划后,初步决策还是基于Kong网关来定制开放API网关平台,对于Kong网关前面已经有文章做过介绍,下面再总结下Kong网关的一些关键特点. 1.可扩展性: 通过简单地添加更多的服务器,可以轻松地进行横向扩展,这意味着您的平台可以在一个较低负载的情况下处理任何请求;.

开源API网关Kong基本介绍和安装验证(201129)

- - 人月神话的BLOG
今天准备介绍下开源API网关Kong,在Gtihub搜索API网关类的开源产品,可以看到Kong网关常年都是排第一的位置,而且当前很多都有一定研发能力的企业在API网关产品选型的时候基本也会选择Kong网关,并基于Kong网关进行二次开发和定制. 简单来说API网关就是将所有的微服务提供的API接口服务能力全部汇聚进来,统一接入进行管理,也正是通过统一拦截,就可以通过网关实现对API接口的安全,日志,限流熔断等共性需求.

微服务-API网关实战小结

- - 掘金 后端
 1.为什么需要API网关.         在业务开发中,后台经常要暴露接口给不同的客户端如App端、网页端、小程序端、第三方厂商、设备端等使用,由于技术栈比较统一使用了 Spring boot web开发框架. 所以刚开始统一封装了如鉴权、限流、安全策略、日志记录等集成的工具包,开发中只需要引入该工具包即可实现上述的功能,请求端通过 Nginx后将请求到对应的微服务集群的节点上.

花椒直播 Kong 应用实践

- - DockOne.io
Kong 是面向现代架构(混合云,混合组织)的下一代 API 网关平台,具有云原生、高性能,易用、可扩展等特性. 适用于 API Gateway,Kubernetes Ingress,Service Mesh Sidecar 等场景. 云原生:与平台无关,Kong 可以从裸机运行到 Kubernetes.

怎么用API网关构建微服务|架构

- - 企业架构 - ITeye博客
转于http://www.tuicool.com/articles/bMnEbmv. 当选择将应用程序构建为一组微服务时,需要确定应用程序客户端如何与微服务交互. 在单体应用程序中,只有一组(通常是重复的、负载均衡的)端点. 然而,在微服务架构中,每个微服务都会暴露一组通常是细粒度的端点. 在本文中,我们将讨论一下这对客户端与应用程序之间的通信有什么影响,并提出一种使用API网关的方法.

个推微服务网关架构实践

- - DiyCode - 致力于构建开发工程师高端交流分享社区社区
作者:个推应用平台基础架构高级研发工程师 阿飞. 在微服务架构中,不同的微服务可以有不同的网络地址,各个微服务之间通过互相调用完成用户请求,客户端可能通过调用N个微服务的接口完成一个用户请求. 因此,在客户端和服务端之间增加一个API网关成为多数微服务架构的必然选择. 在个推的微服务实践中,API网关也起着至关重要的作用.

微服务和API网关限流熔断实现关键逻辑思路

- - DockOne.io
本文谈下微服务架构和API网关中的限流熔断,当前可以看到对于Spring Cloud框架本身也提供了Hystrix,主流的开源API网关产品类似Kong网关本身也包括了限流熔断能力. 当然也有完全较为独立的限流熔断开源实现,比如阿里的Sentinel即是我们经常会用到的限流熔断开源产品,而且可以和Dubbo,SpringCloud等各种微服务框架无缝集成.