K8s 集群节点在线率达到 99.9% 以上,扩容效率提升 50%,我们做了这 3 个深度改造

导读:2019 年阿里巴巴核心系统 100% 以云原生方式上云,完美地支撑了 双11 大促。这次上云的姿势很不一般,不仅是拥抱了 Kubernetes,而且还以拥抱 Kubernetes 为契机进行了一系列对运维体系的深度改造。

Kubernetes 作为云原生的最佳实践,已经成为了事实上的容器编排引擎标准,Kubernetes 在阿里巴巴集团落地主要经历了四个阶段:

  • 研发和探索:2017 年下半年阿里巴巴集团开始尝试使用 Kubernetes api 来改造内部自研平台,并开始了对应用交付链路的改造,以适配 Kubernetes;
  • 初步灰度:  2018 年下半年阿里巴巴集团和蚂蚁金服共同投入 Kubernetes 技术生态的研发,力求通过 Kubernetes 替换内部自研平台,实现了小规模的验证,支撑了当年部分 双11 的流量;
  • 云化灰度:  2019 年初阿里巴巴经济体开始进行全面上云改造,阿里巴巴集团通过重新设计 Kubernetes 落地方案,适配云化环境,改造落后运维习惯,在 618 前完成了云化机房的小规模验证;
  • 规模化落地:2019 年 618 之后,阿里巴巴集团内部开始全面推动 Kubernetes 落地,在大促之前完成了全部核心应用运行在 Kubernetes 的目标,并完美支撑了 双11 大考。

在这几年的实践中,一个问题始终萦绕在各个架构师的头脑中: 在阿里巴巴这么大体量、这么复杂的业务下, 遗留了大量传统的运维习惯以及支撑这些习惯的运维体系,落地 Kubernetes 到底要坚持什么?要妥协什么?要改变什么?

本文将分享阿里巴巴这几年对于这些问题的思考。答案很明显:拥抱 Kubernetes 本身并不是目的,而是通过拥抱 Kubernetes 撬动业务的云原生改造,通过 Kubernetes 的能力,治理传统运维体系下的沉疴顽疾,释放云弹性的能力,为业务的应用交付解绑提速。

在阿里巴巴的 Kubernetes 落地实践中,关注了下面几个关键的云原生改造:

面向终态改造

在阿里巴巴传统的运维体系下,应用的变更都是 PaaS 通过创建操作工单,发起工作流,继而对容器平台发起一个个的变更来完成的。

当应用发布时, PaaS 会从数据库中查到应用所有相关的容器,并针对每个容器,向容器平台发起修改容器镜像的变更。每一个变更实际上也是一个工作流,涉及到镜像的拉取、旧容器的停止和新容器的创建。工作流中一旦发生错误或者超时,都需要 PaaS 进行重试。一般而言,为了保证工单及时的完成,重试仅会执行几次,几次重试失败后,只能依靠人工处理。

当应用缩容时,PaaS 会根据运维人员的输入,指定容器列表进行删除,一旦其中有容器因为宿主机异常的情况下删除失败或者超时,PaaS 只能反复重试,为了保证工单的结束,在重试一定次数后只能认为容器删除成功。如果宿主机后续恢复正常,被“删除”的容器很有可能依然运行着。

传统的面向过程的容器变更一直存在如下问题无法解决:

  • 单个变更失败无法保证最终成功

例如,一旦容器镜像变更失败,PaaS 无法保证容器镜像的最终一致;一旦删除容器失败,
也无法保证容器最后真的被删除干净。两个例子都需要通过巡检来处理不一致的容器。而巡检任务因为执行较少,其正确性和及时性都很难保证;

  • 多个变更会发生冲突

例如应用的发布和应用的扩容过程需要加锁,否则会出现新扩的容器镜像未更新的情况。而一旦对变更进行加锁,变更的效率又会大幅下降。

Kubernetes 的能力提供了解决这个问题的机会。Kubernetes 的 workload 提供了声明式的 API 来修改应用的实例数和版本,workload 的控制器可以监听 pod 的实际情况,保证应用 pod 的实例数量和版本符合终态,避免了并发扩容和发布的冲突问题。Kubernetes 的 kubelet 会依据 pod 的 spec,反复尝试启动 pod,直到 pod 符合 spec 描述的终态。重试由容器平台内部实现,不再和应用的工单状态绑定。

