阿里系统软件技术
作者:互联网
为什么 K8s 在阿里能成功?| 问底中国 IT 技术演进
作者:
曾凡松 阿里云云原生应用平台高级技术专家
张振 阿里云云原生应用平台高级技术专家
导读:本文描述了阿里巴巴在容器管理领域的技术演进历程,解读了为什么 K8s 最终能够大获成功的原因,以及到今年 双11 阿里巴巴内部的 K8s 应用情况。内容着重描述了阿里巴巴基于 K8s 的云原生改造实践过程的三大能力升级,在对应能力升级过程中沉淀的技术解决方案,以及通过这些能力升级所取得的业务价值。
从 2015 年 Google 牵头成立 CNCF 以来,云原生技术开始进入公众的视线并取得快速的发展,到 2018 年包括 Google、AWS、Azure、Alibaba Cloud 等大型云计算供应商都加入了 CNCF,云原生技术也从原来的应用容器化发展出包括容器、Service Mesh、微服务、不可变基础设施、Serverless、FaaS 等众多技术方向,CFCF 旗下也囊括了越来多的开源项目。
Kubernetes 作为 CNCF 的第一个项目从诞生之初就就令人瞩目,Kubernetes 由 Google 工程师基于 Google 内部多年集群管理系统 Borg 的设计经验,结合云计算时代的基础设施特点重新设计而得,旨在帮助企业解决大规模 IT 基础设施的应用容器编排难题。
Google 在 2014 年 6 月开源 Kubernetes 以后,在 Redhat、Microsoft、Alibaba 等厂商和众多开源爱好者共同的努力下,成长为如今容器编排领域的事实标准,极大的推动了云原生领域的发展。
今天为大家分享来自阿里云的 Kubernetes 大规模实践经验,展现阿里云如何基于 Kubernetes 推动阿里巴巴应用运维技术栈走向云原生,如何推动 Kubernetes自身的技术进步,充分挖掘云原生时代的红利助力阿里巴巴大幅降低 双11 的 IT 成本。
容器在阿里巴巴的发展历程
在 2011 年之前,阿里巴巴使用 VM 虚拟化技术将一个物理机切分为 3 个虚拟机,用于部署淘宝服务,而随着淘宝业务的飞速发展,基于 VM 的技术方案在灵活性上跟不上业务的步伐。
因此,阿里巴巴在 2011 年就开始探索基于 Linux lxc 的容器技术,用于替代传统基于 VM 的应用部署方案,到 2013 年,研发了基于 Linux lxc 的 T4 容器和 AI 容器编排系统。这在当时已是非常领先的技术方案,但自己研发的容器技术与基于 VM 时代的运维系统始终存在一些兼容性问题。
在 2013 年随着 Docker 容器镜像方案的出现,阿里巴巴技术人员立即看到了基于容器 + Docker 镜像技术的未来,开始大力投入到这一领域的研究当中,到 2015 年 Aliswarm、Zeus、Hippo 等容器编排系统蓬勃发展,各自开疆扩土服务了阿里巴巴经济体的一部分业务。诸多的系统在解决了业务运维成本的同时,也带来了一定的重复建设成本,同时也导致了阿里巴巴内部的资源分布比较分散,无法统一调度多样的业务类型发挥出不同业务错峰使用资源的优势。
正是在这样的背景下,Sigma 系统应运而出并在 2017 年统一了阿里巴巴的资源池,统一调度阿里巴巴所有的核心业务,并第一次支持将在线服务与离线作业运行在同一个物理机上,大幅提高数据中心的资源利用效率并降低了阿里巴巴的 IT 成本。
随着云原生技术的高速发展,阿里巴巴也看到了云原生技术的潜力,以及未来企业 IT 全面上云的必然趋势,从 2018 年开始转型到 Kubernetes 技术,通过 Kubernetes 扩展能力将 Sigma 积累多年的调度能力通过 Kubernetes 的方式提供出来。
在 2019 年阿里巴巴宣布全面上云,阿里巴巴开始全面拥抱 Kubernetes,并将 Sigma 调度系统全面的迁移到基于 Kubernetes 的调度系统,该系统也正是支持了今年最大规模 双11 电商交易系统的底层基础设施,稳定的支持了大促前后数百次的应用变更并提供极速的应用发布与扩容体验,为 双11 的顺畅的购物体验立下悍马功劳。
为什么 K8s 在阿里能成功
Kubernetes 在众多的技术中脱颖而出,概括起来可以归纳为以下三个方面。
- 首先是其在诞生之初就为云时代而生,拥有超前的眼光和先进的设计理念,加之最初由天才的 Google 工程师基于其内部 Borg 多年的经验设计而来,诞生之后就飞速发展;
后来随着 RedHat、IBM、微软、Vmware、阿里云等来自全球的优秀工程师大力投入,打造了繁荣的社区和生态系统,成为企业容器编排系统的首选。
阿里巴巴经济体拥有众多的子公司,这些子公司在加入阿里巴巴大家庭时或多或少都会有一套自有的容器编排系统,在融入阿里巴巴的基础设施过程中,Kubernetes 是最标准也最容易被经济体内外的客户所接受的一个方案。
- 其次,Kubernetes 倡导的申明式 API 的设计理念,也贴合了阿里巴巴在应用运维领域的经验与教训;
传统的运维系统通常是基于过程式的设计,而过程式的运维系统在较长的系统调用链路下,通常会出现因异常处理复杂而导致的系统效率低下。
在大规模应用运维系统中复杂又繁多的状态处理也是一个大难题,基于过程式的系统设计很难确保系统的一致性,针对这些边界异常的处理通常又导致运维系统变得非常复杂,最终为异常兜底的只能依赖运维人员的人工操作。基本上可以认为基于过程式的运维系统难以应对超大规模的应用管理,而 Kubernetes 提供的申明式 API 却是解决应用运维状态轮转的一剂良药,是提高运维技术栈整体链路效率的最佳实践原则。
- 第三,Kubernetes 模块化、可扩展的架构设计,满足阿里巴巴的定制化改造以支持众多业务运维场景的需求。
在阿里巴巴内部,即有大量的无状态核心电商系统,也有大量的缓存、消息队列等中间件有状态系统,也包括大量带有倒排索引数据的检索系统,还有大量的 AI 计算任务,不用的应用类型对底层容器管理平台的要求也有所不同。
因此,一个模块化方便迁入自定义应用管理策略、易于扩展调度模型的设计显得至关重要,是能够服务阿里内部众多应用形态、提供统一容器管理基础设施的关键,Kubernetes 基本上提供了这些关键基础能力,虽然在实际应用过程中仍然会遇到非常多的实际问题。
阿里巴巴的 K8s 应用情况
在 2019 年 双11,阿里巴巴内部核心业务主要运行在神龙、ECS、ECI 三种资源类型的基础设施之上,而这些不同类型的基础设施资源均通过 Kubernetes 统一管理,以容器的形态提供给上层应用使用,完成了核心业务的支撑。
有别于以往的 双11,今年核心电商业务应用大规模部署在神龙裸金属服务器上。如果有关注过阿里云技术的发展,应该不会对神龙服务器感到陌生,它是阿里云自主研发的新一代云服务器,通过“软硬一体”的技术开创性的将云计算的虚拟化开销分摊到低价硬件板卡上,彻底的释放 CPU 的计算能力,第一次真正的做到了云计算虚拟化的“零”开销。
容器也是一种轻量级的虚拟化方案,神龙+容器+Kubernetes 的结合正是云原生时代的最佳拍档,支撑了今年最大规模的 双11,也将是未来的主流技术形态。
阿里巴巴也在继续使用 ECS 作为 Kubernetes 的底层资源供给,ECS 作为传统的云计算虚拟化方式支撑了部门集团内部业务,同时结合灵活性更好的弹性容器实例 ECI 用于应对业务突发的流量峰值,为业务带来了云计算的弹性价值,真正实现了按需申请、释放资源的极致弹性能力,降低了业务需要提前规划资源所带来的成本。
这些分布在海内外的数十万个节点的资源,被数十个 Kubernetes 集群托管,运行着阿里巴巴上万个应用,共计超过百万的容器,其规模之大前所未有。在今年的 双11 中,阿里巴巴内部最大的 Kubernetes 集群规模达到万级;当然这并不是Kubernetes 的技术极限,而是我们考虑数据中心资源效率与基础设施容灾能力之间所取的平衡,在将来如果有需要这个数字也可能变得更大。
基于 K8s 的云原生改造实践
Kubernetes 作为云原生技术的代表,已经成为了容器编排领域的事实标准,阿里巴巴自 2017 年开始探索,到 2018 年确认技术转型到使用 Kubernetes 来管理生产的容器。
在落地 K8s 的过程中,我们主要面临着两大难题:
- 其一,上层多样的业务运维平台;
为了支撑阿里巴巴内部多样的业务形态,在内部发展出来了多个典型的业务运维平台,每一个运维平台的基础设施、流程控制、应用发布策或多或少都会存在一些差别,缺少一个统一的应用运维标准。在调度与集群管理的技术演进过程中,如何牵引整个运维体系升级的同时并保持多个业务的平台及其上业务的稳定性,这是一个巨大的工程。
- 其二,随着阿里巴巴经济体全面上云战略的实施,整个底层基础设施包括存储、网络、基础运维软件的技术演进也非常迅速。调度与集群管理需要在支持好基础设施快速演进的同时,迭代自身的技术架构,并同时保证业务的稳定性。
基于 K8s 的云原生技术改造正是在这样的背景下诞生,发展到 2019 年 Kubernetes 在内部已大规模部署,所有的核心业务也都已经运行在 K8s 集群管理中。但在这几年的实践过程中,有一个问题始终萦绕在工程师头脑中,在阿里巴巴这么大体量、这么复杂的业务下,遗留了大量传统的运维习惯以及支撑这些习惯的运维体系,在这样的背景下落地Kubernetes (内部一个形象的比喻叫做给高速飞行的飞机更换发动机)到底是在坚持什么,哪些地方可以妥协,哪些地方必须改变?
这一章节, 将为大家分享我们这几年对这个问题的一些思考,特别是经过了今年的 双11 考验后,这个问题的答案基本上得到了工程师群里的集体认可。
负责顶层设计的架构师终于可以喘一口气:拥抱 Kubernetes 本身并不是目的,而通过拥抱 Kubernetes 翘动业务的云原生改造,通过 Kubernetes 的能力治理传统运维体系下的沉疴顽疾,真正释放云的弹性能力,为业务的应用交付解绑提速,才是这次技术变革的最大价值所在。
面向终态升级
在传统的运维体系下,应用的变更都是运维通过创建操作工单发起工作流,继而对容器平台发起一个个的变更来完成的。比如升级一个服务下的 3000 个实例,工单会被提前计算并生成出多个批次的子任务,并逐个的调用容器平台的接口完成变更应用的变更。
为了确保应用发布工单的顺利执行,在每一个子工单内部,每一个容器的发布也是一个工作流,包括监控开管、镜像拉取、容器启停、服务注册、配置推送等等,如果一切正常该流程会按预期有序的进行。
在大规模应用发布的场景中,诸如宿主机宕机、磁盘异常、IO 异常、网络异常、内核异常等几乎是必然存在的,如果发布流程中的某一个步骤出现了错误,通常情况下需要运维平台按照一定的策略来重试,直到超过该批次的超时阈值,这将会带来三个问题,下面逐一展开。
- 其一是重试带来的效率问题;
每一个子任务的执行时间将被任务内的长尾发布所拖累,假设将 3000 个容器分为 30 批次每批 100 个(仅为示意并非最佳实践),每一批次内出现一个容器发布异常时,该批次的发布时间将被重试拉长。
- 其二是失败带来的一致性问题;
对于发布异常的容器,在工单结束之后通常只能通过外围链路巡检的方式来治理,而事实上通常的巡检是依赖运维人员手工操作的,带来了极大的人工成本和不确定性。
- 第三是应用并发变更冲突问题。
如果在应用发布的过程中,同时提交了应用扩容的请求,由 3000 扩容到 3200 个实例,扩容的 200 个实例应该采用旧版本还是新版本,采用旧版本扩容将面临的问题是谁最终负责这 200 个旧版本实例的升级,采用新版本扩容将面临的是稳定性问题,如果新版本存在问题新扩容的实例将产生较大的影响。
正是因为这些复杂的问题导致多数运维系统拒绝了并发的应用变更,导致并发操作效率非常底下。
K8s 为应用管理所提供的申明式 API 的设计理念同时解决了解决了这三个问题,用户只需要描述期望的最终状态以及达成期望状态的过程中需要遵守的限制条件,达成终态所需要执行的复杂操作全部交由 K8s 的来完成。
在应用发布过程中,通常情况下 K8s 通过控制并发度及最大不可用实例数来约束应用发布对服务的影响,对于发布过程中失败的实例通过最终一致的方式在系统内部解决。正是基于这一设计,用户发起服务变更时只是更新了应用的预期状态,并不需要等待任何任务的结束,一并解决了应用发布效率、线上配置的一致性和并发变更冲突效率的问题。
基于面向终态的理念管理应用,我们开发 Advanced StatefulSet 的应用管理工作模型,顾名思义它基于 Kubernetes 官方的 StatefulSet 扩展而来。
在官方的工作模型中,应用通过滚动的方式完成版本升级,也就是创建新的 Pod 同时删除旧版本的 Pod,直到整个应用切换为新的版本。
这种方式简单直接,但存在效率的问题,比如所有应用的 Pod 需要重新的调度,这在大规模应用发布场景将给调度器带来很大的压力;同时,因为新版本 Pod 为全新创建,需要重新分配 IP 并挂载远程卷,这对云计算网络、存储基础设施也将是很大的挑战;再者,因为容器是被全新调度出来的,在机器上需要重新下载新的应用镜像,这将大幅降低应用发布的效率。
为了提高应用发布的效率和资源的确定性,开发了这一工作负载模型,它支持原地发布应用,应用发布前后应用所在的位置保持不变,同时支持了并发更新、容错暂停等丰富的发布策略,高效的满足了阿里巴巴内部电商应用的发布需求。因为应用发布前后位置不变,因此我们可以在灰度发布的过程中预先下载并解压即将要发布的容器镜像,从而大幅提高应用发布的效率。