OpenKruise:阿里巴巴双11全链路应用的云原生部署基座

Stella981
• 阅读 720

OpenKruise 是由阿里云于 2019 年 6 月开源的云原生应用自动化引擎,本质是基于 Kubernetes 标准扩展出来一个的应用负载项目,它可以配合原生 Kubernetes 使用,并为管理应用容器、sidecar、镜像分发等方面提供更加强大和高效的能力,从而在不同维度上通过自动化的方式解决 Kubernetes 之上应用的规模化运维和规模化建站问题,包括部署、升级、弹性扩缩容、Qos 调节、健康检查、迁移修复等等。

OpenKruise:阿里巴巴双11全链路应用的云原生部署基座

Kruise 是 Cruise 的谐音,'K' for Kubernetes,寓意 Kubernetes 上应用的航行和自动巡行,它满载着阿里巴巴多年在大规模应用部署、发布与管理最佳实践,以及阿里云 Kubernetes 服务数千客户的需求沉淀。

OpenKruise: 阿里巴巴 双11 全链路应用的云原生部署基座

在阿里巴巴经济体的整体云原生化过程当中,阿里的技术团队逐渐沉淀出了一套紧贴上游社区标准、适应互联网规模化场景的技术理念与最佳实践。这其中,最重要的无疑是如何对应用进行自动化的发布、运行和管理。于是,阿里云容器团队将这些能力通过 OpenKruise 反哺社区,以期指引业界云原生化最佳实践,少走弯路。

今年 双11,阿里巴巴实现了核心系统的全面云原生化。截至 2020 年 双11,阿里巴巴内部已运行近十万 OpenKruise 的 workload、管理着上百万容器。

1. 内部运行的 OpenKruise 版本代码超 95% 来自社区仓库

下图展示了阿里巴巴内部运行的 OpenKruise 版本与开源版本之间的关系:

OpenKruise:阿里巴巴双11全链路应用的云原生部署基座

从上图可以看出:Github 上的 OpenKruise 就是我们主体的上游仓库,而内部的下游仓库只基于公共接口实现了极少数内部耦合功能(这部分代码只占据了不到 5%),也就是说阿里巴巴内部运行的 OpenKruise 其中 95% 以上的代码完全来自于社区仓库。

有两点值得说明:

  • 所有通用能力,我们都会直接基于开源仓库开发和提交,然后再同步到内部环境。
  • 社区成员为 OpenKruise 贡献的每一行代码,都将运行在阿里内部环境中。

2. 在 Kubernetes 上自动化应用程序工作负载管理

做上层业务的同学可能对 “应用负载(workload)” 缺乏概念,这里先简单做个介绍。不知道你是否有好奇过,每一次应用扩缩容、发布操作的背后是如何实现的呢?在云原生的环境下,我们都是通过面向终态的方式去描述应用的部署需求(需要的机器数、镜像版本等等),见下图:

OpenKruise:阿里巴巴双11全链路应用的云原生部署基座

应用负载(workload)主要指的就是这个 YAML 定义和对应的控制器:

当应用扩缩容时,PaaS(运维平台)会修改上述 YAML 对象中的需求机器数(比如扩容 10 台改为 110,再缩容 5 台则改为 105),然后控制器就会按照 workload 期望的数量来调整实际运行的 Pod(容器)数量。当应用触发发布或回滚时,PaaS(运维平台)则会修改上述 YAML 对象中的镜像版本和发布策略,控制器就会按照给指定的发布策略来将所有管理的 Pod(容器)重建为期望版本(这只是一些便于理解的简化描述,实际工作机制会复杂得多)。

也就是说,应用负载(workload)管理着应用所有容器的生命周期。不仅应用扩容、缩容、发布都依赖于 workload 的工作,workload 还负责持续维持应用运行时的 Pod(容器)数量,来保证持续有符合期望数量的实例在跑着。如果有宿主机发生故障、上面的应用实例被驱逐,那么 workload 会立即再为应用扩出新的容器。

3. 双11 核心应用全面基于 OpenKruise 部署

随着阿里巴巴经济体上云,双11 主体相关的电商类业务、以及中间件等应用都迁移到了云原生环境下,统一使用 OpenKruise 的应用负载能力做部署。OpenKruise 提供了多种不同类型的 workload 来支持不同的部署方式:

OpenKruise:阿里巴巴双11全链路应用的云原生部署基座

  • CloneSet:(无状态应用)这是规模最大的部分,绝大部分泛电商业务都是通过 CloneSet 来部署发布。
  • Advanced StatefulSet:(有状态应用)目前主要是用于中间件在云原生环境的部署。
  • SidecarSet:(sidecar 生命周期管理)可以将定义好的 sidecar 容器动态注入到新建的 Pod 中,云上的运维容器、 mesh 容器都是通过这种机制加入到业务 Pod 中。
  • Advanced DaemonSet:将宿主机级别的守护进程部署到所有节点上,包括各种用于给业务容器配置网络、存储的基础组件。

因此,我们看到从上层电商业务到中间件,再到运维容器、基础组件,整个上下游链路都是依赖于 OpenKruise 提供的 workload 做部署和运行。不管是应用运行时的机器数量、版本管理,还是紧急扩容、发布等操作,都有 OpenKruise 无时无刻在维护着。

可以想象,如果 OpenKruise 出现了故障会发生什么?

  • 如果只是控制器挂了,则应用扩缩容、发布操作全量失败。
  • 而如果控制器逻辑存在重大 bug,比如数量或版本号计算错误,甚至可能引起业务容器大规模误删或是升级为错误的版本。

当然,针对以上高危情况,我们做了很多重的防护措施,务必保障业务的稳定可用。

这就是阿里巴巴的云上部署基座,OpenKruise 几乎承载了全量 双11 业务的部署管理与运维职责。

4. 主要能力

OpenKruise 从何而来?或者说什么问题或需求促使了 OpenKruise 的诞生呢?

当上云成为大势、当云原生逐渐成为标准,我们却发现 Kubernetes 原生提供的 workload 能力根本无法满足阿里巴巴超大规模业务场景的需求:

  • 应用发布时,所有容器都要飘移重建:对于我们来说几乎无法接受,在发布高峰期如果阿里巴巴的大规模应用都在大规模重建,这是不管对于业务自身还是其他调度器、中间件、网络/存储组件都是一种灾难性的压力。
  • 无状态应用负载(Deployment)无法灰度升级容器。
  • 有状态应用负载(StatefulSet)无法并行升级容器。
  • 还有很多,这里不一一列举......

在这种背景下,OpenKruise 出现了。我们通过或是全新开发(CloneSet、SidecarSet),或是兼容性增强(Advanced StatefulSet、Advanced DaemonSet),来使得上层业务终于可以顺利落地云原生。

OpenKruise 首推的功能就是“原地升级”。通过这种能力,我们终于可以使应用发布不需要将容器飘移重建,而是在原地、原 Pod 上只升级需要更新的镜像。这样带来的好处太多了:

  • 发布效率大大提升。根据不完全统计数据,在大部分业务场景下原地升级至少比完全重建升级提升了 80% 以上的发布速度:不仅省去了调度、分配网络、分配远程盘的耗时,连拉取新版本镜像的时候都得益于 node 上已有旧镜像、只需要拉取较少的增量 layer。
  • 发布前后 IP 不变、升级过程 Pod 网络不断,并且 Pod 中除了正在升级容器之外的其他容器都一直保持正常运行。
  • Volume 不变,完全复用原容器的挂载设备。
  • 确保了集群确定性,使全链路压测通过后的集群拓扑为大促提供保障。

当然,除此之外我们还增强了许多其他的高级能力,满足了许多种面向大规模场景下的业务诉求,本文不做一一介绍,但下图可以看到 OpenKruise 与 Kubernetes 原生应用负载针对无状态、有状态应用的功能对比:

OpenKruise:阿里巴巴双11全链路应用的云原生部署基座

作者 | 王思宇(酒祝)

原文链接

本文为阿里云原创内容,未经允许不得转载。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
2019 年 CNCF 中国云原生调查报告
!头图.jpg(https://ucc.alicdn.com/pic/developerecology/6db0c465111b4d9a96eb1ffe85c00e7a.jpg)中国72%的受访者生产中使用Kubernetes在CNCF,为更好地了解开源和云原生技术的使用,我们定期调查社区。这是第三次中国云原生调查,以中文进行
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这