自愈能力改造

在阿里巴巴传统的运维体系下,容器平台仅生产资源,应用的启动以及服务发现是在容器启动后由 PaaS 系统来执行的,这种分层的方法给了 PaaS 系统最大的自由,也在容器化后促进了阿里巴巴第一波容器生态的繁荣。但是这种方式有一个严重的问题,即:
容器平台无法独立地去触发容器的扩缩容,需要和一个个 PaaS 来做复杂的联动,上层 PaaS 也需要做很多重复的工作。这妨碍了容器平台在宿主机发生故障、重启、容器中进程发生异常、卡住时的高效自愈修复,也让弹性扩缩容变得非常复杂。

在 Kubernetes 中通过容器的命令以及生命周期钩子,可以将 PaaS 启动应用以及检查应用启动状态的流程内置在了 pod 中;另外,通过创建 service 对象,可以将容器和对应的服务发现机制关联起来,从而实现容器、应用、服务生命周期的统一。容器平台不再仅仅生产资源,而是交付可以直接为业务使用的服务。这极大地简化了上云之后故障自愈以及自动弹性扩缩容能力的建设,
真正地发挥了云的弹性能力。

另外,在宿主机发生故障的情况下,PaaS 传统上需要先对应用进行扩容,然后才删除宿主机上的容器。然而在大规模的集群下,我们发现往往会卡在应用扩容这步。应用资源额度可能不够,集群内满足应用调度限制的空闲资源也可能不够,无法扩容就无法对宿主机上的容器进行驱逐,进而也无法对异常的宿主机进行送修,久而久之,整个集群很容易就陷入故障机器一大堆,想修修不了、想腾腾不动的困境之中。

在 Kubernetes 中对于故障机的处理要“简单和粗暴”得多,不再要求对应用先扩容,而是直接把故障机上的容器进行删除,删除后才由负载控制器进行扩容。这种方案乍一听简直胆大妄为,落地 Kubernetes 的时候很多 PaaS 的同学都非常排斥这种方法,认为这会严重影响业务的稳定性。事实上,绝大多数核心的业务应用都维护着一定的冗余容量,以便全局的流量切换或者应对突发的业务流量,临时删除一定量的容器根本不会造成业务的容量不足。

我们所面临的关键问题是如何确定业务的可用容量,当然这是个更难的问题,但对于自愈的场景完全不需要准确的容量评估,只需要一个可以推动自愈运转的悲观估计就可以。在 Kubernetes 中可以通过 PodDisruptionBudget 来定量地描述对应用的可迁移量,例如可以设置对应用进行驱逐的并发数量或者比例。这个值可以参考发布时的每批数量占比来设置。假如应用发布一般分 10 批,那么可以设置 PodDisruptionBudget 中的 maxUnavailable 为 10%(对于比例,如果应用只有 10 个以内的实例,Kubernetes 还是认为可以驱逐 1 个实例)。万一应用真的一个实例都不允许驱逐呢?那么对不起,这样的应用是需要改造之后才能享受上云的收益的。一般应用可以通过改造自身架构,或者通过 operator 来自动化应用的运维操作,从而允许实例的迁移。<

不可变基础设施改造

Docker 的出现提供了一种统一的应用交付形式,通过把应用的二进制、配置、依赖统一在构建过程中打到了镜像中,
通过使用新的镜像创建容器,并删除掉旧容器就完成了应用的变更。Docker 在交付应用时和传统基于软件包或者脚本的交付方式有一个重大区别,就是强制了容器的不可变,想要变更容器只能通过新创建容器来完成,而每个新容器都是从应用同一个镜像创建而来,确保了一致性,从而避免了配置漂移,或者雪花服务器的问题。

Kubernetes 进一步强化了不可变基础设施的理念,在默认的滚动升级过程中不但不会变更容器,而且还不会变更pod。每次发布,都是通过创建新的 pod,并删除旧的 pod 来完成,这不仅保证了应用的镜像统一,还保证了数据卷、资源规格以及系统参数配置都是和应用模板的 spec 保持一致。

