如何做到秒级扩容1000加业务节点

文章目录

  • 如何做到秒级扩容1000加业务节点
    • 写在前面
    • 一. 扩容时间长/服务响应慢
      • 替换容器载体为ECI
      • 实际应用
    • 二. 服务发现模式单一
      • 解决方法
    • 三. 容器隔离不健康
    • 四. 服务扩缩容断流
      • 解决方法
        • cronhpa控制器
    • 五. 扩容需求过多导致ip不够用
    • 总结

写在前面

这里如果想要了解这个项目的背景可以看我之前写过的一篇文章.
经过一段时间业务方的打磨在弹性扩容上我们遇到了很多问题, 这里我简单列举一下:

  1. 扩容时间长:ecs自动申请分钟级耗时;
  2. 服务响应慢:ecs申请到之后还需要加入k8s集群以及安装os和相关的网络资源;
  3. 服务发现模式单一:仅支持基于svc的rr负载;
  4. 容器之间隔离不健康:容器之间的隔离使用污点进行配置,操作繁琐并且依然存在抢占的肯能行;
  5. 服务扩缩容断流:扩缩容时存在流量闪断的情况;
  6. 大量弹性需求导致集群ip不够用:ip可用端超出集群上线;

对于上面的6个问题我会在下文中一一做出解答, 这些问题的答案也是我们如何做到秒级扩容1000加业务节点的方法. 希望能帮助到大家在k8s以及云原生相关的设计中带来一些启发.

一. 扩容时间长/服务响应慢

再使用ECS作为扩容节点时主要流程如下图所示:

  1. 到达定时扩容的时间,触发扩容动作;
  2. 判断当前弹性伸缩池中是否还有可用的机器,如果没有则申请新的ECS资源;
  3. 等待ECS初始化结束之后将其加入到k8s集群中,作为一个可用节点,初始化node节点,安装一些DaemonSet以及网络插件;
  4. 拉取镜像,进行容器初始化;
  5. 将服务注册到eureka上等待接受请求;
  6. 完成扩容动作,pod status转为Running.

通过梳理上述流程我们可以发现动作2/3/4是拖慢扩容的主要原因, 也是整个ECS扩容流程时延在分钟级别的主要原因. 为了是扩容的动作时间缩短到秒级我们就需要解决2/3/4让其可以快速的加入集群进行初始化, 快速的拉取镜像(甚至是不需要拉取镜像).

替换容器载体为ECI

为了解决之前提到的问题这里会引入一个新的技术–ECI.

阿里云弹性容器实例(Elastic Container Instance)为Kubernetes提供了基础的容器Pod运行环境,但业务间的依赖、负载均衡、弹性伸缩、定期调度等能力依然需要Kubernetes来提供。本文为您介绍如何通过Kubernetes集群与ECI对接,使用ECI作为Pod的运行资源。
ECI为您提供免运维、弹性、低成本、快速启动的容器运行环境。

  • Serverless:容器基础设施托管
    您只需要提交容器镜像,无需关心底层服务器。不需要预先创建集群和集群的维护,也不需要关注运行过程中的容量规划,专注业务领域创新。
  • 弹性:灵活部署
    以阿里云全球计算基础设施作为资源池,按需提供海量、高并发、多种资源类型(CPU、高主频、GPU、本地盘大数据计算加速)的容器计算资源。
  • 低成本:按量按秒收费
    按实例启动到结束时间段消耗资源收费。配合Kubernetes或者您自建的调度系统,ECI可根据业务流量自动弹性伸缩,减少空置费用。
  • 效率:秒级启动
    实例快速启动,从容面对突发访问,不需要提前预估集群和业务流量,按需扩容,轻松应对百倍的业务突发流量。
  • 兼容 Kubernetes
    Kubernetes集群上Pod能直接调度至ECI。无缝集成至阿里云容器服务托管版(ACK)和Serverless版(ASK),同时支持通过virtual kubelet对接用户自建Kubernetes。
  • 服务集成
    自动集成阿里云上产品,例如:SLS(日志服务)、NAS(文件存储)、云盘、ARMS(监控服务)等。

