2.2 网关演进
随着技术变革的推动和系统架构的不断演进,服务与外部组件、服务内部之间的交互模式也发生了较大变化。从较早的直连模式到当前的云原生负载均衡器及Gateway API,网关的发展可谓曲折。
Gateway API的引入解决了客户端应用程序和后端组件之间的通信问题,但同时带来了额外的开发成本。加上云原生生态的普及,传统API网关处于尴尬的境地。
此时,网关的出路在哪里?
2.2.1 传统API网关
API网关是微服务架构的重要组成部分,允许将应用程序分解为更易于管理和更新的小组件。借助API网关,开发人员可以更好地管理应用程序的前端,并专注于应用程序的核心功能开发。
1.API网关概念
API网关通常用于API管理,位于客户端和后端服务之间,接受所有应用程序编程接口(API)调用,聚合实现应用所需的各种服务,并返回结果。
无论基于传统的单体架构还是流行的微服务架构,API网关的主要职责都是接受来自客户端的API调用,将请求路由到对应的微服务,并执行一些业务逻辑,例如,可能会组合来自后端服务的响应和进行协议转换。API网关可以同时处理多个外部请求,并将它们路由到后端的各种微服务。
简而言之,API网关作为请求从防火墙外部进入应用程序的单一入口点,实现了包括请求授权及认证、请求路由、速率限制、计费、监控、分析、策略检查、告警和统计等多种功能。
2.API网关工作原理
API网关的工作原理可以参考图2-1。
图2-1 API网关工作原理参考示意图
根据上述参考示意图,我们可以得知,API网关工作主要涉及如下几个阶段。
1)请求接收。API网关接收来自客户端的API请求,并将请求转发到后端服务。通常,API网关可以接收各种类型(包括REST、WebSocket和HTTP)的请求。
2)请求验证。API网关会验证请求的格式、认证、权限等,涉及验证API密钥、JWT令牌、基本认证等。如果验证失败,API网关会直接返回错误响应,不转发到后端服务。
3)请求转发。验证成功后,API网关会将请求转发到相应的后端服务,然后将请求路由到正确的服务和端点。
4)响应处理及返回。后端服务处理请求并返回响应后,API网关会接收到响应结果,并进行一些额外的处理以及将结果返回给客户端。
API网关的核心功能之一是请求路由,通过将请求路由到相应的服务来实现某些API操作。API网关收到请求时会查询路由映射。该映射指定了将请求路由到哪个服务,例如,可以将HTTP方法和路径映射到HTTP服务的URL。
协议转换也是API网关的常用功能,在应用服务逻辑处理中发挥着重要作用。在实际场景中,API网关可能向外部客户端提供RESTful API,即使应用程序服务内部使用的是混合协议,如REST和gRPC。在需要时,某些API操作会在基于REST的外部API和基于gRPC的内部API之间进行转换,以满足业务需求。
API网关可以提供通用的API。通常,单一API的存在是因为不同客户往往有不同的需求,例如,第三方应用可能需要Get Merchant Details API操作命令返回完整的Merchant详细信息,而客户端可能只需要数据的一个子集。解决这个问题的一种方法是让客户端在请求中指定服务器应返回哪些字段和相关对象。对于为第三方应用提供服务的公共API,这种方法已经足够,但通常无法为客户提供所需的控制权。
在现代应用框架设计中,最佳解决方案是API网关为每个客户端提供定制的API。例如,Mobile API网关可以实现为移动客户端提供专门设计的API。API网关甚至可以为Android和iPhone移动应用程序提供不同的API。此外,API网关还提供了公共API,供第三方开发者使用。
API网关为通过一组API向外界暴露多个微服务或Serverless服务的架构组件。建立在典型反向代理的一部分功能之上,API网关能够承载多个任务的处理,具体如下。
(1)负载均衡
在微服务架构中,API网关旨在多个服务之间依据所设定的算法策略路由所流经的流量,以提高架构整体性能和可用性。
(2)流量治理
依据实际的业务场景,API可将流量与基础设施的容量进行自适应适配,主要涉及速率限制、服务发现、请求聚合等。
(3)访问控制
API网关通过在传入连接到达Web服务器之前对其进行身份验证以及对客户端隐藏Web服务器的IP地址和网络结构来保证访问安全。
(4)SSL/TLS连接终止
将处理SSL/TLS连接的任务从Web服务器转移到反向代理,让Web服务器专注于处理请求。
(5)缓存
API网关通过缓存更靠近客户端的频繁请求内容来提高性能。
(6)请求/响应转换
API网关通过修改传入请求或传出响应来符合特定要求,例如添加或删除标头、压缩/解压缩以及加密/解密内容。
(7)记录和监控
API网关主要收集API使用情况和性能数据,为流量分析及后续架构优化提供数据参考。
3.API网关架构
在实际的业务场景中,API网关具有分层的模块化架构。API网关架构如图2-2所示,由两层组成——API层和公共层。API层由一个或多个独立的API模块组成,每个API模块为特定客户端实现一个API。通用层实现共享功能,包括身份验证等边缘功能。
图2-2 API网关架构
在上述架构中,API网关有3个核心模块。
❑移动端API:为移动客户端提供API调用。
❑浏览器API:为在浏览器中运行JavaScript应用程序提供API调用。
❑公共API:为第三方开发者提供的API。
API模块通过两种方式实现API操作。
❑一些API操作可以直接映射到单个服务的API操作。API模块通过将请求路由到相应服务的API操作来实现这些API操作。我们可以使用通用的路由模块,读取路由规则配置文件来实现这些API操作。
❑复杂API操作使用API组合实现。这些API操作由自定义代码实现。每个API操作通过调用多个服务并组合结果来处理请求。
4.API网关选型关注点
API网关降低了后端服务的复杂性。在选择API网关之前应考虑几个关键方面,具体如下。
(1)可扩展性和性能
在选择API网关之前,最重要的考虑因素是其可扩展性和性能。具有API网关的平台应同时支持异步和非阻塞I/O,以提高效率。虽然API网关具有可扩展性、高可用性、负载均衡和共享状态等优点,但在确保性能不受影响的前提下,我们尽可能使其表现良好。
此外,API网关还应该为硬件或云基础设施提供容错能力,并为消费者提供更低时延。
(2)安全
API网关充当应用程序的第一道防线,验证请求的授权并确保数据安全传输,为API的消费者和开发者提供了一个集中的访问点和控制界面,从而保障API安全和按照预期运行。
为了防止对API资源未授权访问,API网关可以将API访问和使用限制为仅授权用户。API调用安全功能可以确保只有授权用户才能调用API,并在执行API调用时使用正确的参数。
从本质上讲,这类似于我们使用护照或签证来验证自己的身份。通过提供身份验证层,API网关可确保只有经过身份验证的用户才能访问后端,以避免安全漏洞。
(3)响应变换
API网关通过将请求转发给服务并将服务的响应返回给客户端来处理请求。API网关负责将请求路由到适当的后端服务,以满足客户端的需求。
API网关可以通过缓存频繁请求的数据来提高后端服务性能,并且可以转换请求和响应格式,以针对客户端或后端服务进行优化。例如,API网关可以将客户端的JSON格式请求转换为XML格式,然后将其转发到仅支持XML格式的后端服务。
(4)速率限制
API可以轻松处理来自不同路径的多个请求。在现实世界中,API需要处理大量请求而不会使系统过载。这就是速率限制功能的用武之地。
速率限制功能用于控制可能流经API网关的流量。通过限制在特定时间段内可以发出的请求数,我们可以确保API即使在高负载下也能正常运行。
(5)立体化观测
默认情况下,API网关应提供对所有API的监控,以便跟踪所有API请求和响应,还应该能与API监控解决方案集成,以便分析API指标。
日志记录是API监控的关键组件,以便查看API运行状况和分析性能,从而及早发现并解决问题。
5.API网关的优势
API网关的优势主要体现在如下几方面。
(1)灵活性
API网关易于配置。在微服务架构中,开发人员可以轻松地以各种标准设计应用程序的内部结构,以便用户获得合适的服务。
(2)轻松的服务交付
API网关以合乎逻辑的方式合并请求并及时提供服务。灵活的API网关架构可节省带宽并协调API流程,从而带来更好的用户体验。这就是移动应用程序可以快速提供服务的原因。
(3)增强API端点的安全性
API网关可作为前端服务和其他微服务之间通信安全的障碍,确保基本API端点不被泄露,还可以保护API免受恶意网络攻击,包括SQL注入、DoS攻击和其他利用API缺陷的恶意攻击。
(4)扩展遗留应用程序
即使遗留应用程序过时,我们也可以尝试使用API网关来访问,而不是完全迁移。
(5)降低API复杂性
API的目标是提供某种服务。然而,访问控制、速率限制、令牌授权和缩放等可能会阻碍API快速处理任务。API网关负责这些日常任务,让API与其核心功能一起工作。
(6)监控API
通常,在将API集成到应用程序时,企业会使用监控工具来监控集成API的服务。API网关比其他监控工具要好得多,可以在监控过程中完美识别具体问题。
6.API网关的劣势
API网关在现代应用程序设计中扮演着重要角色,但也存在一些缺点和问题,需要技术团队注意和解决。API网关的劣势主要体现在以下几方面。
(1)可靠性和弹性低
由于API网关通常是应用程序的入口,如果API网关出现故障,整个应用程序的可用性将受到影响。
同时,在增强应用功能和服务时,技术团队应谨慎行事,因为当网关存在风险时,整个应用程序的性能和服务交付可能会受到影响。
(2)易成为攻击目标
API网关有广泛的应用场景,这也成为其被恶意攻击的原因之一。API网关需要处理大量敏感数据,包括用户凭据、个人身份信息等,如果API网关受到攻击,这些敏感数据可能会被泄露。
(3)复杂
通常,API网关能够监控和控制功能和服务的交付。即使是系统中微小的变化也会对API网关性能产生深远影响。如果开发人员要使用其他增强功能更新应用程序,那么需要确保API网关也得到更新。同时,API网关需要动态发现和路由请求到后端服务,这需要使用复杂的算法和配置选项。
2.2.2 Ingress代理
在虚拟机或Kubernetes Ingress出现之前,一般会采用Nginx或HAproxy等组件作为暴露的负载均衡器,以将外部流量路由到内部集群服务。这些负载均衡器可以根据不同的路由规则将流量分发到不同的后端服务,并通过健康检查来确保服务的可用性和稳定性。
随着云原生技术的快速发展,Kubernetes Ingress已经成为新一代的负载均衡器,通过更加灵活和简单的方式来管理集群服务的流量。
1.流量路由模型
通常,路由规则可以被添加到Nginx或HAProxy的Pod或服务实例的配置映射中。当DNS发生变化或需要添加新的路由条目时,可以更新配置映射并重新加载Pod或服务实例的配置,或者重新部署以使更改生效。
(1)传统虚拟机模式
基于传统虚拟机模式的流量路由架构示意图具体可参考图2-3。
图2-3 基于传统虚拟机模式的流量路由架构参考示意图
在此架构中,负载均衡器通常会使用一些算法来决定将流量路由到哪个后端应用服务器上。例如,轮询、最少连接和IP散列等算法都可以用于负载均衡器。应用服务器通常会运行多个相同的应用实例,以便同时处理更多的流量,提高可用性和容错性。
然而,基于传统虚拟机模式的流量路由模型也存在一些劣势。在这种架构中,每个应用程序都需要单独管理和部署,这可能会导致管理和部署的复杂度提升、资源浪费和效率降低。
此外,在这种架构中,负载均衡器和应用服务器通常是静态配置的,无法自适应地根据流量变化进行调整。这可能会导致负载均衡器、应用服务器出现资源浪费或过载的情况,从而影响应用程序的性能或可用性。
(2)未引入Ingress
在云原生架构中,未引入Ingress的容器云模式的流量路由架构示意图具体可参考图2-4。
在此架构中,流量入口模型通常使用服务网格和云原生服务端口来处理流量入口:将服务端口映射到节点端口,并允许外部客户端通过访问节点IP地址和节点端口来访问服务,以实现简单的流量负载。
图2-4 基于未引入Ingress的容器云模式的流量路由架构参考示意图
(3)引入Ingress
与传统模式相对应的云原生Kubernetes Ingress模式也采用了类似的方式,即将路由规则维护为本地Kubernetes Ingress对象,而不是通过配置映射来实现,具体可参考图2-5。
图2-5 基于Ingress的容器云模式的流量路由架构参考示意图
基于上述参考示意图,在云原生生态体系中,作为一个Kubernetes API对象,Ingress主要用于管理外部流量如何路由至Kubernetes集群中的服务。
从另一个角度来看,Ingress充当一种路由协议(例如HTTP、HTTPS),详细阐述了Kubernetes集群中的服务如何被集群外的用户访问。
本质上,Ingress为Kubernetes中的服务提供了更高级别的流量控制和管理机制,特别是针对HTTP请求。通过Ingress,我们可以定义一系列路由规则,从而避免为每个服务单独创建负载均衡器或将其暴露给外部。此外,Ingress还可以用于为Kubernetes中的服务提供外部可访问的URL、负载均衡流量、终止SSL/TLS、配置基于主机名的虚拟主机以及实现基于URL路径的路由转发。
尽管Kubernetes Ingress向外公开了集群服务,但有助于管理员有效地管理应用程序并诊断与路由相关的问题。这样做可以增强集群的安全性,因为Kubernetes Ingress显著降低了潜在的攻击面。
在实际的业务场景中,Kubernetes Ingress的典型用例如下。
❑提供外部可访问的URL,以访问集群内的特定服务。
❑通过执行负载均衡任务来管理流量。
❑提供基于主机名、路径的虚拟托管,以实现不同的参数映射至不同的服务。
❑通过SSL或TLS终止解密、加密流量。
2.Ingress体系解析
通常,Ingress体系由两部分组成,包括入口资源和入口控制器。
(1)入口资源
Ingress基于7层(L7)规则将主机名(和可选路径)定向到Kubernetes中的特定服务,以定义入站流量到达服务的规则。通过Ingress,可以配置外部URL、负载均衡传入流量、终止TLS,以及基于路径或前缀路由流量等。
通常情况下,我们可以在Kubernetes Ingress资源中指定DNS路由规则,将外部DNS流量映射到内部Kubernetes服务端点。
以下是一个基础的入口资源示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: devops-ingress
namespace: devops
spec:
rules:
- host: devops.apps.example.com
http:
paths:
- backend:
serviceName: devops-service
servicePort: 80
基于上述Yaml文件,所有对devops.apps.example.com调用的流量都应该被路由到devops命名空间中名为devops-service的服务。
需要注意的是,Ingress只是路由规则。我们可以为基于路径的路由添加多个路由端点,还可以添加TLS配置等。
关于入口对象,我们需要了解的关键事项具体如下。
❑入口对象需要入口控制器进行路由。
❑外部流量不会直接命中入口API,而是直接命中通过负载均衡器配置的入口控制器服务端点。
通常情况下,Kubernetes中的入口主要分为如下3种类型。
1)单一服务入口。单一服务入口是指只有一个服务向用户暴露的入口。要启用单一服务入口,我们需要定义一个默认后端服务,当入口对象中的主机或路径与HTTP消息中提到的主机或路径不匹配时,所有流量都会被定向到该默认后端服务。因此,在处理单个服务入口时,需要指定一个没有规则的后端服务。
单一服务入口示例可参考如下代码:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: devops-service
namespace: default
spec:
backend:
serviceName: devops
servicePort: 80
2)简单的扇出入口。简单的扇出入口通常允许使用单个IP地址来暴露多个服务,以便根据请求类型将流量路由到目标位置。这种配置可以轻松实现流量路由,同时减少集群中负载均衡器的数量。
简单的扇出入口示例可参考如下代码:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
namespace: default
spec:
rules:
- host: devops.example.com
http:
paths:
- backend:
serviceName: devops1
servicePort: 80
path: /devops1
- backend:
serviceName: devops2
servicePort: 80
path: /devops2
3)基于主机名的入口。基于名称的虚拟主机支持将HTTP流量从一个IP地址引导到在集群中运行的不同主机。在这种类型入口中,通常会先将流量引导到特定的主机,然后进行深入的路由。
基于主机名的入口示例可参考如下代码:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: devops-services
namespace: default
spec:
rules:
- host: devops1.example.com
http:
paths:
- backend:
serviceName: devops1
servicePort: 80
path: /
- host: devops2.example.com
http:
paths:
- backend:
serviceName: devops2
servicePort: 80
path: /devops2
(2)入口控制器
入口控制器是为了无缝管理Kubernetes和其他容器化环境而设计的负载均衡器。入口控制器通常使用标准的OSI模型中的传输层和应用程序层来操作从外部到Kubernetes集群内的服务或Pod的流量。
传输层(OSI模型中的第4层)揭示了模型中网络层之间的连接,而应用程序层(OSI模型中的第7层)涉及OSI堆栈中的应用程序端。在入口控制器中,通常会先将流量引导到特定的主机,然后再进行深入的路由。
通常,入口控制器在Kubernetes集群中主要执行以下任务。
❑允许从Kubernetes环境外部导入流量,并将其分配(负载均衡)到运行在Kubernetes平台的Pod或容器上。
❑管理需要访问特定集群外的服务以及与之交互的出口流量。
❑在Kubernetes集群运行的服务中添加或删除Pod时实时更新负载均衡规则,以确保负载均衡器能够正确地将流量分配到每个Pod。
从根本上来说,入口规则与处理流入网络或集群的HTTP流量的协议有关。对于缺乏规则的入口,所有入站流量都会被发送到默认的后端服务。
入口控制器是使用入口资源配置HTTP负载均衡器的应用程序,可以是软件负载均衡器,例如在集群中运行的负载均衡器,也可以是在集群外部运行的硬件或基于云的负载均衡器。市面上有各种类型入口控制器。选择合适的入口控制器对于Kubernetes集群的负载和流量管理至关重要。
在云原生架构设计中,入口控制器不是原生Kubernetes实现的,也就是说在集群中并不是默认存在的。因此,我们需要根据自身实际业务架构,设置入口控制器,以便入口规则能够正常运行。
入口控制器通常是集群中的反向Web代理服务器的实现,可作为Kubernetes中部署的反向代理服务器,暴露于服务类型负载均衡器。我们可以在集群中将多个入口控制器映射到多个负载均衡器。每个入口控制器都应该有一个名为入口类的唯一标识符并添加到注释中。
那么,入口控制器到底是如何工作的?
我们先来看一下基于Ingress控制器的实现原理参考示意图,具体如图2-6所示。
图2-6 基于Ingress控制器的实现原理参考示意图
这里,我们以Nginx入口控制器实现为例,来探究一下具体的工作原理。基于图2-7,可以得知:
❑Nginx Pod内的nginx.conf文件与Kubernetes入口API进行通信,并实时获取流量路由的最新值。
❑Nginx控制器与Kubernetes入口API交互,检查是否有为流量路由创建的规则。
❑如果发现入口规则,Nginx控制器会在每个Nginx Pod内的/etc/nginx/conf.d位置生成路由配置。
❑对于依据业务场景所创建的每个入口资源,Nginx都会在/etc/nginx/conf.d目录下生成对应的配置。
❑主目录下的nginx.conf文件包含来自etc/nginx/conf.d目录的所有配置。
❑如果使用新配置更新入口对象,Nginx配置将再次更新,并优雅地重新加载配置。
如果使用exec连接到Nginx Pod并检查/etc/nginx/nginx.conf文件,我们会看到该文件中应用的入口对象指定的所有规则。
这里,我们来看一下Kubernetes集群中入口和入口控制器的架构示意图。该示意图主要展示了如何通过Ingress将流量从负载均衡器路由至应用程序端的入口规则,具体如图2-7所示。
图2-7 基于Ingress控制器的架构参考示意图
通常情况下,我们使用服务资源在Pod内部或外部暴露应用程序:通过定义入口点自动将流量路由到可用的Pod上。由于Pod经常启动和停止,因此在特定时刻运行的Pod集合可能与后续运行应用程序的Pod集合不同。服务资源利用标签选择器对Pod进行分类,以便在应用程序需要扩展或压缩时能够快速找到并使用相应的Pod。
3.服务暴露类型
除了Ingress之外,Kubernetes集群中还有其他几种常用的服务暴露类型,包括ClusterIP、NodePort和LoadBalancer。它们提供了不同的服务暴露方式。需要注意的是,Ingress本身并不是服务,只是作为代理而存在,用于管理和路由流量。而ClusterIP、NodePort和LoadBalancer是实际提供服务的对象。
(1)ClusterIP
ClusterIP主要通过Kubernetes集群内部IP地址暴露服务。选择此种类型暴露服务可以实现服务只能在集群内部访问,这也是默认的服务暴露类型。
由于ClusterIP模式下无法从外部访问服务,因此可以使用Kubernetes代理来访问构建的服务。基于ClusterIP的流量访问架构参考图2-8。
图2-8 基于ClusterIP模式的流量访问架构参考示意图
出于调试目的,可以使用Kubernetes代理从外部访问集群IP。同时,在Pod中运行的应用程序实例可以使用集群IP进行内部通信。
ClusterIP模式下服务的Yaml文件参考如下:
apiVersion: v1
kind: Service
metadata:
name: devops-internal-service
spec:
selector:
app: devops-service
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
(2)NodePort
NodePort是一种服务暴露类型,主要用于在每个节点IP公开服务,并使用静态端口进行访问。在使用NodePort时,云平台会自动创建面向NodePort服务路由的ClusterIP服务。通过请求<NodeIP>:<NodePort>,我们可以从集群外部访问NodePort服务。
作为最简单的服务暴露类型,NodePort不需要进行复杂的配置,只需要将主机上随机端口上的流量路由到容器上的随机端口即可。NodePort适用于大多数情况,但也存在一些缺点。
❑可能需要使用反向代理(如Nginx)来确保正确路由Web请求。
❑每个端口只能公开一个服务。
❑每次启动Pod时,容器IP都会发生变化,从而无法进行DNS解析。
❑容器无法从Pod外部访问Localhost,因为没有配置IP。
基于NodePort模式的流量路由架构参考图2-9。
图2-9 基于NodePort模式的流量路由架构
对于NodePort类型的服务,其可用的端口范围是30000~32767,可以在Yaml文件中指定,也可以由Kubernetes自动分配。从图2-10中我们可以观察到,外部流量可以通过访问3个节点中任意一个节点的指定端口,从而到达NodePort服务并将被转发到特定的Pod。
NodePort模式下服务的Yaml文件参考如下:
apiVersion: v1
kind: Service
metadata:
name: devops-nodeport-service
spec:
selector:
app: devops-service
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30036
protocol: TCP
在上述Yaml文件中,服务将HTTP端口80映射到容器端口80(targetPort)。我们可以使用IP:PORT从外部访问该服务,其中IP是工作节点(VM)的IP之一,PORT是节点端口。如果我们没有指定nodePort字段,Kubernetes将为其分配一个默认值。
(3)LoadBalancer
对于在云平台上部署的Kubernetes服务,使用云供应商提供的负载均衡器是暴露服务的最佳方式。在使用此方式时,云供应商自动创建向外部负载均衡器暴露的NodePort和ClusterIP服务。
LoadBalancer是Kubernetes中最常用的服务暴露类型之一,作为一个标准的负载均衡器,在每个Pod上运行并与外部网络建立连接。通常,LoadBalancer可以连接到Internet或内部数据中心网络。我们可以根据目标端口号、协议和主机名路由流量,或使用应用程序标签将任何类型的流量发送到LoadBalancer。使用此方法可以直接暴露我们构建的服务。
基于LoadBalancer模式的流量路由架构参考图2-10。
图2-10 基于LoadBalancer模式的流量路由架构参考示意图
上述3种类型服务最根本的目的是提供Layer-4 TCP/UDP负载均衡,只是直接暴露应用端口。如果云供应商提供的服务支持自定义注解,那么LoadBalancer类型服务也可以实现Layer-7负载均衡。
基于Ingress的架构参考示意图如图2-11所示。
图2-11 基于Ingress的架构参考示意图
针对API网关和Ingress,本质上来说,在处理上游流量并将其路由至对应的服务器时,Ingress与API网关的工作原理是一致的。然而,Ingress在不同的网络堆栈级别中运行,即运行在Kubernetes环境中。
2.2.3 Gateway API
Gateway API是一种基于Kubernetes的新兴开源项目,旨在通过定义一组资源来创建一个统一的网关控制器,适用于更复杂的路由和负载均衡场景;同时还提供了可扩展和面向角色的界面。由于其强大的功能和灵活性,Gateway API被广泛应用,被视为Ingress的有力替代品。
1.Gateway API开发背景
初期,Ingress简单易上手且以开发者为中心。但随时间推移,Ingress变得功能丰富,就像多功能工具。一个典型的例子是,当基础设施团队向开发者提供Ingress服务时,采用类似Istio的方式,将API分解为资源,实现创建和使用入口隔离与基于角色的控制,支持基于L4和L7实现更复杂的路由和负载均衡。这种面向服务的网关更适应未来的用例。
尽管Ingress是一个多元化项目,但目前看来它的发展似乎已经停滞不前。作为各种平台和解决方案的集中地,Kubernetes项目的最大挑战是保持供应商中立。因此,Kubernetes社区提出了Gateway API,旨在通过定义一组资源(包括GatewayClass、Gateway、HTTPRoute、TCPRoute、Service等),在多供应商之间提供强大、可扩展和面向角色的接口,以推动Kubernetes服务网格发展并为开发者提供更多的选择。
2.Gateway API与Ingress的差异性
Kubernetes应用部署后,通常需要通过南北向流量的入口控制器暴露给用户。Ingress API定义了外部流量到Kubernetes服务的路由和映射,提供负载均衡、SSL终止及基于名称的虚拟托管。
目前,多种流行的入口控制器实现了Ingress API,如Nginx、HAProxy、Traefik等,在集群中管理和路由流量。这些控制器通过专有扩展实现高级负载均衡等功能。
Gateway API是Ingress的演进,通过扩展API提供原生高级功能。这些功能由单个供应商作为扩展实现,但不一致。现在,这些功能将由多个供应商按统一规范实现,以供用户选择。
Gateway API的重要补充包括HTTP和TCP路由、流量拆分以及面向角色的方法。该方法允许集群管理员和开发人员专注于与其职责相关的设置。相比之下,Gateway API在Ingress API之上添加了很多功能,例如基于HTTP Header的匹配、加权流量拆分、支持各种后端协议(如HTTP、gRPC等)以及其他后端(如Bucket、Functions等)。这些功能的引入使Gateway API在处理复杂流量路由时有更高的灵活性和可扩展性。
以下为基于Gateway API的Yaml文件参考示例,具体如下:
kind: HTTPRoute
apiVersion: networking.x-k8s.io/v1alpha1
metadata:
name: devops-route
namespace: devops
labels:
gateway: external-https
spec:
hostnames:
- "devops.example.com"
rules:
- forwardTo:
- serviceName: devops-v1
port: 8080
weight: 90
- serviceName: devops-v2
port: 8080
weight: 10
- matches:
- headers:
values:
env: canary
forwardTo:
- serviceName: devops-v2
port: 8080
相比Ingress API,Gateway API更好地实现了关注点分离。使用Ingress时,集群操作员和应用开发人员在不了解对方角色的情况下操作同一个对象,可能导致配置错误。
Gateway API通过独立创建Route和Gateway对象进行配置,给予了集群操作员和应用开发人员更多权利,使他们可以更加专注于自己职责范围内的任务。
3.基于Gateway API的流量管理架构
基于Gateway API的流量管理架构如图2-12所示。
图2-12 基于Gateway API的流量管理架构
SIG-Network社区为Gateway API提出以下实现目标。
❑面向角色。API资源用于管理Kubernetes服务网络,应支持以处理不同范围资源的组织角色进行建模,以便各司其职。基于不同的资源,我们可以划分不同的组织,以实现更好的管理。例如,集群运营商可以创建从GatewayClass派生的Gateway资源。该网关负责部署或配置所代表的底层网络资源。通过Gateway和Rout之间的路由附加过程,集群运营商和特定团队必须就可以附加到此网关并通过公开他们的应用程序达成一致。集群运营商可以在网关上实施集中式策略,例如TLS。
❑可扩展。网关API允许在API的各个层链接自定义资源。基于自定义资源进行扩展,从而实现API结构的精细化定制。
❑强大的表现力。API原生支持核心功能,例如基于标头的路由、流量加权,以及其他只有通过Ingress的自定义注释才能实现的高级功能。
❑可移植。从本质上来讲,Gateway API和Ingress一样,也应该是可移植的,并且遵循一个通用的规范。
4.Gateway API相关特性
Gateway API的主要设计目标是使不同的解决方案提供的Ingress功能保持一致,并提高可移植性。这意味着,当我们将工作负载转移到不同的提供商或编写多云解决方案时,将以相同的方式工作,而无需对规范进行大量更改。
除上述所述之外,Gateway API还包括其他一些值得关注的功能,具体如下。
❑GatewayClass:定义负载均衡的实现类型,使用户能够更清晰地理解Kubernetes资源模型的各种能力。
❑共享网关和跨命名空间支持:这些功能允许我们创建分离的网关和路由,支持根据团队的职责在团队之间进行网关共享。
❑类型化路由和类型化后端:Gatewy API提供对HTTPRoute、TCPRoute、TLS、UDPRoute等协议的支持,以覆盖所有类型的流量路由。
在实际的业务场景中,高级路由是Ingress最为欠缺的地方,目前的解决方案是基于服务网格实现的,变得复杂且与网格实现紧密耦合。那么,Gateway API具备哪些特性?
(1)基础网关
Gateway API是一种类似于Ingress的流量调度模型,通过网关控制器管理负载均衡器,将所有到达的流量发送到服务。这样,服务所有者便拥有了更多的自主权,可以更加灵活地暴露和管理自己的服务。
(2)基于HTTP/TCP路由
通过HTTPRoute,我们可以根据过滤器将流量路由至多个服务,以实现不同的业务目标。除此之外,Gateway API还支持多种协议,包括TCPRoute等。
(3)HTTP流量拆分
基于Gateway API模型,我们可以进行加权流量路由,将其与A/B测试或金丝雀部署等策略相结合,以简单的方式实现复杂部署。例如,HTTPRoute将流量按照95∶5的比例进行拆分,并将其分别发送到服务1和服务2等。此外,我们还可以使用过滤器实现基于标头的路由,以实现更精细的流量控制。
基于Gateway API的HTTP流量拆分示意图可参考图2-13。
图2-13 基于Gateway API的HTTP流量拆分示意图
(4)TLS
Gateway API支持在客户端和服务之间的网络路径中配置不同点的TLS,即实现独立的上游和下游TLS配置。根据监听器配置,我们可以使用各种TLS模式和路由类型,并实现对证书管理器的集成支持,以便管理和更新证书。这些特性可以帮助用户更好地保护服务安全和可靠,确保客户端和服务之间的通信得到充分保护。
基于Gateway API所支持的上下游TLS配置参考示意图如图2-14所示。
图2-14 基于Gateway API的上下游TLS配置参考示意图
(5)与渐进式交付工具集成
Gateway API的相关特性和高级路由使其可以与各种渐进式交付工具(如Flagger)集成,从而为高级部署策略(如蓝绿和金丝雀部署)提供支持。
Gateway API已经发展成为为基础设施提供商、集群运营商和应用程序开发人员等实施者提供富有表现力、可移植和可扩展的API规范。虽然,Gateway API目前还不能完全替代Ingress,但我们应该尽可能地使用,因为确实为开发人员提供了更多的选择,而无需引入大量注释或不可移植的更改。
此外,服务网格和Ingress控制器都实现了Gateway API,并支持Flagger和cert-manager等工具。随着Gateway API在CNCF生态系统中变得越来越流行,我们应该期待更多的项目加入进来,从而为用户提供更多的选择和支持。