享道出行:容器弹性技术驱动下的智慧出行稳定性实践

作者:郑嘉扬、何杉

前言

享道出行是一家专注于出行服务的专业品牌,是上汽集团实现汽车产业“新四化”(即“电动化、智能网联化、共享化、国际化”)的重要组成部分。作为上汽集团移动出行战略品牌,享道出行充分利用全产业链竞争优势,从消费者对安全及品质的需求出发,通过为消费者提供安全、高效、舒适、便捷的品质体验,打造品质出行服务平台。

图片

在快速的业务发展过程中,基础设施规模的不断增长,为企业管理者带来了对于效率和成本的高度关注。容器技术作为云计算时代基础设施的核心,自然成为了我们关注的焦点。随着容器技术及其生态的不断成熟,对于企业级开发者来说,在提高部署速度、优化资源利用率以及降低环境间差异等方面展现出了巨大的潜力。然而,随着容器数量的激增,如何管理和调度这些容器也成为了一个挑战。

业务架构与痛点

当前业务开发主要采用 Java 技术栈,应用部署架构如图所示:

图片

核心痛点

  • 目前使用的 Kubernetes 原生 HPA 弹性扩缩容方案以及 CronHPA 方案,在容器算力准备阶段流程长,包括算力资源准备、调度、镜像拉取、容器创建、容器启动以及应用启动导致冷启动基本是分钟级弹性。
  • 无法承接预期外流量,流量损失对业务有感。
  • 需要运维人员通过编码、维护程序自动化测算生产环境资源水位,评估扩缩容阈值,运维成本较高。测算结果不够精准也会导致资源浪费或影响业务稳定。

解决方案

针对以上痛点,为解决弹性滞后的问题同时兼顾成本最优,方案如下:

  • ACK AHPA 智能弹性
  • ECS、ECI 混合部署

图片

作为出行行业,享道的业务特征具备明显的潮汐效应,通过弹性架构改造,我们能够充分发挥云弹性算力的优势,进一步提升了业务自身的容错性。

图片

ACK 智能弹性(AHPA)

针对传统弹性能力所存在的问题,在方案设计阶段我们采用了 阿里云ACK 容器服务推出的 AHPA(Advanced Horizontal Pod Autoscaler)弹性预测,可以根据历史 Pod 的 Ready Time 以及历史 Metrics 自动学习规律,在业务量上涨之前的一个 Ready Time 开始扩容,在业务量上涨时 Pod 已提前准备,可以及时供给资源,解决弹性滞后的问题。

AHPA 弹性预测根据历史数据自动规划未来 24 小时每一分钟的应用实例数,相当于进行 1440 个点(一天为 1440 分钟)的 CronHPA 定时配置。

预先扩容

由于业务具有很强的潮汐属性,每日的涨潮落潮时间比较固定,AHPA 会根据过往的数据推测之后的所需要的 Pod 数量。例如,服务A根据以往双休日情况预测出这个双休日可能出现的 Pod 数量最大值为 16,那么就可以预先扩出来满足这些额外 pod。

图片

ECS、ECI 混合部署

如前文所述,AHPA 只能够解决应用层的弹性滞后问题,并不能提前对底层资源是否足够提前做出判断。这也意味着当底层资源不足时,仍存在使应用扩容时间被无限拉长的风险。

弹性容器实例 ECI(Elastic Container Instance) 作为一种纯 Serverless 容器运行服务,对于用户而言,无需管理底层服务器资源,同样也不需要关心运行过程中的容量规划,只需要提供打包好的 Docker 镜像,即可运行容器,非常适合应对这种流量突发场景下的业务场景。

但从成本性上讲,单位价格会相对裸金属 ECS 较贵,该方案结合了各付费模式和底层架构的优势,当前采取混合部署模式,兼顾成本及稳定性两方面的业务目标。如下图所示,未来目标是一半以上的应用作为业务基线部署在裸金属 ECS 上,对于周期型应用部署在按量付费的 ECS 资源,结合出行行业早晚高峰,剩余 10% 以上的场景均通过 ECI 实例保障。

图片