另外,不少应用都有比较复杂的结构,一个应用实例可能同时包含多个团队独立开发的组件。 比如一个应用可能包括了业务相关的应用程序服务器,也包括了基础设施团队开发的日志采集进程,甚至还包括了第三方的中间件组件。这些进程、组件如果想要独立发布就不能放在一个应用镜像中,为此 Kubernetes 提供了多容器 pod 的能力,可以在一个 pod 中编排多个容器,想要发布单个组件,只需要修改对应容器的镜像即可。

不过,阿里巴巴传统的容器形态是富容器,即应用程序服务器,以及日志采集进程等相关的组件都部署在一个大的系统容器中,这造成了日志采集等组件的资源消耗无法单独限制,也无法方便地进行独立升级。因此,在阿里巴巴这次上云中,开始把系统容器中除业务应用外的其他组件都拆分到独立的 sidecar 容器,我们称之为轻量化容器改造。改造后,一个 pod 内会包括一个运行业务的主容器、一个运行着各种基础设施 agent 的运维容器,以及服务网格等的sidecar容器。轻量化容器之后, 业务的主容器就能以比较低的开销运行业务服务,从而更方便进行 serverless 的相关改造。

不过,Kubernetes 默认的滚动升级过程过于僵硬地执行了不可变基础设施的理念,导致对多容器 pod 的能力支持有严重的缺失。虽然可以在一个 pod 中编排多个容器,但如果要发布 pod 中的一个容器,在实际执行发布时,不仅会重建待发布的容器,还会把整个 pod 都删除,而后重调度、再重建。这意味着假如要升级基础设施的日志采集组件,会导致其他组件,特别是业务的应用服务器被一起删除重启,从而干扰到正常的业务运行。因此,多个组件的变更依然没有解耦。

对业务而言,假如 pod 中有本地缓存的组件,而每次业务的发布都会重启缓存进程,这会导致业务发布期间缓存的命中率大幅下降,影响性能甚至用户的体验;另外,如果基础设施、中间件等团队的组件升级都和业务的组件升级绑定在一起,这会给技术的迭代更新带来巨大的阻碍。假设负责中间件的团队推出了新的 service mesh 版本, 而为了升级 mesh 还需要央求一个个业务发布才能更新 mesh 组件,那么中间件的技术升级就会大大减速。

因此,相比 pod 层次的不可变,我们认为坚持容器级别的不可变原则,更能发挥 Kubernetes 多容器 pod 的技术优势。为此,我们建设了支持应用发布时只原地修改 pod 中部分容器的能力,特别地建设了支持容器原地升级的工作负载控制器,并替换 Kubernetes 默认的 deployment 和 statefulset 控制器作为内部的主要工作负载。

另外,还建设了支持跨应用进行 sidecar 容器升级的 sidecarset, 方便进行基础设施以及中间件组件的升级。此外,通过支持原地升级还带来了集群分布确定性、加速镜像下载等的额外优势。这部分能力,我们已经通过 OpenKruise 项目开源出来。OpenKruise 中的 Kruise 是 cruise的谐音,'K' for Kubernetes, 寓意 Kubernetes 上应用的自动巡航,满载着阿里巴巴多年应用部署管理经验和阿里巴巴经济体云原生化历程的最佳实践。目前,OpenKruise 正在计划发布更多的 Controller 来覆盖更多的场景和功能,比如丰富的发布策略、金丝雀发布、蓝绿发布、分批发布等等。

总结

今年我们实现了 Kubernetes 的规模化落地,经受了 双11 大促真实场景的考验。像阿里巴巴这样有着大量存量应用的场景,落地 K8s 并没有捷径,我们经受住了快速规模化落地的诱惑,没有选择兼容和妥协落后的运维习惯,而是选择深蹲打好基础、选择深挖云原生价值。接下来,我们将继续推动更多应用的云原生改造,特别是有状态应用的改造,让有状态应用的部署和运维更加高效;另外,还将推动整个应用交付链路的云原生改造,让应用交付更加高效和标准化。


原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/517288.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDC:移动云进入云运营服务市场前五!

