本文根据杨小飞在【第十五届中国系统架构师大会(SACC2022)】线上演讲内容整理而成。
历经两年,中通快递已经实现了内部与生态绝大多数应用容器化的目标,期间经历了从单集群到多集群的部署,从单集群独立管理到统一多集群管理能力的发展旅程。中通云平台持续推出了基于真实负载的调度器和节点均衡job、应用画像、容器现场保留、应用迁徙、固定IP、跨集群HPA等多种功能或者产品,既提高了极端情况下单一集群的容灾能力,也提升了各个集群的资源利用率。
单一网络多集群治理探索,以及不断推进容器化,提升各个集群资源利用率并部分提供容灾能力。本文就国产分布式数据库在引入后如何结合银行业务场景选型,如何配合开发兼容性改造、如何完成数据迁移等技术问题,如何搭建运维体系建设、如何规范流程管理进行内容分享。
▲中通快递中通云平台资深架构师 杨小飞
嘉宾介绍: 中通快递云平台软件工程师,致力于内部云平台建设,曾经某厂服务网格开发,熟悉java微服务技术栈,专注于go云原生机会,资深潜水于istio、dapr社区。
分享大纲:
1、中通云发展背景与挑战
2、从单集群到多集群
3、多集群治理
4、成功与总结
5、未来规划
一、中通云发展背景与挑战
截止2019年前,独立的devops平台,中通云绝大部分流量都跑在虚拟机。从2019年开始,中通云开始容器化进程,自一开始便使用了bgp打通了各集群间的网络,支持虚机容器混部。
截至2022年中旬,中通云现有业务绝大部分跑在容器上,大的生产集群有6个,总共pods数量18000多个,node节点700多,持续推进集群治理以保障环境的稳定和资源充分利用。未来,中通云会推动南北流量治理,全域容器化;提升可观测能力,有状态应用的支持。
2019年前,中通云的状况是预研K8s、上线wayne、提供k8s资源管理微服务、上线ZKE、开发、测试上容器。自2020年开始,中通云开始生产上容器,并且不断推进容器化、多集群、cilium。未来,中通云将统一网关、离线混部等。
容器化前,中通云主要是跑在虚拟机,部分有状态服务运行在物理机。其应用生命周期管理迟缓,南北流量全部依赖于静态配置,伸缩缓慢,大量僵尸应用缺乏治理,资源利用率低。
容器化后,中通云的资源利用率从15%提升到百分之40%,应用全生命周期管理更快便捷、快速,弹性伸缩能力加强。
在容器化过程中,中通云遇到了很多挑战。包括:安全要求,所有的外网访问都需要走申请;单集群部署存在风险,单集群的故障影响面太大;对接devops平台,有独立的devops平台,需要从传统的虚机发布添加对于容器和混部的支持;固定ip的需求,少量应用对于固定ip存在需求,比如“雪花算法”的应用。
资源吃紧,由于容器化不断推进,而资源回收滞后,集群资源禁止持续了很长时间;原生调度器不足,基于request和limit的调度无法完全体现各个节点的资源情况;容器内故障现场难以保留,运行在容器的应用故障,重启或者回滚就丢失了现场;节点均衡,集群各个节点调度不均衡,为了平衡需要根据实际负载二次均衡。
二、从单集群到多集群
单集群支持内容基于真实负载的调度器拓展,中通云自研了基于原生的拓展调度器,基于采集到节点注解的负载信息进行调度。固定ip支持,采用ipam固定ip方法建立专用固定ip集群。
容器现场保留,有别于官方的临时容器方案,通过宿主机cri能力切断故障现场的容器网络,然后踢出工作负载管理,再用钩子dump堆栈等。节点二次均衡,即使使用了自研的拓展调度器,个别情况下还是会出现负载不均匀的情况。因此,自研了二次均衡的job,来确保集群各个节点负载均匀。
自研的拓展调度器的改造内容包括由采集器将节点真实负载写入到节点注解上,然后调度器从中获取信息之后调节节点的score。
这期间踩过一些坑,由于node-exporter偶尔出现采集不到信息的情况,导致上报的负载为0,使得该节点被大量调度pod上去,最终打垮了该节点。热点调度,目前的工作负载都会设置反亲和性。
关于容器的现场保留,其需求背景是生产环境上个别应用出现java进程假死情况或者出现应用层的保持。出于快速止血的需要,一般都会进行重启或者回退版本,这使得故障现场第一时间丢失。手动dump内存等周期长、慢,且不完整。
基于选型的考虑,官方由提供临时容器的方式,可以复刻一个现场。但是,由于我们存在低K8s版本,无法全部满足需要,另外现场可能还会继续工作,如果既要他不工作又要现场保留,就会存在困难。
最终采用是自研方案,由于我们内部都是无状态工作负载,所以最终采用了自带的特性:修改已经存在的label,然后k8s会自动拉起一个新pod来替代它;同时,调用容器内的dump堆栈指令保存即时的现场,再调用cri指令,切断容器的网络。
二次节点均衡的背景是单集群内长期存在各个节点负载不均匀的情况,即使上了自研的基于真实负载的拓展调度器也未解决问题。高负载的节点会使得大量的运行上的应用高延迟,影响很大。等待触发k8s的驱逐机制非常危险且不确定。长期的解决方式是由运维手动删除一些负载较高的节点上的pod。
解决方案是在内部,我们调研了descheduler,并且基于它改造了部分内容,根据真实的负载水平驱逐pod。但是,内部我们并未采用它,我们只需要其中更简洁、确定的功能。最终,我们自研了二次均衡的job。
那么,哪些pod适合被驱逐?单实例多副本中的其中一个。非网关等核心应用,支持namespace、app、node节点白名单机制。cpu在2C~4C之间,低CPU驱逐没有意义,高CPU驱逐对于应用影响比较大。
多集群的基本能力包括:跨集群之间的资源管理、Devops支持多集群发布和多集群管理、单集群管理控制台适配多集群管理工作负载的能力、多集群管理控制台——云看板。
多集群支持的内容分为四个方面,应用发布支持多集群,由于集群间网络打通,所以只需要在多集群确保工作负载一致。多集群ingress与统一网关对接,应用路由以及各集群ingress网关上报给统一网关。
多集群与日志平台的对接,从工作负载页面,支持快捷跳转日志平台和应用监控平台页面。多集群与监控中心的配合,以应用为纬度,统一上报到prometheus,再由监控中心配置告警阈值。
三、多集群治理
我们所做的治理内容包括应用迁徙、跨集群应用均衡、应用打分三方面。
在应用迁徙方面,支持按照集群权重迁徙副本数,当新加入一个集群,需要对于资源进行迁徙,可根据配置,划分设置比重的副本到新集群。支持整体迁徙,拷贝所以资源到新集群,然后停用旧集群相关资源。
在应用打分方面,支持根据部门和产品纬度整体打分,输出具体打分标准和低分整改要求。目的是为了应用的健壮运行提供了数据支撑,保障集群的稳定性,各产品良性竞争。支持依据cpu、memory等的使用情况和设置规则的差值比例;大副本;内存使用等多标准,依据不同情况对于应用提供治理项和依据。
在跨集群应用均衡方面,对于历史应用,支持基于副本数和HPA对于工作负载在多集群之间进行均分,或者按照集群剩余request等多种方式分布或者伸缩。且支持cronHpa,未来还将支持基于消息积压的HPA。对于新发布应用,我们都会默认开启后,逐渐模糊单集群的概念,应用只需要关于自己的运行状态。
四、成功与总结
在单一网络多集群实践中,成功的方向有四个。我们解决了长期的基础设施历史包袱,推进容器化进程,应用大部分都跑在容器中,回收虚拟机与物理机都已经达到预期。拥有一个应用全生命周期管理,具备了比虚机更便捷的应用运行、发布、回滚等能力。
关于多集群控制能力层次设计,避免鸡蛋都放在一个篮子,多个生产集群,避免单集群的故障对于整体的影响。多集群管理,目前可以非常友好的支持增加集群或者减少集群,中间周期可以大大缩短。
由于各个集群之间细微的差异,比如版本,K8s核心组件和组件部署方式差异。我们在节点预留资源踩一些坑。此外,我们与统一网关的结合需要更加友好。比如,自动上报网关地址和端口以及域名和产品信息。
由于长久的历史原因,提供东西流量的治理存在很大的未知性。由于安全的特殊要求,网络策略在多集群的管理下支持的不够好。
五、未来规划
目前是将各个集群的ingress网关地址配置在外部网关上,由此导致上层无法拿到pod ip,只有网关ip,对于个别的问题排查存在阻碍。所以,我们将引入多集群统一网关,让每个应用都能拿到pod ip,从而方便南北流量的治理。
目前大数据侧有大量离线任务;而中通应用集群存在明显的谷峰,在低峰期存在大量可用资源可以进行使用。
在东西服务治理方面,内部支持dubbo,充分利用现有资源,监控,zcat,网关,满足平滑迁徙、过度、多集群支持、跨部门协作、虚机、容器混合等。