上述内容简单介绍了ECI的特点, 我们可以知道基于ECI部署的服务是秒级扩容的这个特性可以帮助我们解决之前的问题2.
当ECI与k8s进行结合的时候使用需要在k8s集群中创建一个虚拟节点"如下图所示

这个节点使用来处理ECI的流量, 实际的工作场景如下图所示

通过上图可以了直观的看到想要在k8s中使用ECI只需要在调度pod的时候将其指定到virtual-node-eci-0这个node上就可以了.
由于virtaul-node-eci-0这个虚拟节点是提前加入到k8s及群中的所以在创建ECI时不需要重新创建网络插件而是直接复用虚拟节点的就可以.

通过这些操作我们可以规避调之前提到的2和3问题.

实际应用

由于cronhpa的deployment和原有的deployment是完全独立的所以只需要在生产CronhpaDeployment的时候将nodeName指定进去就好

apiVersion: apps/v1
kind: Deployment
metadata:namespace: defaultname: nginx-base-eci
......serviceAccountName: filebeat-testnodeName: virtual-node-eci-0containers:# 指定ECI nodename- name: nginx-base-eciimage: registry.cn-beijing.aliyuncs.com/ailab-paas/nginx:1.1.1
......

实际部署效果如下图所示

二. 服务发现模式单一

这个问题的产生和我们最初的集群架构设计存在一定关系, 我们是基于SpringCloud+k8s实现的整体框架, 服务发现使用到了Eureka但是实际的请求负载是交给svc去做的, 整体网络结构如下图所示.

在负载的时候, 请求进入gateway, 之后从eureka上获取对应的服务信息, 获取其中的hostname, gateway拿着hostname去请求对应的svc, 最终的负载是交给svc去做的, 但是基于k8s部署的svc只有一种负载策略就是RR.
对于扩出来的cronpod我们只能将他加入到现有的svc中作为ep中的一个端点使用RR的方式处理请求. 但如果想要以权重的方式配置负载就无法实现.

解决方法

在处理这个问题的时候需要考虑如何实现按照权重进行负载, 对于gateway而言, 可以在转发请求的时候根据hostname的不同进行权重负载, 这也就意味着在向eureka注册的时候同一个application下需要有不同的hostname进行注册. 具体的网络结构如下图所示

对于弹性扩容出来的pod单独指定一个svc这样在配置权重的时候可以指定具体的svc想要匹配的权重大小

三. 容器隔离不健康

原有的弹性容器组在进行隔离的时候是居于污点进行隔离的, 但是基于污点的隔离操作无法做到精准控制, 如果拥有同样的容忍的类型的业务同事部署仍然会出现资源抢占的问题.

对于cronhpa的需求场景是需要尽量做到稳定扩容的, 如果出现抢占的情况就会造成资源无法稳定的完成部署. 之前提到的ECI在k8s场景中每个pod的部署都是完全隔离的, 一个ECI容器只会搭载一个pod, 而ECI的使用时从资源池中将资源划分出来的, 所以在这种场景下资源可以做到物理层面的隔离, 可以大大的提高服务的稳定性, 防止在扩容任务并发是产生资源抢占导致服务迟迟无法部署的问题.

四. 服务扩缩容断流

在进行服务扩缩容的时候会造成服务断流, 这个问题的主要原因是解决服务发现模式单一而引入的, 在之前的逻辑中负载均衡是交给k8s的svc去做的, 但是当引入了权重负载的概念后同时也增加了一个service, 对于扩容服务而言当进行缩容时所有的pod会全部下掉, 但是在网管中仍然保留了之前的缓存, 这也就意味着请求通过网关依然会转发到后端服务上, 为了解决这个问题我们需要在服务下线之前通知eureka将自己注销掉, 并且对于pod自身仍然需要保持Running状态持续接收网关发出的请求.

解决方法

k8s对于生命周期的处理自身是提供了preStop这样的监听去处理的但是当pod进行下线时出发了preStop中的逻辑就会将pod的状态立刻转为terminating同时对于svc而言会立刻把pod踢出
ep这也就意味着svc不会选择这个pod作为转发的地址.

如果是对于之前的情况(只是用同一个svc作为负载)那是没有问题的, 因为gateway最终获得的是svcName无论是原有的pod还是扩容出的pod使用的都是同一个svc这样gateway中的instance即使得到的是定时扩容的实例, 在负载时也会交到同一个svc上, 这样流量就会转到原有的pod上进行处理, 详情见下图.

