Kong 微服务网关在 Kubernetes 的实践
来源:分布式实验室
译者:qianghaohao
本文主要介绍将 Kong 微服务网关作为 Kubernetes (https://www.alauda.cn)集群统一入口的最佳实践,之前写过一篇文章使用 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 (https://www.alauda.cn)简化了微服务架构,以 Service 为单位,代表一个个微服务,但是 Kubernetes 集群整个网络对外是隔离的,在微服务架构下一般需要一个网关作为所有 API 的入口,在 Kubernetes 中架构微服务同样也需要一个网关,作为集群统一的入口,作为服务消费方和提供方的交互中间件。Kong 可以充当这一网关角色,为集群提供统一的外部流量入口,集群内部 Service 之间通信通过 Service 名称调用:
那么 Kong 是如何在 Kubernetes 集群上跑起来?具体机制是什么样的?
Kong 作为服务接入层,不仅提供了外部流量的接收转发,而且其本身还提供了 Admin 管理 API,通过 Admin 管理 API 实现 Kong 的路由转发等相关配置,这两项功能都是在一个进程中实现。
在 Kubernetes (https://www.alauda.cn)中 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(https://www.alauda.cn) 集群,并启用了 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 微服务网关在 Kubernetes 的实践的更多相关文章
- SpringCloud的微服务网关:zuul(实践)
Zuul的主要功能是路由和过滤器.路由功能是微服务的一部分,比如/api/user映射到user服务,/api/shop映射到shop服务.zuul实现了负载均衡. zuul有以下功能: Authen ...
- 第三模块 :微服务网关Zuul架构和实践
52.Zuul网关架构剖析~1.mp4 请求过来之后首先会通过前置过滤器,然后到路由过滤器,路由过滤器是真正访问后台远程服务的,经过路由器之后,最后会传递给后置过滤器 在三个过滤器处理的过程中任何一个 ...
- 微服务架构学习与思考(10):微服务网关和开源 API 网关01-以 Nginx 为基础的 API 网关详细介绍
微服务架构学习与思考(10):微服务网关和开源 API 网关01-以 Nginx 为基础的 API 网关详细介绍 一.为什么会有 API Gateway 网关 随着微服务架构的流行,很多公司把原有的单 ...
- 微服务网关哪家强?一文看懂Zuul, Nginx, Spring Cloud, Linkerd性能差异
导语:API Gateway是实现微服务重要的组件之一.面对诸多的开源API Gateway,如何进行选择也是架构师需要关注的焦点.本文作者对几个较大的开源API Gateway进行了压力测试,对 ...
- 微服务网关实战——Spring Cloud Gateway
导读 作为Netflix Zuul的替代者,Spring Cloud Gateway是一款非常实用的微服务网关,在Spring Cloud微服务架构体系中发挥非常大的作用.本文对Spring Clou ...
- 微服务网关 Spring Cloud Gateway
1. 为什么是Spring Cloud Gateway 一句话,Spring Cloud已经放弃Netflix Zuul了.现在Spring Cloud中引用的还是Zuul 1.x版本,而这个版本是 ...
- 王院生:Apache APISIX 微服务网关极致性能架构解析
2019 年 10 月 27 日,又拍云联合 Apache APISIX 社区举办 API 网关与高性能服务最佳实践丨Open Talk 杭州站活动,Apache APISIX PPMC 成员王院生做 ...
- 小D课堂 - 新版本微服务springcloud+Docker教程_6-01 微服务网关介绍和使用场景
笔记 第六章 微服务网关zuul开发实战 1.微服务网关介绍和使用场景 简介:讲解网关的作用和使用场景 (画图) 1)什么是网关 API Gateway,是系 ...
- SpringCloud Gateway微服务网关实战与源码分析-上
概述 定义 Spring Cloud Gateway 官网地址 https://spring.io/projects/spring-cloud-gateway/ 最新版本3.1.3 Spring Cl ...
随机推荐
- Set数据结构基本介绍
构造 const set = new Set([1, 2, 3, 4, 4]); 可接受的参数为所有具有iterable 接口的数据 特性: 类似数组,无重复值. const set = new Se ...
- 使用JSONArray.fromObject转化list时,如果有集合属性,很容易出错,此刻把集合属性过滤掉便可
使用JSONArray.fromObject转化list时,如果有集合属性,很容易出错,此刻把集合属性过滤掉便可
- 移动端滚动方案:better-scroll
BetterScroll 是什么 BetterScroll 是一款重点解决移动端(已支持 PC)各种滚动场景需求的插件.它的核心是借鉴的 iscroll (opens new window) 的实现, ...
- JAVA上传文件到FTP上
添加maven <!-- https://mvnrepository.com/artifact/commons-net/commons-net --> <dependency> ...
- Windows10 c++获取网卡信息(ipv4,子网掩码,网关,mac地址)
关于 本文样式环境: win10 + vs2017 + c++11 1.说明 算是踩坑吧,先前一直认为一块网卡只能有一个IP. 今天发现结构体中,定义了相关结构: 一块网卡可以用多个IP. 2.连接库 ...
- 【LeetCode】447. Number of Boomerangs 解题报告(Java & Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 [LeetCode] 题目地址:https:/ ...
- 【剑指Offer】二叉搜索树的第k个结点 解题报告(Python)
[剑指Offer]二叉搜索树的第k个结点 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-intervie ...
- 『学了就忘』vim编辑器基础 — 97、vim使用技巧
目录 1.在vim中导入其他文件内容或命令结果 (1)导入其他文件内容 (2)在vim中执行系统命令 (3)导入命令结果 2.设定快捷键 3.字符替换 4.多文件打开 vim使用技巧,就是vim编辑器 ...
- Java GUI 桌面应用开发
前言 虽然现在已经很少项目会涉及GUI技术,但作为一个合格的Java开发工程师,还是得了解才得 本文记录,idea使用JFormDesigner插件进行Java GUI 桌面应用开发 GUI Swin ...
- MySQL中写操作
具体到操作流程: 当执行某个写操作的 SQL 时,引擎将这行数据更新到内存的同时把对应的操作记录到 redo log 里面,然后处于 prepare 状态.并把完成信息告知给执行器. 执行器生成对应操 ...