API网关作为成熟的云产品,已经集成了非常丰富的接入能力。将API网关作为Kubernetes集群应用的接入服务使用,将大大提高Kubernetes集群的服务能力,并可以作为大型互联网应用的标准架构。本文介绍API网关如何作为Kubernetes集群的接入层。
概述
Kubernetes 集群介绍
Kubernetes(k8s)已经成为主流的自动化容器平台,因其开源性而备受赞誉。Kubernetes在容器技术的基础上,增加调度和节点集群间扩展能力,可以非常轻松地让你快速建立一个企业级容器应用集群,这个集群主要拥有以下能力:
自动化容器的部署和复制
随时扩展或收缩容器规模
将容器组织成组,并且提供容器间的负载均衡
很容易地升级应用程序容器的新版本
提供容器弹性,如果容器失效就替换它
API网关作为Kubernetes集群的接入层架构
我们可以看到Kubernetes集群是可以作为应用服务的,但是Kubernetes集群没有足够的接入能力,特别是在大型应用中,它是不能够直接对用户提供服务的,否则会有非常大的安全风险。将API网关放在Kubernetes集群前面作为应用集群的接入服务使用,可以作为标准的大型互联网应用的标准架构。下面是使用阿里云架构图:
是否启用Ingress Control?
从架构图中我们可以看到,API网关作为Kubernetes集群的桥头堡,负责处理所有客户端的接入及安全工作,API网关和Kubernetes集群中Ingress Control的内网CLB或者服务的内网CLB进行通信。具体什么时候用Ingress Control呢?如果Kubernetes集群内只有一个服务,网关直接和此服务关联的内网CLB进行通信最高效。如果Kubernetes集群内有多个服务,如果使用服务的内网CLB对网关提供服务,将会生成很多CLB,资源管理起来会比较麻烦,此时我们可以使用Ingress Control做Kubernetes中服务发现与七层代理工作,API网关的所有请求发送到Ingress Control关联的内网CLB上,由Ingress Control将请求分发到Kubernetes集群内的容器内,这样我们也只需要一个内网CLB就能将Kubernetes集群内的所有服务暴露出去了。
API网关接入能力
接入了API网关具体能为整个架构带来哪些好处呢?下面我们列一下这种架构中,API网关具体能给整个应用带来什么价值。
API网关允许客户端和API网关使用多种协议进行通信,其中包括:
* HTTP * HTTP2
API网关使用多种方法保证和客户端之间的通信安全:
* 允许定义API和APP之间的授权关系,只有授权的APP允许调用; * 全链路通信都使用签名验证机制,包括客户端和API网关之间的通信和API网关和后端服务之间的通信,保证请求在整个链路上不会被篡改; * 支持用户使用自己的SSL证书进行HTTPS通信; * 支持OPENID CONNECT;
API网关具备iOS/Android/Java三种SDK的自动生成能力,并且具备API调用文档自动生成能力。
API网关支持入参混排能力,请求中的参数可以映射到后端请求中的任何位置。
API网关提供参数清洗能力,用户定义API的时候可以指定参数的类型,正则等规则,API网关会帮用户确认传输给后端服务的请求是符合规则的数据。
API网关支持流量控制能力,支持的维度为用户/APP/API。
API网关提供基于请求数/错误数/应答超时时间/流量监控报警能力,所有的报警信息会使用短信或者邮件在一分钟内发出。
API网关已经和阿里云的SLS产品打通,用户可以将所有请求日志自动上传到用户自己的SLS中,以便后续更好地对访问日志进行统计分析。
API网关支持Mock模式,在联调中这个能力非常方便。
API网关支持用户配置调用方的IP白名单和黑名单。
API网关结合阿里云的云市场,为Provider提供向API使用者收费的能力。
阿里云的API网关是一个上线数年的成熟云产品,在稳定性和性能方面,经过了时间和阿里云的工程师的不断打磨,适用于有高性能需求的用户。
快速配置Kubernetes集群和API网关
阿里云支持快速创建Kubernetes集群,同一个Region内的Kubernetes集群和API网关的集成也非常简单。在API网关作为Kubernetes集群的接入层架构设计中,API网关和Kubernetes有两种结合的模式:
方式一:API网关将请求发送到Ingress Control前的CLB,由Ingress Control将请求路由到Kubernetes对应的节点中。只需要Ingress Control前有一个CLB就可以了,由Ingress Contro做服务发现与路由。
方式二:API网关直接将请求发送到Kubernetes中服务前的CLB,由CLB直接将请求转发到Kubernetes中服务对应的节点中。每个服务前都需要申请一个CLB,适合并发量大的场景。
方式一:Ingress Control模式的配置
创建Kubernetes集群并安装Ingress
创建ACK 托管版集群或ACK Serverless集群时,在组件配置阶段的Ingress参数配置区域,选择安装ALB Ingress。关于创建集群,请参见创建ACK托管集群或创建ACK Serverless集群。
在集群内创建一个多容器的服务
我们需要在集群内创建一个服务,这个服务由2个容器组成,每个容器都由Nginx镜像生成。容器的端口是80,Ingress Control提供服务的端口是80。
登录容器服务管理控制台,在左侧导航栏选择集群列表。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择 。
在无状态页面,单击使用YAML创建资源,输入下面的资源编排文本单击创建。
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-demo labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-service spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: nginx sessionAffinity: None type: NodePort
说明编排模板YAML文本解释如下:
使用Nginx镜像创建两个容器,容器的服务端口是80,并且创建一个命名为nginx-service的服务,对外服务的端口为80,映射到容器80的端口。
每个容器上面跑着一个Nginx。这两个容器组成一个无状态应用,并且组成了一个命名为nginx-service的服务。可以进入无状态应用详情页面看到整个应用的运行情况。目前API网关不能访问到这个服务,需要在Ingress Control上建立一条到这个服务的路由才能把全链路打通。
在Ingress Control上给服务配置路由
应用有了,还需要在Ingress Control上为这个应用建立一个服务,然后在服务上建立一条路由,这样API网关将请求发送给Ingress Control时,Ingress Control会根据配置的路由信息将请求代理到对应的应用节点上。
登录容器服务管理控制台,在左侧导航栏选择集群列表。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择
。单击创建 Ingress按钮,在创建 Ingress页面的规则区域,填写域名,配置路径映射参数并单击确定。
对Ingress Control的内网CLB授权
API网关如果要访问Ingress Control的内网CLB,需要在API网关控制台上增加VPC网络的授权。
登录容器服务管理控制台,在左侧导航栏选择集群列表。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择
。在路由页面复制端点信息。
- 登录应用型负载均衡ALB控制台。
在左侧导航栏选择概览,在资源列表处搜索复制的端点信息,单击搜索到的ALB实例。
在ALB实例详情页面,复制VPC网络ID和ALB实例的DNS 名称。
登录API网关控制台,选择地域并在左侧导航栏选择API管理 > VPC授权。
在授权列表页面,单击右上角创建授权。
在创建VPC授权页面,输入VPC授权名称、VPC Id、实例Id或地址、端口号,单击确定。
创建API
登录API网关控制台,选择地域并在左侧导航栏选择API管理 > 分组管理。
在分组列表页面下,单击所创建的目标分组操作列下的API管理。
在API列表页面,单击右上角创建API。
在创建API页面的基本信息栏,配置如下基本信息,单击下一步。
在定义API请求栏,配置如下信息,单击下一步。
在定义API后端服务栏,配置如下信息,单击下一步。
重要创建API页面的常量参数添加一个名字为host,位置header的参数,参数值设置为Ingress Control上给服务配置路由的域名。
在定义返回结果栏,单击创建。
在创建成功之后弹框中单击发布。
在发布弹框中发布的环境选择线上,输入请填写变更备注,单击发布。
调用测试
API发布到线上就可以使用API网关的测试工具进行测试,查看能否将请求发送到刚才创建的Kubernetes集群中去。
登录API网关控制台,在左侧导航栏选择API调用 > 调试。
在调试页面选择,所创建的
nginx-test
API,然后单击发送请求,即可看到如下图信息说明配置成功。
方式二:Kubernetes服务内网CLB结合模式的配置
本节主要描述创建携带内网CLB的Kubernetes服务。
创建Kubernetes集群
创建ACK 托管版集群或ACK Serverless集群,请参见创建ACK托管集群或创建ACK Serverless集群。
在集群内创建一个多容器的服务
有了Kubernetes集群,现在我们通过资源编排文本在这个集群中创建带有内网CLB的服务。本段资源编排代码和方式一中的资源编排代码不同的是,我们把最后一行的Type变成了LoadBalancer,并且指定了这个CLB LoadBalancer为内网。
登录容器服务管理控制台,在左侧导航栏选择集群列表。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择 。
在无状态页面,单击使用YAML创建资源,输入下面的资源编排文本并单击创建。
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-demo labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-service annotations: service.beta.kubernetes.io/alicloud-loadbalancer-address-type: intranet spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: app: nginx type: LoadBalancer
说明编排模板YAML文本解释是:使用Nginx镜像创建两个容器,容器的服务端口是80,并且创建一个命名为nginx-service的服务,这个服务前有一个内网CLB,对外服务的端口为80,映射到容器80的端口。
对Kubernetes集群中服务的内网CLB授权
我们成功创建了一个携带内网CLB的服务,可以在Kubernetes控制台的网络菜单的服务子页面找到这个内网CLB的内网IP。
登录容器服务管理控制台,在左侧导航栏选择集群列表。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择
。在服务页面找到外部 IP 地址(External IP)列下的地址。
- 登录应用型负载均衡ALB控制台。
在左侧导航栏选择概览,在资源列表处搜索复制的外部 IP 地址,单击搜索到的CLB实例。
在CLB实例详情页面,复制VPC网络ID和CLB实例ID。
登录API网关控制台,选择地域并在左侧导航栏选择API管理 > VPC授权。
在授权列表页面,单击右上角创建授权。
在创建VPC授权页面,输入VPC授权名称、VPC Id、实例Id或地址、端口号,单击确定。
创建API
登录API网关控制台,选择地域并在左侧导航栏选择API管理 > 分组管理。
在分组列表页面下,单击所创建的目标分组操作列下的API管理。
在API列表页面,单击右上角创建API。
在创建API页面的基本信息栏,配置如下基本信息,单击下一步。
在定义API请求栏,配置如下信息,单击下一步。
在定义API后端服务栏,配置如下信息,单击下一步。
在定义返回结果栏,单击创建。
在创建成功之后弹框中单击发布。
在发布弹框中发布的环境选择线上,输入请填写变更备注,单击发布。
调用测试
API发布到线上就可以使用API网关的测试工具进行测试,查看能否将请求发送到刚才创建的Kubernetes集群中去。
登录API网关控制台,在左侧导航栏选择API调用 > 调式。
在调试页面选择,所创建的
nginx-test-2
API,然后单击发送请求,即可看到如下图信息说明配置成功。
配置总结
我们描述了在阿里云的公有云如何创建一整套API网关加Kubernetes的流程,关键点在于Kubernetes集群通过Ingress Control组件服务发现,在API网关对Ingress Control组件的内网CLB进行授权后,将所有请求发送到CLB上。下面我们再总结一下通过Ingress结合API网关与Kubernetes的步骤:
创建一个带有Ingress Control组件的Kubernetes的集群。
使用资源编排命令,在Kubernetes集群中创建两个运行的Nginx的容器,并且基于这两个容器创建对应的服务。
在控制台上给Ingress Control加上一条服务路由。
到CLB控制台找到Ingress Control内网CLB的实例ID和VPC ID,在API网关控制台创建一个VPC授权。
在API网关控制台创建API,后端服务使用刚才创建的VPC授权,并且设定一个名为host的参数,参数值使用Ingress Control服务路由设置的域名。API的请求将发送到Kubernetes集群的Ingress Control的CLB上,由Ingress Control将请求路由到容器内部的Nginx服务上。
在高并发场景或者只有一个服务的场景,我们可以跳过Ingress Control,直接在服务前面架设一个内网CLB,并且将这个内网CLB授权给API网关,供API网关进行访问。
Ingress Control和CLB两种方案对比
使用CLB+Ingress Control。Ingress Control可以做Kubernetes集群的服务发现和七层代理工作,如果Kubernetes集群中有多个服务,可以统一使用Ingress Control进行路由,同时只需要一个内网CLB就可以对外暴露多个服务,便于运维管理和Kubernetes集群的服务扩充。推荐使用此种方式。
直接使用CLB。如果集群中某个服务的业务压力很大,可以考虑为此服务单独建立一个CLB,API网关直接连接此CLB,从而达到更高的通信效率。此种方式的弊端也比较明显,如果Kubernetes集群内有多个服务,需要为每个服务配置一个CLB,因此给运维管理带来较大的工作量。
总结
我们描述了Kubernetes集群和API网关的各项能力,并且画出了结合它俩作为后端应用服务生产的架构图。我们结合API网关和Kubernetes集群的架构,让系统具备了动态伸缩,动态路由,支持多协议接入,SDK自动生成等各项能力,成为可用性更高,更灵活更可靠的一套架构。