👉腾小云导读
2022 年 10 月,腾讯自研业务产品全面完成云原生上云。自研业务产品云上规模已突破 5000w CPU,借助云原生的技术优势,全面提升了腾讯自研业务产品的运营效率,在此过程中我们也对腾讯云产品进行了打磨和验证。无论是在业务场景、稳定性要求、运维效率等多个方面,大规模容器化过程中都面临不少的技术挑战。本篇将进行分享,希望可以给广大开发爱好者带来灵感。
👉看目录,点收藏
1 项目背景
1.1 腾讯自研业务产品云原生上云历程简介
1.2 腾讯有状态服务的共性
2 腾讯大规模业务容器化面临的几个挑战
2.1 容器快速升级
2.2 容器原地热升级
2.3 面向业务产品的全局快速扩缩容
2.4 对应用屏蔽多样的底层机型,提升资源池利用率
2.5 从面向集群到面向应用的调度编排
3 总结
腾讯自研业务产品历经三年,包括 QQ、微信、王者荣耀、腾讯会议等亿级用户规模的业务产品,都已全面上云。自研业务产品云上的资源规模已突破 5000 万核,打造了国内最大规模的云原生实践典范。各位读者在后台回复「云原生」可下载鹅厂7w字大规模云原生技术实践案例集、腾讯云技术实践精选文集。
在这个过程中,腾讯做了大量的技术优化和突破,包括优化 K8s 集群、全局的资源管理调度,实现了 65%的 CPU 利用率、提升容器应用链路上各层的稳定性等等。
3 年时间,腾讯最终达成了全面云原生上云的目标。在容器应用管理上,有几个事情非常关键:
最早期需要云原生理念的布道。让所有业务产品”认识“到云原生上云所带来的业务价值。几年前,腾讯内部的 K8s Oteam 联合腾讯学堂推出了第一个面向全公司的 K8s 系列课程。
提供易用性和稳定性的容器管理平台。这解决不同的业务场景容器化上云的痛点并沉淀了产品的能力,让所有腾讯业务产品都真实感受到云原生上云的价值。
资源调度编排能力。底层海量的资源规模,需要打造极好的资源调度编排能力,提升全局的资源利用率,从集团层面达成上云后的降本增效目的。
度量机制。「各个业务产品云原生上云做的怎么样」需要有一套度量机制。例如腾讯的云原生成熟度模型,有效帮助各个业务提升了业务产品的云原生成熟度。
下面将主要介绍开发过程中我们遇到的部分技术挑战和解决方案,各位将能看到我们在此过程中是如何一步步去夯实产品能力的。
01
项目背景
1.1 腾讯自研业务产品云原生上云历程简介
腾讯自研业务产品容器化上云始终以腾讯云产品为底座,整个过程分为两个阶段,云原生上云 1.0 和 2.0 阶段。2022 年前主要是 1.0 阶段,技术中心在「离线混部、在线混部」场景中,业务产品的容器化形态主要经历了富容器和微容器 2 个形态。
经过大规模自研业务产品的容器化,团队沉淀了各种业务场景下容器化上云的最佳实践方案和产品所需的能力,例如容器调度(单集群和多集群)、弹性伸缩、有状态服务容器化、大规模资源管理、稳定性提升、业务运维效率提升等。
上云阶段不仅仅是把业务产品容器化上云,更重要的是要给业务产品带来实际的价值。这里有腾讯云原生的成熟度规则,来考核腾讯自研业务产品和其对应的容器平台。主要从四个维度考核:
最大的权重维度是资源利用率,指业务产品容器利用率、平台资源利用率。还有弹性伸缩能力、容器可调度能力以及申请的 Pod 资源是不是小核心的资源。通过这些核心指标来规范和评估业务产品云原生上云的过程和效果。
1.2 腾讯有状态服务的共性
|
这些业务产品特性使其在 TKE 管理上面临巨大挑战,既要尽量兼容这些业务产品特性,也要保持其使用镜像发布和升级的云原生准则。TKEx 应用管理平台抽象出了这些特性背后的需求,研发了多集群统一灰度发布、多地域多集群工作负载管理、面向应用的多集群协同扩缩容、容器快速升级、容器热升级等通用的平台能力。
02
腾讯大规模业务容器化面临的几个挑战
2.1 容器快速升级
针对「使用 IPC 共享内存,可能有超 GB 的有状态本地数据,升级时不能丢失,而且只允许 ms 级的用户无感知抖动」 这个业务产品特性,TKEx 应用管理平台开发团队设计研发了使容器快速升级的产品能力,提供像进程重启一样的 ms 级业务抖动体验,这也是腾讯会议容器化上云很有挑战性的点。
容器原地升级,也是一种针对有状态服务进行升级的有效手段。实现在 Pod 不重建的情况下,Pod 内某个 Container 进行重建,保持了 IPC 共享内存,本地有状态数据不丢失。但是原地升级过程中,虽然容器网络和存储不再需要重新分配和挂载,但是仍然需要 ReCreate Container,就会存在 Image Pull 和 Container 销毁和启动的过程。
因此原地升级的整个流程耗费时间一定是秒级的,这会造成服务的秒级不可用。结合 ReadinessGateway 能做到按需添加/剔除路由,实现过程中请求无损。但是用户的有状态数据是在本地的,请求表面无损,而实际上用户对应的长链接服务已经无法正常提供服务了。这会导致会议秒级中断,是不可行的。
Pod 里有 3 个关键容器,它们的职责分别如下:
容器 | 职责 |
biz-sidecar: Sidercar | 容器职责很简单,提供“ Pod 是否在升级中”的状态维护。通过 Readiness Probe 比较 EmptyDir Volume 中的业务发布版本文件 version1 和 version2 的内容是否相等,相等则 Ready,否则 notReady。 |
biz-container | 容器启动脚本会将环境变量(预注入)里的一个版本号写到 versionX 文件中,然后开始循环等待文件锁,如果成功获取文件锁则启动业务进程。文件锁是防止 Pod 内同时运行多个版本,是业务 Container 的关键,用文件锁来做不同版本容器的互斥,可以实现业务新旧主进程的 ms 级切换。 |
biz-pause | 这是一个占位容器,容器的启动脚本会将环境变量里的一个版本号写到 versionX 文件里,然后就进入无限 sleep 状态。当业务需要升级时,它就会通过原地升级的方式切换到 biz-container 的角色。 |
接下来,此处我们以业务从版本 V1 升级到版本 V2 为例,阐述升级流程。
|
值得注意的是,原生 K8s apiserver 允许修改 Pod 的 image 等,不支持修改 resource 以及环境变量等,所以该方案需要修改 K8s apiserver 的相关代码。另外为了保证 Pod request 资源以及其 Pod qos 不变,StatefulSetPlus-Operator 在升级时需要对各阶段容器进行 Resource 调整。
最后,基于这个技术原理,我们封装成 TKEx 应用管理平台所需能力的产品,提供简单好用的操作体验。用户按规则编译好镜像后,只需升级时勾选「快速升级」,即可完成整个过程。
通过占位容器、状态机 Sidecar 容器、原地升级、共享 volume、文件锁机制,实现容器升级时业务进程的快速切换。
保持镜像发布的云原生体验,实现方式完全是 K8s 原生,拒绝把容器当虚拟机使用。
2.2 容器原地热升级
部分模块发布需要保持共享内存数据不变,并且业务自身要有热重启能力,容器化如何提供业务热升级的能力?是云直播等业务模块能否顺利容器化的关键。针对 「部分模块的开发框架支持热升级,需要在容器升级时支持原地热升级」这一业务诉求,TKEx 应用管理平台基于 Kubernetes 原地升级、共享 volume、Probe 和占位容器的关键技术,完成并实现了原生的业务容器原地热升级的技术方案和平台能力。
方案说明:
|
其中,占位容器负责将业务新版本镜像中的新版本业务 bin 复制到共享 volume。业务容器 watch 共享 volume 中相关内容的变化,并可以进行进程 reload 热升级。
而业务容器的探针 Readiness 要负责感知原地热升级的状态,从而支持原地热升级的时候仍然能进行容器流量管理。但实际上,因为原地热升级通常是 ms 级的,通常没有必要去在这 ms 级时间范围内做路由的剔除和添加。
此过程中,需始终保持以镜像发布的云原生体验,实现方式完全 k8s 原生,拒绝把容器当作虚拟机用的方式去做业务进程升级。遗憾的是目前还没有将这些技术原理封装成平台能力,所以业务要做原地热升级的知识门槛仍然较高。
2.3 面向业务产品的全局快速扩缩容
因接入需求和容灾、多活的需求,有些头部业务产品海内外多地域部署单个模块最多的实例数超过 1 万。整个产品的 Workload 万级,分布在上百个集群,和其类似的自研业务产品其实不少。这种业务产品有一个特点,通常对一段时间的「PCU(同时最大在线人数)」的预估来提前进行扩缩容的决策。
例如当前业务产品的 PCU 是 2kw, 需要扩容到 3kw,核心链路上的大部分模块都需要在当前规模的基础上扩容 50%。在如此复杂的业务分布拓扑中,要提前进行大规模扩缩容会面临很多困难:
|
为此,平台进行了基于业务自建拓扑的全局快速扩缩容产品能力建设,通过任务的形式管理全局扩缩容,核心能力如下:
第一,用户选择一批跨业务、跨集群的 Workload,组成一个全局的业务拓扑 Set,作为业务产品维度的扩缩容任务设计的对象,设置全局扩缩容参数,完成扩缩容下发动作。当前支持「基于步长」和「基于等比例」两种扩缩容策略,支持配置 HPA 的 Workload 和未配置 HPA 的 Workload 的提前全局扩缩容。这里有 2 种情况:
|
第二, 在配置好全局扩容后,资源概览页支持按照「计算资源」、「IP 资源」、「配额」三个维度展示资源需求、资源库存和详细资源缺口等数据,方便按需补充对应资源。
第三,基于业务大盘视图展示的整个扩缩容任务的所有 Workload 和 Pod 实时状态信息,可以快速找出异常 Pod(状态异常、实时利用率异常),快速掌握整体业务服务扩缩容状态。
第四,提供业务产品的全局 Workload 扩缩容状态视图。支持按照业务、集群、地域等维度聚合查看整个扩缩容任务中所有 Workload 的扩缩容进展,并有完整的 Workload 列表页展示各 Workload 运行中副本数量、目标副本数量、库存副本数和异常信息。
方案说明:在 TKEx 应用管理平台中,基于 Clusternet 构建的多集群管理方案,业务产品全局快速扩缩容的核心组件 Global Scaler Operator部署在 Clusternet Hub Cluster 中,用户在平台前端构建生成 ScalerJob CR 后,会自动生成ScalerTemplate。
Global Scaler Operator 核心管理着 2 个 CRD,分别是前面提到的扩缩容任务 ScalerJob 和扩缩容模板 ScalerTemplate 。
CRD | 解析 |
ScalerJob | 定义全局扩缩容配置,并关联扩缩容模板 ScalerTemplate,为整个全局扩缩容提供按指定策略触发运行、回滚、终止等核心能力的定义和状态管理。 |
ScalerTemplate | 定 义要扩缩容的 Workloads 对象及其 Scale 参数,也提供全局扩缩容回滚模板的能力。 |
全局快速扩缩容策略:前面提了 2 个业务产品全局扩缩容策略,这里举个例子做简单说明。假如业务产品X有 3 个 Workload,分布在广州、上海、北京,副本数分别是10, 20, 30,当前支持的 PCU 是 10w,需要新增扩容支持 5w PCU。
策略 | 解析 |
基于步长策略 | 当业务产品X每增加 1w PCU 时,Workload A 要增加 2 个副本,Workload B 要增加 4 个副本,Workload C 要增加 5 个副本,这就是每个 Workload 单独的步长。业务产品X扩容 5w PCU,基于 1W PCU 的步长,扩容系数就是 5 倍,就意味着 Workload A 要新增 2*5=10 个副本,以此类推。 |
基于等比例扩容策略 | 当前业务产品 X 的 PCU 是 10w,需要新增 5w PCU, 核心链路的模块都要等比例扩容 50%, 则所有 Workload 的副本数在当前基础上都要扩容 50%,扩容系数就是 1.5。
|
2.5 对应用屏蔽多样的底层机型,提升资源池利用率
底层使用的资源有各代的老旧机型,也有新代机型。如何让业务能无差异的使用这些资源,是提升整个资源池利用率必须要解决的问题。例如 Application X 的实例分布在北上广 3 个地域,调度在多个集群中使用了腾讯云 S3、S4、S5、S6 多种机型资源。如果不做各个实例的路由权重上的差异化处理,那么必定会出现每个实例的负载不一致。这就容易出现老旧代机型高负载,新代机型低负载的情况。并且平均负载并不高,不能触发原生 HPA,从而导致业务服务质量出现下降。
如果使用的服务路由系统具备「根据实例负载或者自定义指标动态调整服务权重」的能力,这一问题将得到大幅缓解。
为了解决这个问题,目前有 2 个解决方案,分别应用在不同的业务场景中:
【方案1】
引入机型族的概念。基于计算、存储、网络等方面的关键性能指标,构建综合性模型,将性能接近的机型放入同一个机型族(普通性能机型族、高性能机型族、指定机型),从而大幅收敛原本暴露给用户的底层机型。调度上保证同一个 Workload 都使用一个机型族,最终使得各个业务实例在请求量一致的情况下负载基本均衡。这样业务的平均负载就与各个实例的负载方差很小,HPA 也能正常工作,以保证业务的服务质量。 这种方案主要适用于批量计算型业务,也适用于业务对机型性能有一定要求的业务,或者必须指定某个具体机型的通用计算场景,但是可能会面临一些资源调度上的风险,例如业务指定机型或机型族的资源不足等问题。这个方案本质上是在缓解这类对资源有性能要求的业务问题。机型族应用越多,该方案对提升底层各种好差料的效果就越好。 |
【方案2】
将底层算力标准化、产品化。平台将底层的所有机型算力都按照预设的模型折算到标准算力,平台从底层资源池中按需调度算力组合成业务需要的标准算力需求。应用在部署和扩缩容时需要的资源,都以标准算力为单位,不用再关注任何机型信息。 例如,应用X需要在广州任意 2 个可用区等比例算力部署,共需要 32c*200g* (c* 表示标准 cpu 单位,g* 表示标准内存单位)。假设底层资源池中一共有 3 种机型,机型 A 的算力为标准算力的 50%,机型 B 的算力为标准算力的200%,机型 C 的算力正好是标准算力,则应用X可能的部署拓扑如下。 |
这里还有一个重要的工作,就是需要根据各种底层组合的机型的算力,动态调整对应的服务路由权重。因此 TKEx 应用管理平台联合北极星 Polaris,将各个机型的算力动态折算成路由权重动,实现了基于机型算力的业务全局动态路由权重能力,最终使得同一个 Workload 下不同机型的负载基本保持平衡。
2.6 从面向集群到面向应用的调度编排
前几年大家更多关注的是怎样给用户提供直接面向 K8s 集群的业务管理能力。在小规模业务场景下,这种方式没有痛点。但随着业务规模的增加,这里的业务管理痛点就逐渐暴露。用户要感知底层大量的可用区和集群,对应大量的 Workload、ConfigMap、Service、Ingress 对象的管理。因此这里要转换思路,由面向集群到面向应用的调度编排,这意味着用户不用再关注集群,不用关注底层资源,不用关注每个集群中的 K8s 对象管理,只需关注应用本身。
举个例子,某个业务产品在全网有上万个 Workloads 和 Pods ,分布在全球十几个地域、近百个集群。要对这个业务某个模块做一次全网升级变更,按照以前面向集群的方式实现效率较低,当然借助上层 的 DevOps 流水线可以提升一些效率。所以要抽象出面向应用的管理能力,简化业务产品在部署、扩缩容、升级变更、配置管理、流量管理、业务看板等方面的操作体验和效率。
要实现这一目标,核心的底层能力建设就在多集群编排调度上,可以基于Clusternet 的多集群管理能力来实现。例如,应用想部署同城多活的场景,TKEx 应用管理平台直接提供这种部署策略,不用去指定 Region 去找合适的集群单独部署,直接指定 Region 后,Clusternet 动态拆分调度器 i ,自动根据集群容量、位置拓扑等信息来做调度决策,选择合适的集群并做好最佳的副本分布决策。
再例如,配置应用弹性伸缩时,不需要再面向集群配置 HPA。会有一个全局的多集群 HPA Coordinator Controller 做多集群 HPA 协同,可以根据集群容量、集群的可用性做 HPA 参数的动态调整和协同,保证业务扩容时不会因为某个集群的资源不足无法扩容,会自动在其他可用集群中扩容。
还有很多重要业务场景,需要在多集群编排中解决。例如面向应用灰度升级时,应用对应的 Workloads 分布在底层多个集群中,如何做好多集群的应用灰度发布?ConfigMap 的多集群灰度发布也是一样的道理。另外,给用户提供的大盘视图、监控告警能力等等都不再是面向集群维度的,而是面向应用的多集群聚合维度的。
03
总结
腾讯拥有国内最大规模的云原生实践案例,过程中大量的技术和产品能力服务了大量业务场景,包括音视频、游戏、电子商务、社交、办公协同、出行等。我们正在将这里积累的各种业务场景的最佳实践经验,例如应用的标准化检测、业务的 QoS 定义、应用多集群灰度发布、应用多集群自愈等等,都输出到云原生应用管理平台这个公有云产品中。
用同样的应用管理平台同时服务好腾讯内部和外部客户,与开发者们一起迈入云原生 2.0 时代。以上是本次分享全部内容,欢迎大家在评论区分享交流。如果觉得内容有用,欢迎分享转发~
-End-
原创作者|王涛
技术责编|王涛
你怎么看待云原生?云原生未来的发展趋势是什么?欢迎在评论区讨论。我们将选取1则最有创意的分享,送出腾讯云开发者-文化衫1个(见下图)。5月17日中午12点开奖。
后台回复「云原生」查看鹅厂离线学习包:
7w字腾讯大规模云原生技术实践案例集
腾讯云技术实践精选集