引言
统一接入作为阿里巴巴集团7层应用流量入口网关,其技术底座Tengine作为高性能的HTTP和反向代理web服务器,日常承载千万级QPS流量,为双11等各类大促活动保驾护航,对外提供永不停机的HTTP(S)接入服务。
虽然Tengine以高性能和高可用著称,但统一接入的一些限制却一直为人诟病,最典型的就是应用域名新增和更新无法动态生效;新增证书和加签域名无法动态生效;用户侧HTTP(S)流量可配置性和可观测性能力弱;HTTP(S)路由能力弱;不支持应用分域名灰度变更;接入层集群变更范围影响过大等问题也一直困扰着我们。
随着云原生ingress入口网关规范的事实标准化以及阿里集团ASI的大范围落地,统一接入新应用AServer-Ingress基于云原生ingress标准实现了统一接入层的架构升级,其技术底座Tengine-Ingress在深度优化kubernetes/ingress-nginx基础上融合Tengine-Proxy,不断提升自身性能和可用性,彻底根除了上述痛点和问题,并已反哺开源社区,持续保持Tengine业界领先地位。
Tengine官网: https://tengine.taobao.org
Tengine-Ingress开源仓库: https://github.com/alibaba/tengine-ingress
Tengine开源仓库: https://github.com/alibaba/tengine
术语
- AServer-Ingress: 基于K8s云原生ingress标准,实现阿里统一接入层架构升级的新应用,为集团淘宝,天猫,高德,阿里妈妈,国际化,菜鸟,UC,钉钉,考拉等BU提供稳定的7层应用流量入口网关。
- Tengine-Ingress:应用AServer-Ingress的技术底座,在深度优化kubernetes/ingress-nginx基础上融合Tengine-Proxy。
- K8s: Kubernetes简称为K8s,K8s是用于自动部署、扩展和管理容器化应用程序的分布式系统。
- ASI:AlibabaCloud Serverless Infrastructure的简称,面向云原生应用的统一基础设施,提供全托管和半托管K8s集群运维服务。
- ingress: K8s集群向外部提供访问集群内部服务的HTTP(S)七层负载均衡,TLS卸载和路由转发的系统原生资源。
- annotations: 注解,ingress通过注解 (annotations) 来扩展七层负载均衡,TLS卸载和路由转发相关的配置信息。
- etcd: 用于存储K8s集群中配置数据的一种持久性,轻量型,分布式的键-值数据存储组件。
- API server: API服务器是K8s集群的一个关键组件,通过K8s API和JSON over HTTP提供K8s的内部和外部接口。API服务器处理和验证REST请求并更新API对象在etcd中的状态,从而允许客户端在工作节点之间配置工作负载和容器。
- CRD: CustomResourceDefinition的简称,用于定义API服务器上可公开访问的用户自定义资源。
- MD5: Message-Digest Algorithm的简称,一种被广泛使用的密码杂凑函数,可以产生出一个128位元 (16个字节) 的散列值,用于确保信息传输完整一致。
架构
应用AServer-Ingress作为7层应用流量入口网关,公网HTTPS请求首先路由到4层负载均衡SLB,SLB在4层将HTTPS报文转发到7层网关AServer-Ingress,AServer-Ingress基于动态ingress域名和secret证书本地卸载TLS,基于单元化和路由策略向后端应用转发HTTP请求。
图1. 应用AServer-Ingress系统架构图
应用AServer-Ingress的技术底座Tengine-Ingress由两部分组成,Tengine-Ingress控制器和Tengine-Proxy。Tengine-Ingress控制器是一个基于Tengine-Proxy的ingress控制器,在兼容云原生ingress标准规范的基础上扩展了Server,Backend,TLS,Location和Canary。Tengine-Ingress控制器通过订阅和处理ingress域名资源和secret证书资源,基于tengine ingress模板转换为动态配置写入共享内存。Tengine-Proxy订阅共享内存变化写入内部运行时共享内存,将终端用户的外部流量路由到K8s集群中的应用服务。
图2. Tengine-Ingress网关架构图
Tengine-Ingress在Tengine基础上新增很多新特性和功能,最显著的变化是配置动态无损生效,无论是应用域名新增和路由变更,还是证书新增和加签域名,都无需tengine reload,配置无损实时生效,长连接保持不变,成功率不受影响,应用变更效率提升翻倍,集群稳定性进一步得到增强。支持分域名和单证书独立分批次逐级生效,用户可按需中断和继续变更,应用侧风险可控,变更影响面小。TLS加解密允许同时加载ECC,RSA和国密多证书。在应用域名灰度方面,支持基于request header,header值,header值正则匹配,cookie和权重的流量切分,满足应用在灰度发布,蓝绿部署和A/B测试不同场景的需求。在可观测性方面,支持应用分域名独立监控,用户可实时查看单域名QPS,成功率,RT和报文大小相关的监控信息。Tengine-Ingress复用k8s ingress注解(高级配置)规范,基于内部运行时共享内存,通过tengine ingress模板构造HTTP(S)高级功能,支持动态无损实时生效,满足用户基于不同应用场景下的HTTP(S)高级配置需求,例如用户可配置应用域名是否允许网络爬虫和应用域名CORS (跨域资源共享)。综上所述,Tengine-Ingress在应用配置更新模型,系统稳定性,TLS加解密,灰度路由,可观测,HTTP(S)高级配置等多方面得到了显著提升。
云原生
Tengine-Ingress全面兼容K8s ingress标准,在此基础上不断扩展和完善,相对于原生Kubernetes Ingress和NGINX Ingress,主要有以下优点和增强:
支持域名和证书接入的无损动态实时生效, Tengine-Ingress控制器实时监听ASI ingress存储集群中的ingress域名和secret证书资源对象,在ingress域名和secret证书配置发生变化时,校验域名和证书配置的合法性和全局一致性,符合ingress标准和X509证书规范的配置信息将全量写入系统共享内存。Tengine-Proxy感知系统共享内存变更,strategy进程刷新运行时共享内存,双缓存切换,worker进程运行时读取配置动态生效。
图3. 配置动态生效模型
Tengine-Ingress支持域名同时使用ECC和RSA双证书,默认原生系统只能使用单张证书,Tengine-Ingress扩展标准ingress规范,在兼容单证书的场景下,满足ECC和RSA双证书同时动态生效的应用场景,且可以继续扩展为ECC,RSA和国密的三证书复杂场景。
tls: -hosts: - {host1} secretName: {secretname1} -hosts: - {host1} secretName: {secretname2}
Tengine-Ingress在基于云原生ASI的基础上,利用标准化的k8s资源ingress和secret分别存储域名路由配置和TLS证书秘钥信息,在此基础上提出单个ingress域名和单张secret证书分批次逐级生效机制,这不仅满足了用户侧新增和修改应用域名和证书的灰度需求,同时保障接入层集群整体运行的稳定性和可靠性。新增下述ingress和secret注解,用于标识域名和证书逐级分批次灰度范围。
1.ingress灰度开关●annotation: nginx.ingress.kubernetes.io/ingress-rollout注释:是否灰度ingress值类型:bool默认值:false2.ingress当前版本●annotation: nginx.ingress.kubernetes.io/ingress-rollout-current-revision注释:ingress当前运行版本号值类型:string默认值:""3.ingress升级版本●annotation: nginx.ingress.kubernetes.io/ingress-rollout-update-revision注释:ingress升级版本号值类型:string默认值:""4.ingress灰度范围●annotation: nginx.ingress.kubernetes.io/ingress-rollout-index-id注释:只有Pod序号小于ingress-rollout-index-id的Pod才会更新ingress。○0..N-1为Pod所在的序号,从0开始到N-1。○ForaStatefulSetwithNreplicas, eachPodintheStatefulSetwillbeassignedanintegerordinal, from0upthroughN-1, thatisuniqueovertheSet. 值类型:number默认值:-1
Tengine-Ingress通过全局一致性校验机制保障内存中运行态持有的用户侧ingress域名和secret证书的有效性和正确性,秒级校验10w+域名和1000+泛证书,在域名配置和证书信息不符合标准化k8s资源ingress和secret规范及其相关RFC标准时,将不再更新本地缓存,并实时告警通知,保障运行态永远可正常向外提供7层转发服务。新增CRD IngressCheckSum和SecretCheckSum,用于定义全局一致性校验信息。
typeIngressCheckSumstruct { metav1.ObjectMetaSpecIngressCheckSumSpec} typeIngressCheckSumListstruct { metav1.TypeMetametav1.ListMetaItems []IngressCheckSum} typeIngressCheckSumSpecstruct { // `Timestamp` is the time when the md5 of all the ingress was calculated.Timestampmetav1.Time// `Checksum` is the md5 of all the ingress.Checksumstring// `ids` describes which id will match this ingress.Ids []string}
Tengine-Ingress复用k8s ingress注解(高级配置)规范,基于内部运行时共享内存,通过tengine ingress模板构造HTTP(S)高级功能,支持ingress注解动态实时生效,满足用户基于不同应用场景下的HTTP(S)高级配置需求。Tengine-Ingress在兼容ingress canary注解的基础上,支持基于request header,header值,header值正则匹配,cookie和权重的流量切分,无需tengine reload,所有应用域名的ingress金丝雀规则实时动态无损生效。
图4. 基于“Header值”和“服务权重”的灰度路由组合
ingress标准:https://kubernetes.io/docs/concepts/services-networking/ingress/
X509证书规范:https://datatracker.ietf.org/doc/html/rfc5280
ingress canary注解:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary
高可用
Tengine-Ingress作为7层流量入口网关应用AServer-Ingress的技术底座,对于高可用有严苛的要求。任何的变更操作都必须可灰度,可监控,可回滚。然而,K8s原生资源对象包括ingress域名,secret证书,configmap配置,service服务等,在被写入etcd后,所有监听控制器默认都会处理资源对象的配置更新,即相同命名空间内的所有Pod会同时加载新的配置对象,如果配置存在错误和脏数据,变更影响将会触发全局风险,导致线上事故。统一接入每天大约存在上百次的应用域名新增,修改和删除的变更操作,每周都存在数十次的证书新增和加签域名的变更操作,接入层任何一次应用域名和证书的配置变更都至关重要。Tengine-Ingress作为云原生网关,必然通过K8s API处理和验证资源对象,这就需要我们扩展支持ingress应用域名和secret证书的灰度能力,保障变更操作的可灰度,可中断和可回滚。
以ingress应用域名变更为例,按照相同命名空间内Tengine-Ingress Pod数量,通过新增的ingress灰度注解确定每批次ingress资源对象动态生效的Pod范围。配置变更Pod范围内的Tengine-Ingress监听到ingress资源对象的更新事件,校验域名配置的合法性和全局一致性,将符合ingress标准的配置信息全量写入系统共享内存。在ingress域名分批次灰度生效的变更过程中,用户可以基于应用域名成功率等监控指标随时主动终止和回滚本次配置变更,将风险缩小到可控范围内,保障应用域名变更的可灰度,可监控,可回滚。
图5. Ingress域名和Secret证书配置分批次逐级生效模型
Tengine-Ingress通过ASI core集群与ASI ingress存储集群相隔离的高可靠性方案,将运行态和存储态相分离,独立ASI ingress集群可以保证自身API服务器和etcd性能稳定,并且在core集群核心组件API服务器和etcd不可用的高危场景下也能正常向外提供7层转发服务。以ASI ingress存储集群标准3实例API服务器 (16C64G, 100G ESSD)和3实例etcd (8C32G, 100G ESSD) 资源规格为条件,2万个ingress域名资源对象 (1KB大小) 作为背景数据,以10 QPS更新ingress资源对象,随着Tengine-Ingress pod个数的增加,监听ingress配置更新的时延也会相应增加,即使是上万级别超大规模集群,资源watch和list的时延均在可控范围内。
表1. Ingress存储集群性能基线
K8s分布式系统本身可以保障单个ingress资源的一致性,但分布式环境是无法保证用户存储在etcd中ingress域名配置的全局正确性和全局完整性,并且在API服务器和etcd不可用的情况下,ingress域名配置的可用性更是无法保障。因此,Tengine-Ingress提出了一种分布式环境下ingress全局一致性方案,在新增和更新域名时,Tengine-Ingress基于ingress全局一致性校验算法计算全局MD5值,与CRD ingresschecksums资源对象中的MD5值相匹配,则表明本次更新的ingress资源对象是全局一致性,即可将ingress资源对象更新到本地缓存,并写入共享内存,开始使用最新的ingress域名配置对外提供HTTP(S)七层负载均衡,TLS卸载和路由转发功能;否则表明更新的ingress资源对象全局不一致,系统存在脏数据,不再更新本地缓存和共享内存,仍旧使用存量的ingress域名配置对外提供HTTP(S)接入服务,保证运行态域名接入和路由服务的正确性和可靠性。
图6. Ingress域名配置全局一致性校验模型
分布式系统K8s的核心组件是API服务器和etcd,etcd作为K8s集群中配置数据的存储组件,而API服务器对外提供标准接口处理客户端请求并更新资源对象在etcd中的状态,从而允许客户端在工作节点之间配置各种流量负载和容器。因此,在API服务器和etcd因内部或外部原因导致其不可正常提供服务的情况下,客户端必然会出现各种服务异常。针对ingress资源对象,客户端将无法正常通过API服务器的接口获取ingress的更新配置,并且在API服务器或etcd异常误删除等特殊场景下,系统会错误地触发ingress删除事件,客户端会清空域名配置,这将导致客户端无法再对外提供HTTP(S)接入服务。基于分布式环境下ingress全局一致性方案,Tengine-Ingress在全局MD5值无法正常匹配或匹配失败的情况下,默认系统数据不再信任可靠,Tengine-Ingress进入自保护状态,不再更新本地缓存,仍旧使用缓存中存量的ingress域名配置继续对外提供HTTP(S)接入服务。Secret证书资源对象采用了类似的全局一致性方案。
综上所述,基于分布式环境下ingress和secret全局一致性方案,Tengine-Ingress保证用户存储在etcd中ingress域名和secret证书配置的全局正确性和全局完整性,并且在分布式系统K8s核心组件API服务器或etcd不可用的情况下,仍然可以保障ingress域名和secret证书配置的可用性,对外提供永不停机的HTTPS接入服务。
图7. Ingress全局一致性校验流程图
高性能
阿里集团web端标准接入网关基于远端Keyless服务获取TLS私钥,新架构AServer-Ingress应用本地TLS加解密,对比新旧架构在HTTPS短链接场景下的性能差异。压测模型使用HTTPS短连接,TLS 1.2协议ECDHE-RSA-AES128-GCM-SHA256算法,后端应用返回22KB响应报文,被压机Pod使用32核96G内存。
表2. 被压环境
表3. 压测模型
RT:由于Tengine-Ingress在TLS握手过程中减少了与远端Keyless服务的交互过程,HTTPS 1.1短链接场景下Tengine-Ingress相比Tengine,请求平均响应时间 (RT) 可降低约9ms。
图8. RT性能对比数据
表4. TLS握手时延细分对比
CPU:Tengine在HTTPS建链过程中消耗的CPU由远端Keyless服务与本端Tengine-Proxy两部分组成,而Tengine-Ingress在本端完成所有的TLS加解密。对比相同QPS所消耗的CPU,换算成CPU消耗比例,Tengine-Ingress消耗67.3% CPU,而Tengine需要消耗81.9% CPU,Tengine-Ingress在HTTPS短链接场景下性能提升约20.7%。
图9. CPU开销对比数据
Mem:由于Tengine实际运行时会加载大量的应用域名和路由的静态配置信息,32个worker进程需要各自申请一份内存,整个进程树就会占用较多的内存;而Tengine-Ingress使用动态配置,所有32个worker进程共享一份应用域名和路由配置信息,内存使用大幅下降,内存占用由20.4%下降至8.8%。
图10. 内存消耗对比数据
现状和展望
Tengine-Ingress已全场景覆盖阿里集团线上,预发和日常的互联网,VPN办公网,办公网和内网所有应用场景。Tengine-Ingress已承载十万级规模应用域名,内存消耗下降57%,HTTPS短链接场景下,性能提升约20.7%,请求RT平均下降36%,Tengine-Ingress作为高性能高可用的云原生网关得到了初步的考验。
确定开源Tengine 3.0功能特性范围:升级nginx core稳定版本;基于XQUIC支持QUIC和HTTP3协议;基于k8s ingress标准规范,支持域名和证书无损动态生效,ingress域名和secret证书配置的灰度分批生效,ingress和secret全局一致性校验,ECC和RSA双证书,分布式环境下动态服务发现,应用域名的灰度发布,蓝绿部署和A/B测试;基于XUDP支持bypass内核的用户态高性能UDP转发。
展望未来,Tengine将向通用API网关方向持续演进和发展,在HTTP应用流量入口网关的基础上,逐步支持4/7层TLS,TCP,UDP和GRPC多协议路由能力,适配不同终端和不同应用,打造全场景通用网关,持续保持Tengine业界领先地位。
Tengine官网: https://tengine.taobao.org
Tengine-Ingress开源仓库: https://github.com/alibaba/tengine-ingress
Tengine开源仓库: https://github.com/alibaba/tengine
XQUIC开源仓库: https://github.com/alibaba/xquic
XUDP开源仓库: https://gitee.com/anolis/libxudp