据IDC最新发布的《中国云运营服务市场跟踪&#xff0c;2019H2》显示&#xff0c;2019年下半年中国云运营服务市场规模达到107亿&#xff0c;同比增长27.9%。其中&#xff0c;移动云在全国云运营服务市场份额中占比4.9%&#xff0c;排名进入前五。什么是云运营市场服务&#xff…

三级联动

引入插件的css和js代码&#xff1a; <link href"./css/LArea.css" rel"stylesheet" > <script src"./js/LAreaData1.js"></script> <script src"./js/LArea.js"></script> html代码&#xff1a; <…

Attribute “singleton” must be declared for element type “bean”.

文章目录一、分析定位1.异常现象2.分析定位二、解决方案2.1.找坐标2.3. 找jar包2.3. 打开jar包2.4. 找目录2.5. 编辑xfire.xml2.6. 编辑xfireXmlBeans.xml一、分析定位 1.异常现象 Attribute “singleton” must be declared for element type “bean”. 2.分析定位 因为&a…

高德JS依赖分析工程及关键原理

一、背景 高德 App 进行 Bundle 化后&#xff0c;由于业务的复杂性&#xff0c;Bundle 的数量非常多。而这带来了一个新的问题——Bundle 之间的依赖关系错综复杂&#xff0c;需要进行管控&#xff0c;使 Bundle 之间的依赖保持在架构设计之下。 并且&#xff0c;为了保证 Bu…

为了这个技术,操作系统把 CPU 害惨了!

来源 | 编程技术宇宙责编 | Carol封图 | CSDN 下载自视觉中国内存访问瓶颈我是CPU一号车间的阿Q&#xff0c;前一阵子我们厂里发生了一件大喜事&#xff0c;老板拉到了一笔投资&#xff0c;准备扩大生产规模。不过老板挺抠门的&#xff0c;拉到了投资也不给我们涨点工资&#x…

一个周内上线50个增长策略,竟然能这么高效!

导读&#xff1a;年初的一个晨会上&#xff0c;用户增长负责人湘翁问我说&#xff1a;一个周内上线50个增长策略&#xff0c;技术兄弟们能做到么&#xff1f; 在闲鱼用户增长业务上的实验 闲鱼的用户增长业务具有如下现状&#xff1a; 闲鱼的卖家都是普通小卖家&#xff0c;而…

cannot convert value of type ‘org.codehaus.xfire.spring.editors.ServiceFactoryEditor

文章目录一、分析定位1.异常现象2. 分析定位二、解决方案2.1.找坐标2.3. 找jar包2.3. 打开jar包2.4. 找目录2.5. 编辑customEditors.xml一、分析定位 1.异常现象 cannot convert value of type ‘org.codehaus.xfire.spring.editors.ServiceFactoryEditor 2. 分析定位 原因…

网商银行首席架构师余锋:网商银行的每一笔贷款都是AI贷款

11月28日&#xff0c;在2019年度观察家金融峰会上&#xff0c;网商银行首席架构师余锋表示&#xff0c;网商银行在人工智能领域一直在探索新的应用方向&#xff0c;目前网商银行的每一笔贷款都是AI贷款。 网商银行是国内首家运行在云上的银行&#xff0c;没有线下网点&#xf…

解密 云HBase时序引擎OpenTSDB 优化技术

逝者如斯夫&#xff0c;不舍昼夜。 —— 孔子 时间如流水&#xff0c;一去不复返。自古不乏对时间流逝的感慨&#xff0c;而现代已经有很多技术记录流逝的过去。我们可以拍照&#xff0c;可以录像&#xff0c;当然还可…

官宣!CSDN 重磅发布「AI开源贡献奖Top5」「AI新锐公司奖Top10」「AI优秀案例奖Top30」三大榜单...

2020 年无疑是特殊的一年&#xff0c;AI 在开年的这场“战疫”中表现出惊人的力量。站在“新十年”的起点上&#xff0c;CSDN发起【百万人学AI】评选活动。我们继续聚焦AI的技术落地&#xff0c;关注开源和新生的力量。作为CSDN第三届AI评选活动&#xff0c;本次活动受到数百家…

SpringBoot2 整合 XFIRE 服务端和客户端