注: ECI 的计算资源与 ECS 等实例完全解耦,在每个可用区有单独的资源划分给到 Serverless 架构相关产品,对于大部分场景(CPU 数不超过 1 万 Core),无需担心资源不足的情况产生。因此 ECI 也是一种相对可靠的算力容量保障手段。

自定义弹性资源优先级调度

在资源的调度策略上,由于采用了 ECS 及 ECI 两种部署模式,我们期望应用扩容和缩容行为都是确定性的,当应用需要部署一个 Deployment,此时集群中有对应的多种类型的资源,分别是包年包月的 ECS、按量付费的 ECS 和弹性实例 ECI。

那么,部署的服务优先调度顺序理论上依次为:包年包月的 ECS、按量付费的 ECS、弹性实例 ECI。 同时在服务缩容时优先删除 ECI 上的 Pod,释放 ECI 的节点资源,然后删除按量付费的 ECS 上的 Pod,最后删除包年包月的 ECS 上的 Pod。

图片

对于包年包月及按量付费两种不同付费类型的节点需通过打上不同 label 标签实现。然后创建 ResourcePolicy 自定义节点池调度顺序。

ResourcePolicy 配置示例:

  apiVersion: scheduling.alibabacloud.com/v1alpha1
  kind: ResourcePolicy
  metadata:
    name: DEMO
    namespace: demo-ns
  spec:
    units:
    - max: 15
      nodeSelector:
        env: prd
      resource: ecs
    - max: 5
      nodeSelector:
        foo: bar
      resource: ecs
    - resource: eci
    whenExceedMax: NeverEvict

这里具体的调度策略可根据实际业务场景区分,若对于成本不敏感,且业务的波峰波谷抖动较大的场景,也可以考虑当 ECS 资源不足时,使用 ECI 弹性资源,进而加速 Pod 的启动时间。

向虚拟节点 Pod 注入 Sidecar 容器

在享道的集群架构中,存在采集微服务日志的场景,日志采集器会在 ECS 节点上通过 DaemonSet 方式部署 Agent,但虚拟节点不是真实节点,不支持运行 DaemonSet Pod,如何让调度到虚拟节点的 Pod 也支持上述 Agent 的同等能力呢?答案是向虚拟节点 Pod 注入 Sidecar 容器。

在实施过程中,我们希望做到:

  • 维护一份 Deployment 发布模板。在资源调度部署时,自动对底层 ECS 和 ECI 做区分,当 Pod 被调度到 ECS 节点时,无需注入 Sidecar 容器,当 Pod 被调度到虚拟节点时,则自动向 Pod 中注入 Sidecar 容器,从而实现通过维护一份 Deployment 发布模版,即可同时满足不同架构下的兼容性需求。
  • 对已有存量业务入侵尽可能小。根据软件设计开闭原则,应该对修改关闭,避免改动线上已经运行稳定的存量业务(如 DaemonSet),只增加新的或对新增内容做改变。

使用一个 Deployment 在原生 K8s 架构中无法做到,原因是添加 Sidecar 容器需要修改 Pod Spec,而原生 K8s 架构中 Pod Spec 落到 etcd 之后就不允许修改了,但 Pod 是否调度到虚拟节点是在 Pod Spec 落到 etcd 后由调度器决定的。因此,使用 OpenKruise 原生 SidecarSet,因为采用 Admission Webhook 机制,在 Pod 创建阶段通过 Label 的匹配所有符合条件的 Pod,此时 Pod 还未调度到虚拟节点,无法仅对调度到虚拟节点的 Pod 生效。

注: SidecarSet 是阿里云开源的云原生应用自动化引擎 OpenKruise 的核心功能之一。使用 SidecarSet 可以为集群中创建的符合条件的 Pod 自动注入 Sidecar 容器,实现 Sidecar 容器(如监控、日志等 agent)的定义和生命周期与业务容器解耦。

虚拟节点支持 SidecarSet 就是专门用于解决该问题。借助虚拟节点组件(ACK Virtual Node)仅为调度到虚拟节点上的 Pod 自动注入 Sidecar 容器,来解耦虚拟节点 Pod 的 Sidecar 容器与业务容器。其原理如下图所示:

图片