支持了权重负载之后由于创建了两个svc所以请求获取到扩容出来的pod是取到的svcName实际上是专门负责处理定时扩容的pod由于流量
为了解决这个问题我们需要从另一个方面入手

cronhpa控制器

cronhpa控制器是用来处理定时伸缩任务的, 它在k8s是将任务作为CRD对象保存在etcd中, 通过cronhpa controller去管理定时任务, 到达伸缩的时间后通过clientSet修改对应的Deployments的副本个数.
了解了cronhpa的基本逻辑之后我们可以推断出修改Deployments中replicas个数的动作是由cronhpa的controller发出的, 所以可以在到达缩容时间后让控制器去请求eureka主动下掉对应的application然后在去修改Deployments的replicas完成缩容.

上图是修改之后的流程:

  1. 当到达缩容时间后,由cronhpa控制器用被缩容服务instanceId从control服务获取对应的下线脚本;
  2. 返回脚本
  3. 执行脚本下线对应服务
  4. 等待60秒钟让网关重新从eureka获取注册列表
  5. 通知对应的deployment进行伸缩
  6. 通知ApiServer删除对应的Pod
  7. EP发现Pod状态不为Running,将其ip移除
  8. 执行后续preStop并结束缩容动作

五. 扩容需求过多导致ip不够用

在k8s集群中每个node会有属于自己的ip范围, 这个ip范围来自于同一个网段, 如果我们的网段地址是C类地址, 可用总数约为200w个在ACK(阿里云k8s容器服务)每添加一台机去需要提前指定可用ip范围, 指定范围之后这段ip就只能被这一台机器使用, 如果一台机器我们指定可用ip为4096个那么集群内可以添加的机器总数上线就是488个, 随着业务规模的增长我们的k8s集群内的node个数早已逼近这个范围, 所以当需要扩容1000个业务pod时使用传统的ECS方案已经无法满足了.

在之前介绍的ECI中有提到, ECI加入到k8s集群时并不是作为一个node节点加入进去的, 而是提前创建一个虚拟node然后在虚拟node中进行一次跳转, 将请求路由到ECI的具体服务上

通过这两张图可以看到虚拟节点的ip与原有node不属于同一组, 这样在扩容的时候就可以很好地隔离原有pod与cronpod的ip资源防止大量的扩容请求导致线上正在运行的业务受到影响.

总结

上面的内容就是我们目前在定时伸缩方向上的探索,网校,题拍拍,培优,智康,小猴等部门的考验已经做到了在使用定时伸缩的前情况下达到了日调用了五个九的稳定性.
但是目前仍然有很多问题需要解决:

  1. 如何加快拉取镜像的速度
  2. 如何更优雅的进行eureka下线(避免修改cronhpa control的代码)
  3. 增加伸缩动作相关的告警

