1.前言
(点击可查看大图)
虽然只是一个简单的测试页面,但是它背后是一套完整基于k8s的spec驱动的云原生网络,控制面通过CRD声明式定义DNS,多链路的虚拟IP以及负载均衡。整套系统的数据面从边缘节点到数据中心是纯软件负载,并且实现全链路加密。中间至少经过了3次IPVS,4次Envoy,4次TLS termination,7次主机网络和容器网络的切换,以及若干软硬件防火墙,最后实现了一个从公网到内网全链路加密的网络。里面还有很多技术细节,比如统一的流量管理模型,同时集成Contour和Istio IngressGateway以及Service Mesh,公网和内网证书的自动化等等。
总结下云原生网络的几个主要特点应该包括低成本,高可用,高安全,配置轻量以及弹性扩容,这些都是硬件负载均衡所不具备的。
2.流量管理现状
eBay原本数据边缘以及数据中心全面采用的是F5以及Citrix的硬件负载均衡,有数千对硬件负载均衡设备支撑着全站点的生产环境流量。近年来公司内部通过启动了不同的项目来全面推荐硬件负载均衡设备替换为软件负载均衡,并且也取得了一定的成功。
2.1数据边缘公网流量管理现状
数据边缘,或者称为POP,主要作用是接入公网流量到数据中心。这一部分通过UFES项目已经基本将所有公网流量接入到软件负载均衡,具体可以参考:eBay边缘节点的云原生网络实践
2.2数据中心内网流量管理现状
eBay数据中心主要是通过两层硬件负载均衡设备将内网流量最终转发到服务器。之所以会有两层硬件负载均衡设备,主要出于以下几点考量:
1. 防止客户端缓存VIP造成数据面影响。在一层LB的情况下,如果单个集群的VIP以及服务器整体宕机,由于客户端本地DNS缓存,流量依旧可能转发到该VIP。在两层LB的情况下,我们能够容忍App VIP以及以下的服务端整体宕机,流量可以从Web VIP层转发到其它的数据中心。
2. 精确控制流量。在一层LB的情况下,流量的控制只能通过GTM采用ratio的方式解析DNS,但同样因为DNS缓存的原因,GTM无法精确控制流量。而在两层LB的情况下,数据中心的流量可以在Web VIP层精确控制。
(点击可查看大图)
但是由于硬件负载均衡的限制,目前eBay的数据中心对于高安全的PCI(Payment Card Industry )以及RNPCI(Restricted Non-PCI)生产环境采用的是1层硬件负载均衡(只有App LB),以实现端到端加密,其架构图如下。虽然这种架构在流量管理以及故障容灾方面有所限制,但是这也是我们目前工作的重点,实现1层软件负载均衡,完成PCI/RNPCI环境应用到软件负载均衡的迁移。
(点击可查看大图)
相对于公网数据流量接入软件负载均衡,数据中心的软件负载均衡项目启动相对较晚。公网以及内网流量需要处理的问题以及面对主要的挑战也各有不同。
公网流量
1. 高安全性。需要有能力防止各种安全攻击,比如ddos,robots,以及相关的ACL控制。
2. 全球分布。需要在全球部署,尽可能的靠近用户以加快用户的访问数据。
3. 控制面复杂性。公网流量控制面的复杂性主要在于L7规则比较数量比较多,将近3000条L7规则。但是相应的接收流量的Service/Endpoint的数量并不是很大。
内网流量
1. 超大规模。由于微服务架构,生产环境3000+应用,数万个VIP,数十万个Pod。
2. 高安全性。由于合规要求,支付相关的应用必须全链路加密,并且集成软件防火墙。
3. Istio生产可用。由于我们采用的软件负载均衡方案是Istio,而Istio直到2019年才生成可用。
3.统一流量模型
3.1 NameService
NameService是eBay定义的一种联邦级别的管理DNS记录的资源。由于eBay应用多k8s集群部署的方式,需要有一个联邦资源统一管理应用的DNS记录,包括创建A记录,CNAME等。另外eBay的生产环境采用的是GTM,可以认为是一种智能的DNS,在解析域名的同时能够提供健康检查,流量控制等功能。并且GTM同时也会区分内网以及公网,这样也就需要NameService资源能够实现多种provider,提供统一的域名管理功能。NameService的sample spec 如下:
(点击可查看大图)
3.2 AccessPoint
AccessPoint是eBay定义的另一种联邦级别的管理流量接入的资源。在多集群部署的模式下,一个应用会在不同k8s集群部署流量接入网关,因而需要一个联邦资源进行统一管理。
另外由于Istio以及k8s中定义了很多流量管理的资源,比如Gateway,VirtualService,DestinationRule,ServiceEntry,WorkloadEntry以及Service等,定义了AccessPoint资源也是为了便于统一管理这些资源。用户只需要通过Federated APIServer创建一个AccessPoint,相应的联邦控制器会将资源同步到用户指定的集群,而集群中的控制器会进一步创建在AccessPoint定义的Istio/Kubernetes资源。
eBay数据中心应用采用的是Istio作为软件负载均衡,AccessPoint中的资源天然支持所有Istio社区的功能,包括证书配置,L7规则配置等等。目前eBay数据中心的应用已经大量采用AccessPoint以及Istio实现了生产化的部署。
而eBay的数据边缘由于历史原因采用的是Contour管理公网的流量,这里我们仍然决定采用统一的模型来管理公网的流量,出于以下几点考虑:
1. Istio社区定义的资源已经有很明确的语义和很高的接纳程度,我们不需要再重复造轮子。
2. 尽管Contour有自己的CRD IngressRoute,它在很大程度上和Istio的CRD是类似的,我们可以在实现层面通过转换器屏蔽掉这种差异。
3. 继续保持AccessPoint spec作为面向用户的统一的接口。
4. 长期计划是通过Istio替换掉数据边缘的Contour。
因此对于公网和内网的流量管理,我们采用了统一的AccessPoint模型,这样也降低了用户的学习成本。下图是用户创建一个AcessPoint的流程图:
AccessPoint统一流量管理模型
(点击可查看大图)
下面的表格是AccessPoint资源的主要Spec,里面主要封装了Isito和Kubernetes的资源,同时能指定资源需要同步到的集群。并且,该Spec能够在不同的集群中通过修改模板属性值来进行定制。此外,还能在Spec中指定流量策略,比如运行时的策略、不同数据中心的流量权重以及发布策略,主要是指在执行L7规则变更的过程中能支持对不同可用区以及k8s集群逐个变更。
最后一部分是状态的收集和汇总,每个集群的网关VIP、证书、FQDN的状态都会同步到Fedrated APIServer,能够给用户提供一个全局的状态。
(点击可查看大图)
3.3 AdminTrafficControl
ATC(AdminTrafficControl)是eBay定义的另外一种联邦级别的流量管理资源,用声明式的方式实现对eBay全站流量的管理,主要目标是需要实现在30s钟之内将一个数据中心的流量停掉。
eBay目前生产环境采用三数据中心部署方式,每个数据中心会有多个可用区。通过引入ATC,能够使SRE/TDO在日常维护或者数据中心出现故障的时候快速将故障的数据中心或者可用区的流量退出。目前ATC支持多种流量退出的方式:
1.支持NameService的流量退出,通过disable NameService的NameRoute实现,后端的实现是GTM的DNS解析不会返回处于disable状态的VIP。
2. 支持AccessPoint的流量退出。
3. 支持单个应用的流量退出。
4. 主持全站应用的region/az流量退出。
ATC示例spec如下:
(点击可查看大图)
4.多层流量管理架构
eBay在应用硬件负载均衡的时候引入了层(tier)的概念,主要是指负载均衡的层数,以提供更完善的流量管理能力。根据负载均衡设备所处的不同流量转发位置,我们称之为web tier以及app tier。
目前数据中心生产环境全部采用2 tier的架构,也就是有两层LB。但是在与支付相关的高安全性的PCI/RNPCI环境中,目前我们采用的是一层LB,也就是1 tier。
对于公网的流量,我们已经通过UFES项目将eBay的公网流量接入到软件负载均衡,并且将公网的流量拆分成了前端代理(Front Proxy)与数据中心网关(Data Center Gateway)两层架构。然而因为之前数据中心并没有软件负载均衡,所以数据中心网关对接的还是App Tier层的硬件负载均衡设备,也就是3层LB架构。
在统一的流量管理模型中,我们为软件负载均衡提供了与硬件负载均衡一致性的功能,目前已经支持1层的内网流量,同时支持3层的公网流量。
4.1 内网流量 1-Tier
由于eBay采用3数据中心的部署方式,同一个应用会在不同的数据中心创建VIP,一层的架构主要是将3个数据中心的IPVS VIP配置到GTM,其架构图如下:
(点击可查看大图)
流量管理功能
1. 网关VIP配置在GTM,通过DNS解析返回不同的IP给客户端
2. GTM会对后端的VIP做TCP的建卡检查
3. 没有跨数据中心的流量
故障转移
1. 依靠GTM的健康检查,将不健康的VIP标志为不可用
2. 如果应用在一个数据中心的服务器全宕机,客户端的DNS缓存会导致数据面的影响
4.2 公网流量 3-Tier
公网流量是直接面对外网的用户的流量,根据地理位置的不同我们称之为PoP或者前端代理,它们会将用户的请求接入到数据中心,再进一步接入到最终的应用服务器。
这里的3层分别是:前端代理,数据中心网关以及应用网关。其中前端代理以及数据中心网关目前是通过IPVS以及Contour实现,而应用网关则是通过IPVS以及Isito实现,具体可以参考eBay基于Istio的应用网关的探索和实践。其中UFES L4以及TLB都是基于IPVS,但是在控制面实现有所不同。其架构图如下:
(点击可查看大图)
从图上可以看出,内网流量只经过1层软件负载均衡,而公网流量会经过3层,其中每一层在功能上各有不同。
前端代理:主要暴露公网IP,配置安全相关的策略比如防止DDOS,Robots等等。
数据中心网关:配置内网IP,并且作为前端代理的下一跳。主要配置应用转发的相关的7层规则。
应用网关:配置内网IP,既作为数据中心网关的下一跳,同时也是通过IGTM直接接入内网的流量。
需要指出的是,不管是公网流量还是内网流量,在现在的架构中都支持端到端加密,并且集成了软件防火墙。
5.流量管理模型
在eBay的生产环境中,同时会有多种类型的流量,包括公网流量,内网流量以及七层转发规则的流量。多数据中心以及多层软件负载均衡的架构也增加了流量管理的复杂的,因此我们需要一套统一的模型来管理各种类型的流量。
5.1 Upstream/Downstream AccessPoint
这里我们引入了Upstream AccessPoint以及Downstream AccessPoint的概念,这个概念有点类似于Envoy中的Upstream以及Downstream,但是区别在于这里的上下游AccessPoint其实是一组Service/VIP,因此它本质上管理的是service到service之间的流量转发。
Downstream AccessPoint: 下游AccessPoint中的service连接到上游AccessPoint的service,将请求发送到上游并且接收来自上游的响应。
Upstream AccessPoint: 下游AccessPoint中的service接收来自下游AccessPoint中service的连接以及请求并且返回响应。
上下游AccessPoint流量模型将AccessPoint当成一个积木(building block),通过组合的方式能够灵活管理各种类型的流量,避免了将所有配置塞到一起变成一个复杂庞大难以管理的spec,从而也减少了控制面板的复杂程度。这种流量模型适用于:
公网内网流量
默认流量以及7层转发规则流量
1/2/3层网络拓扑的流量
其架构图如下:
(点击可查看大图)
5.2 AccessPoint Connector
上下游AccessPoint的流量模型将复杂的流量拆解成两个AccessPoint之间的流量转发。但是这也带来一个问题,下游的服务如何发现上游的服务并且感知上游服务的变化?
这里我们引入了另外一个组件,AccessPoint连接器,它本质上是一个服务发现的控制器。通过在下游的AccessPoint中的ServiceEntry配置upstream AccessPoint注解的信息,AccessPoint Connector会自动发现上游的服务信息并且以WorkloadEntry的方式回填到downstream的AccessPoint中。所以AccessPoint Connector就像是给上下游AccessPoint建立连接的桥梁。其架构图如下:
(点击可查看大图)
由于AccessPoint是一个联邦资源,并且上下游的服务可能会在不同的k8s集群,比如数据中心网关和应用网关通常会部署在不同的集群。因此AccessPoint Connector也会同时部署在联邦控制面以及集群控制面。
联邦控制面:拥有全局视角,能够实时发现和监控全局的AccessPoint的变化,它能发现上游AccessPoint的服务并且通过WorkloadEntry的方式配置到下游的AccessPoint.
集群控制面: 监控集群内部的AccessPoint/ServiceEntry/WorkloadEntry,生成相应的Envoy配置,最终推送到Envoy。
5.3 AccessPoint Override
因为AccessPoint是一个联邦级别的资源,它带来的一个好处是我们可以通过定义一份spec然后将其复制到多个指定的k8s集群,这样能够避免多个集群之间spec的不一致性。但是它也同样带来了一个挑战,也就是在一些场景下我们需要能够支持不同的集群之间spec存在差异性,比如:
为不同的集群配置不同的到上游服务的WLE的流量权重
能够直接单个集群的流量退出而非整体退出
这里我们引入了override的机制。早期的override是通过json patch的方式实现,但是因为它是非结构化并且可读性很差,因而被废弃。目前我们采用的是merge patch的实现机制,简单的说它就是复制了一份ScopedAccessPointSpec数组用来保存定制的spec,然后通过merge patch的机制能够实现cluster级别的定制,其结构如下:
(点击可查看大图)
6.公网对接内网流量管理
通过统一的流量管理模型,我们已经能够在控制面对公网流量以及内网流量进行统一的管理,并且屏蔽了不同层的软件负载均衡控制面的差异。然而在公网与内网的流量对接中,我们仍然会遇到一些数据面的挑战,比如Istio社区默认强制使用SNI以及如何对不同层级的软件负载均衡进行流量退出。
6.1 SNI(Server Name Indication)管理
6.1.1 SNI模式
Istio社区默认使用的是SNI,也就是Envoy会监听在0.0.0.0地址而非真正的VIP的地址,然后通过SNI匹配不同的证书以支持实现多域名。但是这也存在一些问题:
一些比较旧的client不支持SNI,因此在TLS握手过程中会出现connection reset。
Envoy端口协议冲突。比如8888端口如果被定义成HTTPS gateway就无法再作为别的协议使用。
无法区分Downstream metrics,因为只有一个0.0.0.0_8443的listener,无法区分连接不同VIP的客户端的流量指标.
Gateway以及VirutalService Host冲突。这种冲突在L7转发规则中很突出,甚至会导致无法支持L7规则: 因为为了支持主机匹配的L7转发规则,需要将同一个host配置到上游以及下游的AccessPoint中,但是在SNI的场景下并不能支持,会导致host冲突。
以下是在SNI场景下数据流程以及相应的控制面板配置:
用户通过curl访问https://foo.vip.ebay.com
GTM解析DNS,将某一个集群的应用网关VIP返回给客户端。
请求被转发到某一个4层的IPVS pod,4层Pod的路由是通过BGP宣告实现。
IPVS pod基于IPVS规则将请求通过IPIP tunnel转发到后端服务器,也就是7层的IngressGateway pod。
IngressGateway pod解封数据包,然后经过Envoy的过滤链将请求最终转发到后端的真实应用服务。
IngressGateway和应用pod之间通过mTLS方式传输,应用在处理完请求后将响应放回给IngressGateway pod。
IngressGateway 通过DSR(direct server return)将响应最终返回给客户端。
(点击可查看大图)
6.1.2 None SNI模式
Istio 1.10版本在Gateway资源上引入了一个bind的属性,主要是用来绑定unix domain socket或者localhost到Envoy listener。在我们的场景下,可以通过该bind属性来绑定VIP,这样可以为每个VIP创建Envoy listener,同时通过给Gateway以及VirtualService设置“*”host的方式来实现停用SNI,也就是客户端在不支持SNI的情况下依旧能够TLS握手成功。
但是这里的None SNI模式并非真正签发一张wildcard SAN的证书,这样是很不安全的,而是通过在gateway配置wildcard host,达到了为每个VIP配置一张默认证书的效果。这里我们在使用过程中也遇到了Istio社区的一个bug:只能支持一个VIP配置wildcard host,因为社区并没有考虑到我们的这种4层加7层的使用方式,相应的修复我们也已经提交PR并且合并到社区。
以下是支持none SNI数据流程以及相应的控制面配置。可以看到控制面和数据面都有一些变化,最主要的是Envoy监听在VIP而不是0.0.0.0并且在Envoy的控制面能看到已经给VIP拆分了单独的listener:
(点击可查看大图)
6.2 流量退出管理
6.2.1 公网流量退出
公网流量退出主要是将前端代理的流量退出。这里的退出公网流量的接口是ATC,实现的机制是通过将公网NameService上相应的数据中的公网VIP的enable状态标志为false,然后GTM设备会停止将该VIP返回给客户端,从而实现停止该VIP的公网流量。其架构图如下:
(点击可查看大图)
这种流量退出机制存在一些限制,比如DNS TTL或者客户端DNS缓存的原因,需要等待一段时间才能将流量停止。
6.2.1 内网流量退出
内网流量分为数据中心网关以及应用网关,流量退出的接口依旧是ATC,但是实现的机制是通过将下游AccessPoint中对应的上游AccessPoint服务的WorkloadEntry的状态设置为False来实现停止流量,需要指出的是同一套机制适用于Contour以及Istio。
数据中心网关流量退出
将前端代理中指向数据中心网关服务的WorkloadEntry健康状态标志为False,前端代理将停止转发流量到该上游数据中心网关。
将数据中心网关指向应用网关服务的WorkloadEntry健康状态标志为False,数据中心网关将停止转发流量到该上游应用网关。
应用网关流量退出
对于1层软件负载均衡的网络拓扑,通过将内网NameService对应的VIP状态标志位False以停止DNS解析返回该VIP。
对于2层软件负载均衡的网络拓扑,同样是通过将WorkloadEntry健康状态标志为False的方式停止将流量转发到上游的VIP。
内网流量退出架构图如下:
(点击可查看大图)
7.L7规则管理
eBay数据中心在公网流量和内网流量都配置了大量的七层转发规则,因此也需要AccessPoint能够支持统一的L7规则管理。这里我们采用的是Istio社区的CRD来统一定义L7规则的spec,然后通过的不同的provider来配置不同的控制面的7层规则。从用户的角度来说只有一种spec,也减少了用户的学习成本。其架构图如下:
(点击可查看大图)
7.1 公网L7规则管理
eBay在几个主要的站点上都配置了大量的L7规则,比如www.ebay.com以及m.ebay.com等。这些规则之前在UFES项目中已经从硬件负载均衡迁移到了基于Contour的软件负载均衡。在UFES项目中为了同时适配硬件负载均衡以及软件负载均衡,由LBMS提供了统一的接口管理两者,所以目前对于公网L7规则的管理仍然使用的是LBMS接口。
Contour本身定义了CRD IngressRoute,然而在迁移的过程中为了考虑与硬件负责均衡L7规则的兼容性,我们也做了大量的定制,增加了一些额外的属性,比如Netscaler priotiry, Nescaler Name, 还增加了一些特殊的转发规则比如forewardrewrite等。为了适配IngressRoute,在不修改Istio api的前提下,这里我们采用了给VirutalService增加注解的方式来保存这里额外的属性,其架构图如下:
(点击可查看大图)
公网流量管理的长期的发展方向是用Istio替换Contour,最终这些annotation会被转换成VirtualService的spec,但前提是我们需要将Istio这边缺失的功能补充完整。
7.2 内网L7规则管理
相对于公网的转发规则需要增加注解保存额外的属性,内网的7层流量转发规则完全用Istio的语义,其流程图如下:
(点击可查看大图)
这里需要解决的几个问题是:
将Netscaler的语义转换成Isito的Gateway以及VirutalService spec,并且完成控制面和数据面的验证。
Netscaler提供了一些安全相关的规则,比如DROP/RESET,Istio社区目前并不支持。这里我们需要在Istio/Envoy支持这些功能。目前的方案是通过编写Envoy内置的filter来实现,并通过EnvoyFilter CRD来配置。
Netscaler存在一些特殊的规则,比如下面这种带运算的规则。目前Istio也不支持,也需要通过EnvoyFilter的方式来实现。
(点击可查看大图)
8. 小结
这个项目是在公司另外一个叫ContainerPDLC迁移项目的背景下推进的,而ContainerPDLC项目是目前公司内部的最高优先级。我们期望通过该项目能够同时实现以下目标:
1. 实现云原生的应用部署方式;
2. 实现安全环境全软件防火墙;
3. 实现流量全链路加密以及高可观测性;
4. 实现数据中心全软件负载均衡以及云原生网络。
这里面每一个目标在eBay的规模下都是一个不小的挑战,我们也遇到了各种各样问题。有社区的,应用本身的,还有因为规模带来的性能问题等等。而其中软件负载均衡以及流量管理是处于一个基石的位置,因为用户遇到的任何问题都会怀疑和网络有关,其中的灵魂拷问是为什么我的应用在硬件负载均衡上能够工作,但是在Istio以及Mesh的环境下出现了问题?
这是一个我们需要不断回答的问题,而且一路过来我们解决了各种遇到的不管是数据面还是控制面的问题,并且都能找到根因,从kernel层面,源码层面以及协议层面去理解和解决这些问题。
ContainerPDLC项目在今年年初启动迁移,目前我们已经有将近400个生产环境应用完成迁移,峰值30Gb/s流量运行在PCI/RNPCI的生产环境,预期我们将在明年一季度完成全量的迁移。
基础设施的转型是一个风险很高的事情,新生的技术本身也充满了挑战,我们需要直面这些挑战。但是最最重要的是,我们有很强有力的跨部门以及团队合作,并且所有人都在实践中快速学习和成长。引用一句同事冷教练的话:“我们一起把事情做成,一起反思成长”。这也是我们大家努力的方向。
下一步我们需要将数据中心生产环境2层负载均衡的架构迁移到基于Istio的应用网关,以实现先更完善的流量管理功能以及更强的故障容灾能力。
END