通过标签 Serverless.alibabacloud.com/virtual-node:“true” 指定,该标签会在 Pod 确定调度到虚拟节点后自动打上。同时,该方案与 OpenKrusie 原生 SidecarSet 完全兼容,对于后续 Sidecar 容器的升级、运维等操作,仍可以继续使用OpenKrusie原生 SidecarSet 实现。

自定义弹性指标

如上文所述,基于 CPU/内存的弹性指标无法同真实业务工作复杂完全拟合。很多场景下,用户期望根据自定义指标对应用进行扩缩容。AHPA 所提供的 External Metrics 机制,结合 alibaba-cloud-metrics-adapter 组件,可以为应用提供更丰富的扩缩容机制。

业务价值

当前享道出行已经规模化上线智能容器弹性能力,在保证稳定性的前提下,大大节省了资源成本,并能很好地应对突发流量。 如图所示:当阈值设置为 50,指标有到 50 的趋势时,即会触发弹性扩容,能够更好地应对突发流量,保障业务稳定性的同时,也能够实现可观的降本效果。

图片

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

4、jvm基础知识(四)

有哪些常见的垃圾回收算法? ⚫1960年John McCarthy发布了第一个GC算法:标记-清除算法。 ⚫1963年Marvin L. Minsky 发布了复制算法。 本质上后续所有的垃圾回收算法,都是在上述两种算法的基础上优化而来。 垃圾回收算法-标记清除算法 标记清…

“星际畅聊”来了!电子开启光通信,量子技术领航远程快速通讯

科学家们最近通过使用电脉冲将磁信息成功转换为偏振光信号,开启了一项革命性的量子技术。这一进展预示着未来包括地球与火星间长距离星际光通信在内的通信方式将发生翻天覆地的变化。 这项研究成果于3月27日在《自然》杂志上发表。研究聚焦于自旋电子学领域&#xf…

Gerrit学习

安装Gerrit 以Ubuntu 20.04为例,安装Gerrit容器2.15版本 docker-compose.yml version: 3 services:gerrit:image: gerritcodereview/gerrit:2.15ports:- 8080:8080- 29418:29418volumes:- ./review_site:/var/gerrit/review_siteenvironment:- CANONICAL_WEB_URL…

算法——距离计算

距离计算常用的算法包括欧氏距离、曼哈顿距离、切比雪夫距离、闵可夫斯基距离、余弦相似度等。这些算法在数据挖掘、机器学习和模式识别等领域中被广泛应用。 1.欧氏距离 欧式距离也称欧几里得距离,是最常见的距离度量,衡量的是多维空间中两个点之间的…

Docker容器、Serverless与微服务:腾讯云云原生架构技术实践案例集解析

前言 随着云原生技术的飞速发展,容器化和函数计算正成为企业和开发者关注的焦点。在这一潮流中,腾讯云凭借其卓越的技术实力和深厚的行业积累,发布了《2023腾讯云容器和函数计算技术实践精选集》,为我们提供了一份深入探索云原生…

【编译分析】MSVC编译器函数修饰的返回值问题

在阅读一篇关于函数重载的文章时,作者提到了MSVC进行函数修饰的结果比较gcc更加复杂。 通过查阅GPT发现可以使用vs提供的dumpbin工具查看编译之后的汇编程序相关信息,可以通过下面这条指令进行查看: dumpbin /all test.exe在结果中查看可以找…

[网鼎杯 2020 朱雀组]Nmap1

打开题目 在源代码中看到了提示 先随便输入127.0.0.1 那我们试试输入 127.0.0.1 | ls 可以看到 | 被转义符号\所转义 那我们输入 127.0.0.1 /| ls 得到三条反斜线 我们猜测,我们输入的东西是被escapeshellarg和escapeshellcmd处理过后的结果 我们输入的东西必须…

干懵过Intel、AMD的外星科技,又要再次降临了

2020年苹果 M1 芯片的横空出世,不光盘活了自家的Mac 产品,也让大家意识到 ARM 架构也能发挥出恐怖的实力。 为了涵盖各个定位,随后又是 M1 Pro、M1 Max ,最终还诞生了完全体 - M1 Ultra 。 两块 M1 Max 粘一起的规模带来了怪兽级…