文章目录一、集成XFIRE1. 版本选型2. 导入依赖3. 注入XFireSpringServlet4. 创建一个xml文件5. 使用ImportResource注入xml6. 创建WebService接口6. 创建实现类7. 添加配置类8. 工具类二、XFIRE 发布服务2.1. 运行项目2.2. 异常解决2.3. 测试验证三、XFIRE客户端开源源码.一、集…

css3动画过渡按钮

css(css代码是网上找的)和html代码&#xff1a; .mui-switch {width: 52px;height: 31px;position: relative;border: 1px solid #dfdfdf;background-color: #fdfdfd;box-shadow: #dfdfdf 0 0 0 0 inset;border-radius: 20px;border-top-left-radius: 20px;border-top-right-ra…

阿里云上万个 Kubernetes 集群大规模管理实践

内容简介&#xff1a; 阿里云容器服务从2015年上线后&#xff0c;一路伴随并支撑双十一发展。在2019年的双十一中&#xff0c;容器服务ACK除了支撑集团内部核心系统容器化上云和阿里云的云产品本身&#xff0c;也将阿里多年的大规模容器技术以产品化的能力输出给众多围绕双十一…

SpringBoot2 整合 AXIS 服务端和客户端

文章目录一、服务端1. 版本选型2.导入依赖3. SERVLET4. 接口5.实现类6. 配置工厂7.启动类8. WEB-INF目录18. WEB-INF目录29. /目录19. /目录210. wsdd11. 测试验证二、客户端开源源码.一、服务端 1. 版本选型 阿健/框架版本spring-boot2.5.4axis1.4axis-jaxrpc1.4commons-dis…

地理文本处理技术在高德的演进(下)

在【上篇】里&#xff0c;我们介绍了地理文本处理技术在高德的整体演进&#xff0c;选取了几个通用query分析的点进行了介绍。下篇中&#xff0c;我们会选取几个地图搜索文本处理中特有的文本分析技术做出分析&#xff0c;包括城市分析&#xff0c;wherewhat分析&#xff0c;路…

真正拿大厂offer的人,都赢在这一点

学好一门技术最有价值的体现就是“面试”&#xff0c;对于大部分人来说 “面试”是涨薪的主要途径之一&#xff0c;因此我们需要认真的准备面试&#xff0c;因为它直接决定着你今后几年内的薪资水平&#xff0c;所以在面试这件事上花费再多的时间和精力都是值得的。你会发现有…

今天的这个小成绩,需要向阿里云的朋友报告一下!

今天&#xff0c;想向大家报告一个最新的小成绩&#xff1a; 在数据库领域的权威评选——Gartner全球数据库魔力象限评比中&#xff0c;阿里云成功进入“挑战者”象限&#xff0c;连续两年作为唯一的中国企业入选。 最新评选表明&#xff0c;阿里云过去一年在产品技术领域进展迅…

90%的人会遇到性能问题,如何用1行代码快速定位?

阿里妹导读&#xff1a;在《如何回答性能优化的问题&#xff0c;才能打动阿里面试官&#xff1f;》中&#xff0c;主要是介绍了应用常见性能瓶颈点的分布&#xff0c;及如何初判若干指标是否出现了异常。 今天&#xff0c;齐光将会基于之前列举的众多指标&#xff0c;给出一些常…

SpringBoot2 整合 CXF 服务端和客户端

文章目录一、CXF服务端1. 导入依赖2. 创建service接口3. 接口实现类4. cxf配置类5. 查看wsdl结果二、CXF客户端2.1. 客户端2.2. 断点调试2.3. 发起调用服务开源源码.一、CXF服务端 1. 导入依赖 <properties><cxf.version>3.3.1</cxf.version></propertie…

如果张东升是个程序员,你还有机会吗?

来源 | 编程技术宇宙责编 | Carol封图 | CSDN 下载自视觉中国张东升是一家互联网公司的程序员&#xff0c;一直以来都勤勤恳恳老实工作。可最近一段时间&#xff0c;老板接了几个项目回来&#xff0c;不但开启了996的工作模式&#xff0c;更要命的是频频更改需求&#xff0c;弄…