如何做到秒级扩容1000加业务节点相关推荐

  1. 2022 IoTDB Summit:IoTDB PMC 曹高飞《Apache IoTDB 秒级扩容能力与存算分离实践》

    12 月 3 日.4日,2022 Apache IoTDB 物联网生态大会在线上圆满落幕.大会上发布 Apache IoTDB 的分布式 1.0 版本,并分享 Apache IoTDB 实现的数据管理 ...

  2. 超强性能,秒级存储,华为云GeminiDB for Cassandra 正式商用了

    云数据库GeminiDB是一款基于华为自主研发的计算存储分离架构的分布式多模NoSQL数据库服务.在华为云高性能.高可用.高可靠.高安全.可弹性伸缩的基础上,提供了一键部署.备份恢复.监控报警等服务能 ...

  3. 秒级加速质变,Apache Doris与360数科的“化学反应”

    随着信贷科技的不断发展,使大数据分析场景相应地增加了许多,对于金融科技平台而言,这些新场景对数据的安全性.准确性.实时性提出更严格的要求.与此同时,指数级增长的用户数,也向业务端施加了交付效率.稳定性 ...

  4. 交易中台架构设计:海量并发高扩展,新业务秒级接入

    本文根据孙玄老师在[deeplus直播第219期]线上分享演讲内容整理而成. 孙玄 奈学教育CEO 10年技术老兵,擅长系统架构设计.大数据.运维.机器学习.技术管理等领域: 曾供职于百度.58集团. ...

  5. DDM实践:数据库秒级平滑扩容方案

    2019独角兽企业重金招聘Python工程师标准>>> 本文部分内容节选自华为云帮助中心的分布式数据库中间件(DDM)服务的产品介绍 背景 随着业务增长,逻辑库存储空间不足,并发压力 ...

  6. mysql秒级平滑_DDM实践:数据库秒级平滑扩容方案

    本文部分内容节选自华为云帮助中心的分布式数据库中间件(DDM)服务的产品介绍 背景 随着业务增长,逻辑库存储空间不足,并发压力较大. 解决方案 此时可对DDM实例逻辑库进行平滑扩容,通过增加RDS实例 ...

  7. 中台设计和实践:海量并发业务中台,新业务秒级接入交易中台

    孙玄 奈学教育CEO 读完需要 10 分钟 速读仅需 3 分钟 10年技术老兵,擅长系统架构设计.大数据.运维.机器学习.技术管理等领域: 曾供职于百度.58集团.转转等公司. 本文根据孙玄老师在[d ...

  8. Mysql8秒级加字段_MySQL8.0大表秒加字段,是真的吗?

    前言:? 很早就听说 MySQL8.0 支持快速加列,可以实现大表秒级加字段.笔者自己本地也有8.0环境,但一直未进行测试.本篇文章我们就一起来看下 MySQL8.0 快速加列到底要如何操作. 1.了 ...

  9. 炸!亿级数据DB秒级平滑扩容!!!

    一步一步,娓娓道来. 一般来说,并发量大,吞吐量大的互联网分层架构是怎么样的? 数据库上层都有一个微服务,服务层记录"业务库"与"数据库实例配置"的映射关系,通 ...

  10. mysql 平滑扩容_数据库秒级平滑扩容架构方案

    一.缘起 (1)并发量大,流量大的互联网架构,一般来说,数据库上层都有一个服务层,服务层记录了"业务库名"与"数据库实例"的映射关系,通过数据库连接池向数据库路 ...

最新文章

  1. 太扎心!人艰不拆!16 个程序员专属笑话讲给你听
  2. linux mmap 详解【转】
  3. 复合火焰探测传感器_火灾探测器分类
  4. redis 获取所有key_Redis笔记
  5. 几个高效做事的法则,让你的一天有 25 小时
  6. python日志处理_Python之日志处理(logging模块)
  7. 软件测试的基础知识(五)
  8. Full details will be found in the appropriate container log 解决办法
  9. 安徽50岁计算机职称免考,50岁以上评职称免考外语
  10. java 锁表后事务提交_关于synchronized锁在Spring事务中进行数据更新同步,仍出现线程安全问题...
  11. python实现多智能体一致性_多智能体深度学习算法MADDPG的PARL实践
  12. TextView属性总结,简单的控件也可以很复杂
  13. 深入浅出WPF(一)
  14. 安卓手机虚拟键盘定位position:fixed问题
  15. VM 中设置 Mac 虚拟机 系统联网与时间
  16. ADS1278字符驱动
  17. jqury实现异步文件上传
  18. 第二章 聚合数据模型
  19. 塑料袋吹膜机多少钱一台_塑料袋制袋机多少钱一台-卓越机械(在线咨询)-塑料袋制袋机...
  20. 物联卡中心:物联网卡运营商优劣对比,你选择哪家?

热门文章

  1. 基于egret的点光源光线效果的实现
  2. 如何获取节假日的方法
  3. 《pr2019》怎么加字幕
  4. 国内最受欢迎的API市场对比和介绍
  5. 七周成为数据分析师 第六周:统计学
  6. 抖音api开放平台对接_抖音开放一键发布功能 第三方内容可分享至抖音
  7. 创业公司必备,20个提升团队工作效率的工具神器
  8. 程序员如何提升开发团队的协作效率和质量?
  9. 【每日一具10】磁力资源搜索助手特别版
  10. 苹果手机屏幕镜像_微软应用上线屏幕镜像功能:可在PC端控制安卓手机