skywalking idea中启动调试报错Output path is shared between the same module error

报错信息 简单描述:就是多个moudle一样用了一样的输出路径,这样容易造成冲突 Output path is shared between the same module error 参考:scala - Output path is shared between the same module error - Stack Overflow 解决方法&…

string容器以及vector容器的一些操作(常用的,不全)

目录 string 1.string的一些创建 2.string 的读入和输出: 3.string的一些操作 4.彻底清空string 容器的函数 vector 1.vector的一些创建: 2.vector的一些操作: 3.vector的彻底清空并释放内存: 参考:【C】如何…

【JavaWeb】Day31.SpringBootWeb请求响应——分层解耦(一)

分层解耦 1.三层架构 1.1 介绍 在我们进行程序设计以及程序开发时,尽可能让每一个接口、类、方法的职责更单一些(单一职责原则)。 单一职责原则:一个类或一个方法,就只做一件事情,只管一块功能。 这样就…

全网最全解析!Spring与非Spring环境下获取动态代理对象的原始目标对象

文章目录 前言在Spring AOP中获取动态代理对象的目标对象前置知识---SpringBoot默认是JDK动态代理还是Cglib动态代理?SpringBoot 2.x 版本分析Spring5 版本分析SpringBoot 1.x 版本分析SpringBoot 2.x 为何默认使用 Cglib 前置准备--工程准备1、自己写工具类获取--利…

中国力量:NeurIPS报告折射中国人工智能研究的惊人崛起

会议之眼 快讯 近年来,人工智能技术的发展和应用在全球范围内引起了广泛关注。2024年3月27日,美国保尔森基金会旗下的麦克罗波洛智库(MacroPolo)发布的《全球人工智能人才追踪调查报告 2.0》为我们揭示了这一领域的一个重要趋势&…

大模型 智能体 智能玩具 智能音箱 构建教程 wukong-robot

视频演示 10:27 一、背景 继上文《ChatGPT+小爱音响能擦出什么火花?》可以看出大伙对AI+硬件的结合十分感兴趣,但上文是针对市场智能音响的AI植入,底层是通过轮询拦截,算是hack兼容,虽然官方有提供开发者接口,也免不了有许多局限性(比如得通过特定指令唤醒),不利于我…

vite vue3 import.meta.glob动态路由

在Vite中使用Vue 3,你可以使用import.meta.glob来导入目录下的多个Vue组件,并自动生成路由。以下是一个简单的例子: router/index.js // router/index.js import { createRouter, createWebHistory } from vue-router;// 自动导入views目录下…

【算法】01背包问题(代码+详解+练习题)

题目: 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi,价值是 wi。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。 输入格式 第一行两个整…

举个栗子!Tableau 技巧(268):折叠文本表的数据列

之前,我们分享过 🌰 :灵活折叠文本表的多级数据行。陆续收到很多数据粉的反馈,想学习如何折叠文本表的数据列。 如下示例,假如将所有月份字段全部呈现出来,表格过长不利于查看数据。那么,我们就…

物联网网关和飞鸟物联平台如何助力其实现智能化升级,提升生产效率

随着工业4.0时代的到来,物联网技术逐渐成为推动工业转型升级的关键力量。物联网网关作为连接工业设备与网络的核心枢纽,在工业自动化、数据收集与分析等方面发挥着越来越重要的作用。本案例将围绕一家知名制造企业,展示物联网网关和飞鸟物联平…

职场人该如何学习使用AI大模型

【写在开篇:这是一篇针对非技术背景的职场人,学习和使用AI大模型的完全攻略。】 【今日份AI绘画:终身学习的职人】 非技术背景的职场人想要学习和使用AI大模型,可以遵循以下步骤: 1. 基础学习:首先&#…

Clickhouse-表引擎探索之MergeTree

引言 前文曾说过,Clickhouse是一个强大的数据库Clickhouse-一个潜力无限的大数据分析数据库系统 其中一个强大的点就在于支持各类表引擎以用于不同的业务场景。 MergeTree MergeTree系列的引擎被设计用于插入极大量的数据到一张表当中。数据可以以数据片段的形式一…