ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

混合云弹性伸缩实战:一个伸缩组统一管理IDC托管实例与ECS

混合云弹性伸缩实战:一个伸缩组统一管理IDC托管实例与ECS 做渠道商和代运维久了你会碰上一个特别拧巴的场景客户机房里那几台老物理机业务跑得好好的舍不得扔但一到促销季、月初报表日CPU就飙到95%又必须上阿里云补容量。以前我都是两套班子两套流程——IDC的机器自己SSH上去看云上实例再在弹性伸缩里配一套规则扩缩容全凭人肉值班。后来我把阿里云的托管实例和弹性伸缩搭在一起用才发现这两个功能本来就可以“一个组通管”同一个伸缩组里既有我手动挂进去的托管实例线下机器也有伸缩配置自动弹出来的ECS实例报警规则、定时任务、健康检查、生命周期挂钩全部一套配置走完。这篇文章就聊聊我在实际交付中怎么用弹性伸缩同时管好这两类实例。如果你是阿里云渠道商、代运维团队的交付工程师或者企业里管着混合云资产的运维负责人这篇可以直接照着搭。1. 先理解“实例”和“托管实例”在弹性伸缩里的定位1.1 弹性伸缩组的底层逻辑弹匣、子弹与压弹线先做个俗气的类比。伸缩组就是弹匣伸缩配置就是你定的子弹型号期望实例数就是弹匣里当前该有的子弹数量。你给弹匣设定一个“至少5发、最多15发、日常10发”的规则它就会根据射击情况自动压弹或退弹。具体到弹性伸缩里“最小实例数”“最大实例数”“期望实例数”这三个值基本决定了整个伸缩组的性格。最小实例数是保命线低于这条线伸缩组会想尽办法把实例补上来最大实例数是天花板超过这条线再大的流量也不会继续扩容期望实例数则是当前的目标容量扩缩容活动本质上都是在往“期望实例数”这个值靠拢。三大参数配合伸缩规则、报警任务、定时任务一起用才能形成一个有呼吸感的弹性体系。在这个逻辑里扩容和缩容的对象默认是“按伸缩配置新建出来的ECS实例”。这句话太关键了——很多渠道商第一次接触时以为伸缩组只能管它自己创建出来的机器导致客户IDC那批存量机器完全游离在体系之外。实际上阿里云弹性伸缩支持“手动添加已有实例”包括你账号下的存量ECS以及通过云助手注册进来的托管实例。把这两类实例挂进同一个伸缩组它们就一起被纳入了健康检查、报警触发、缩容策略的管理范围只是扩容时新创建出来的依然只有ECS。手动添加的实例不是伸缩配置“创建”出来的这一点也要分清。它们更像是弹匣里的原装子弹不在自动压弹的清单里但需要统一算在总数量中。伸缩组在判断“实例数够了没有”的时候不会区分你是手动挂的还是自动弹的它只看组内实例总数。所以后面我会反复强调算最小/期望/最大实例数时一定要把托管实例的数量也算进去否则很容易出现“自动补了一堆ECS”的成本事故。1.2 托管实例到底是怎么回事一次注册纳入云上管理托管实例简单讲就是把一台不在阿里云上的服务器用云助手这条通道“报到”你阿里云账号下。注册完成后这台机器在ECS控制台里能看到、能用云助手发命令、能被运维编排调度但它本身不是云产品不按ECS规格计费。它的本质是你借用了阿里云的管控通道把线下机器的状态、心跳、可执行命令的能力都拉到了云上统一视角。注册的核心是“激活码”机制。你在阿里云侧生成一个激活码带实例数量上限和有效期然后在要接入的线下机器上装好云助手客户端执行注册命令这台机器就成为了你指定地域、指定账号下的托管实例。激活码是一次性的过期作废注册过的机器会通过心跳持续上报状态云助手在后台维持一条稳定的管控链路。弹性伸缩和托管实例的结合点就在于托管实例也是一个“实例ID”可以被加入伸缩组的实例列表。伸缩组对它的管理能力和对ECS实例没有本质区别——健康检查、报警任务、生命周期挂钩都会作用到它头上。只不过它不会参与到“自动创建”这个环节里它更像“原装子弹”不在你自动压弹的清单里但需要统一算在总数量里。这一点特别适合渠道商客户最常问的就是“我这台线下机器能不能也享受你们的自动扩容服务”过去你得解释一堆现在答案很简单——把它注册成托管实例挂进伸缩组统一管。1.3 为什么渠道商特别吃这套统一管理的真实收益渠道商的利润来源往往不是单台机器的差价而是服务交付和运维效率。以前我管一个客户的混合云环境要开两个控制台IDC机器一套监控云上ECS一套伸缩告警电话来了还得先判断是哪边的机器出了问题。现在用一个伸缩组把两类实例收编之后告警、扩缩容、生命周期管理都收敛到同一个视图排障路径短了一大截。更重要的是客户看得懂。你跟客户说“你的8台IDC物理机和云上ECS在一个组里统一弹性”客户第一反应是“那我的物理机是不是会被你删掉”你只需要解释托管实例移出伸缩组只是解除管理关系线下机器不会关机更不会销毁。这类话术说清楚了客户对渠道商的专业信任度会明显提升。对于一个月要交付三五个客户的代运维团队来说这种“一套规则管所有机器”的模式能实打实省掉重复配置的时间。2. 渠道商常见的三种混合云弹性伸缩场景2.1 场景A客户IDC存量机器常驻云上实例高峰期补容这是我最常接到的需求。客户机房里有一套业务系统日常8台物理机跑着资源利用率其实只有30%到50%但每个月固定有那么几天业务量翻倍机房加机器不现实扩容周期也长。客户不愿意迁云只想在高峰期借用云上资源。这种情况下我把8台IDC机器注册成托管实例加入伸缩组伸缩组最小实例数设为8期望实例数设为8最大实例数设为15。平时组内就是8台托管实例没有云上ECS零云上成本。高峰触发报警时伸缩组按伸缩配置创建ECS实例补到9台、10台甚至更多高峰结束缩容策略把后创建的ECS实例移除组内又回到8台托管实例。这里有一个关键设置移出策略一定不能是默认的“最早创建的实例先移出”因为IDC机器注册时间早很容易被当成“最旧实例”优先移走。我会把移出策略改成“最新创建的实例先移出”同时给8台托管实例统一开启“保护中”状态。这样无论伸缩活动怎么折腾云上实例来来去去客户那8台物理机始终稳稳待在组内。这套组合拳下来客户满意度极高因为在他们的视角里高峰期“什么都没干”业务就不卡了。2.2 场景B渠道商多账号交付跨账号统一编排渠道商手里往往不止一个客户的账号。有的客户自己注册了阿里云账号授权给你做代运维有的客户干脆用你旗下的子账号。这种情况下我的建议是每个客户一套独立的伸缩组不要试图把不同客户的托管实例混到同一个伸缩组里。托管实例是属于具体账号的A账号注册的托管实例没法挂到B账号的伸缩组里跨账号硬搞只会给自己添乱。正确的姿势是“分账号管理总账号视图”。给每个客户账号单独开通弹性伸缩单独注册各自的托管实例渠道商自己的主账号通过RAM角色扮演的方式跨账号查看或操作这些伸缩组。RAM角色可以只读也可以授权伸缩组的管理权限看交付合同怎么签。我给客户做交付时习惯在客户账号下建一个RAM角色信任渠道商主账号并授予AliyunESSFullAccess。这样既能帮客户操作又能在出问题时说清楚“是哪一方操作的动作”。这里要特别提醒给子账号或者RAM角色授权时权限别给太大。弹性伸缩和ECS的权限尽量分开比如某位同事只需要调整伸缩规则就没必要给他释放ECS的权限。渠道商内部也要有“最小权限”意识不然内部误操作一样会影响到客户生产环境。2.3 场景C故障演练和灰度扩容用伸缩组做“先增后减”渠道商到了一定规模会接到客户“帮我做一次故障演练”的需求。基础设施层面最稳的演练方式就是“先增后减”先用伸缩组的报警规则模拟一次高峰扩容把云上ECS拉起来验证新实例能正常承接业务再把流量切回去触发缩容把多余的实例释放掉。整个过程在伸缩活动历史里都有记录演练报告也好写。演练的时候有一个细节容易被忽略如果客户IDC的托管实例在组内且没有开启保护状态缩容时系统有可能把托管实例移出来。演练不做还好一演练反而把生产节点挪出组业务直接抖动。所以演练之前我建议先检查实例保护状态、移出策略、冷却时间这三个配置项。宁可演练前多花5分钟做检查也不要演练完被客户追着问“为什么我的物理机不在组里了”。3. 完整实操一个伸缩组同时纳管两类实例3.1 动手前的准备清单附表格在创建伸缩组之前有几样东西最好一次性备齐省得到一半发现缺胳膊少腿。我按交付顺序整理了一张清单项目用途检查要点阿里云账号与地域资源归属托管实例和伸缩组必须在同一地域VPC与交换机伸缩组网络边界确认可用区、网段规划多可用区更稳伸缩配置定义新购ECS规格镜像、安全组、登录方式只对新购实例生效专线/云企业网IDC与VPC网络互通托管实例需要能访问云助手服务端点云助手客户端托管实例注册线下机器版本要与阿里云兼容激活码注册托管实例一次生成注意数量和有效期RAM授权控制台/SDK操作建议用子账号或RAM角色别用主账号AK这里面最容易卡住的是网络互通。托管实例的心跳和命令通道需要能到达云助手服务端点如果IDC和VPC之间没有专线或云企业网打通注册过程会异常缓慢甚至失败。有些客户为了省钱想通过公网直连也不是不行但安全性和稳定性就得打个问号。我的习惯是正式交付前先出一份网络连通性检查报告确认IDC侧能访问到目标地域的云助手服务端点再往下走注册流程。3.2 创建激活码并注册托管实例激活码的创建在ECS控制台“托管实例”页面里操作。创建时需要填两个关键值可注册的实例数量上限和有效期。数量上限就是你打算接入多少台线下机器有效期我一般建议24小时以内因为激活码是一次性凭据拖太久容易泄露或者被误用。生成激活码之后去IDC的机器上安装云助手客户端。Linux和Windows都有对应的安装包装完执行注册命令命令大概是下面这个样子aliyun-service-register --region cn-hangzhou --activation-code ACTIVATION_CODE --activation-id ACTIVATION_ID注意region要填和你的伸缩组一致的地域。执行完回到控制台刷新“托管实例”页面能看到这台机器上线。如果没出现先看云助手进程有没有起来再用日志定位。我之前踩过一个坑给Windows机器注册时忘了用管理员权限执行命令结果进程起来一半控制台一直显示“注册中”。后来统一操作规范所有线下机器都以管理员或root身份执行注册这个问题就再没出现过。还有一点激活码的“实例数量上限”要算好比如你有12台机器要注册就别只填10否则后面有几台永远进不来排查半天才发现是配额问题。3.3 创建伸缩组手动加入托管实例和已有ECS伸缩组的创建在弹性伸缩控制台完成。地域选好VPC和交换机选好如果没有现成的先去VPC控制台创建一个。伸缩配置这里也要写好因为只有配了伸缩配置报警触发了才知道要按什么规格创建ECS实例。镜像建议用业务最近的备用镜像安全组和登录方式一次配好避免扩容出来的机器“裸奔”。伸缩组创建完之后进入实例列表选择“手动添加已有实例”。页面里能勾选的对象有两类一是账号下的ECS实例二是已经注册成功的托管实例。把客户的存量ECS、托管实例都勾进去确认添加。在这里有一个关于期望实例数的小陷阱手动加入实例后期望实例数不会自动跟着变。你可以选择把期望实例数同步成当前实例数量也可以保持不变。如果你后续还想做弹性扩容建议把期望实例数调整到“当前实例数预留扩容空间”的位置。比如组里已经有8台托管实例期望实例数设为10伸缩组会认为当前还差2台立刻创建2台ECS来补位。这既可以是“主动补位”的用法也可能变成“意外烧钱”的来源完全取决于你怎么设。3.4 配置伸缩规则和报警任务让两类实例一起动伸缩组的“动静”由伸缩规则驱动。最常用的是报警触发规则比如CPU使用率超过80%持续5分钟就增加2台ECS实例。创建报警规则时要选好关联的云监控指标实例维度的CPU、内存、负载都可以作为触发源。定时规则适合有周期性的场景每天21点把期望实例数收回到8台第二天8点再扩到10台不用人盯。报警规则生效之后你会看到伸缩活动历史里出现两类动作一类是“创建ECS实例”这是伸缩配置在干活另一类是“移出/加入已有实例”这是手动添加的那些机器在被管理。对于托管实例它不会因为报警而“自动出现”报警只能驱动ECS的创建和释放。所以如果你想在高峰期增加“IDC侧算力”那是做不到的——伸缩组只能帮你调度和管理不能物理变出机房里的机器。这个预期一定要跟客户对齐否则客户会问“为什么我的物理机没变多。”4. 渠道商必须会调的四个参数以及成本控制玩法4.1 最小实例数、期望实例数、最大实例数的“三层设计”这三个参数是所有伸缩组设计里最核心的东西。我一般会按“业务常驻基数、日常水位、安全上限”来理解最小实例数就是业务跑通所需的最少机器数期望实例数是日常运行的目标水位最大实例数是成本和安全都能接受的天花板。模式最小实例数期望实例数最大实例数适合场景省钱模式托管实例数托管实例数托管实例数N平时零云上成本仅高峰补量平衡模式托管实例数托管实例数2托管实例数N日常保留少量云上冗余激进模式托管实例数2托管实例数4托管实例数N对扩容速度要求极高这里要特别强调最小实例数统计的是“组内所有类型实例的总数”。如果你有8台托管实例最小实例数却设成10伸缩组会认为当前缺2台立刻创建2台ECS去补位然后你的账单上就多出两台按量付费机器。我第一次给客户做混合云弹性伸缩时就是吃了这个亏所以后来的规矩是每次改参数前先看一眼实例列表里各类实例的数量再算一遍三层关系。宁可多花一分钟在纸上算也不要让账单教做人。4.2 冷却时间、移出策略、实例保护状态的默契配合冷却时间的作用是避免伸缩活动抖动。默认是300秒也就是说某次扩容完成后300秒内即使报警还在持续触发也不会再次扩缩容。冷却时间设得太短流量稍微波动一下伸缩组就会反复横跳ECS创建又释放成本哗哗涨设得太长高峰期扩容速度又跟不上。移出策略这块渠道商要格外留神。默认的“最早创建的实例先移出”在纯云上场景没毛病但组里一旦有托管实例就危险了——线下机器注册时间早很可能被当成“最旧实例”优先移出。我的标准做法是移出策略改成“最新创建的实例先移出”同时给托管实例逐个开启“保护中”。保护中的实例不会因为缩容活动被移出除非人为调整期望实例数或者手动操作这相当于给托管实例加了一道保险。实例“备用”状态和“保护”状态也不一样。备用状态的实例不参与伸缩组的健康检查和扩缩容计数适合做维护保护中的实例仍然参与计数只是缩容时不优先动它。渠道商在交付时最好把这些状态都跟客户讲清楚否则客户看一眼控制台看到“备用”“保护”几个字容易产生歧义。4.3 成本控制与计费边界托管实例不收费但扩容的ECS会托管实例本身不产生实例费用因为它不是云上资源这是它最大的吸引力之一。但要注意它借用了云助手通道、运维编排等云上管理能力这些能力有的免费、有的按量计费具体要看官方计费说明。我一般给客户的报价单里托管实例部分只收“管理服务费”云上扩容的ECS按照实际运行时长单独计费这样对双方都透明。成本控制的另一个抓手是“消息通知”。在伸缩组里配置事件通知伸缩活动发生时往钉钉群或者Webhook推送包括创建了几台ECS、释放了几台、原因是什么。这样客户和我们自己都能第一时间感知到成本波动而不是等月底账单出来才发现异常。渠道商要多做一步“成本趋势周报”哪怕只是把伸缩活动历史导出成表格也能极大提升客户的信任感。5. 实战踩坑与排查速查表渠道商高频问题5.1 托管实例注册失败或加不进伸缩组先按五步排查托管实例加不进去十有八九是下面几个原因。我的排查顺序固定效率很高。第一步看云助手进程是否正常运行进程挂了其他免谈。第二步看网络能不能访问云助手服务端点IDC防火墙经常静默丢包导致心跳不通。第三步查激活码是否过期或配额用尽。第四步确认地域是否一致别在杭州的地域里找北京的托管实例。第五步确认是不是同一个阿里云账号A账号注册的托管实例B账号的伸缩组肯定是加不进去的。加不进伸缩组时控制台通常会给出提示比如“实例类型不支持”“实例状态不在运行中”“实例已经在其他伸缩组中”。如果一台机器已经挂在另一个伸缩组里要加进新组得先从原组移除。实践中我踩过最隐蔽的坑是托管实例注册成功了但加入伸缩组时提示“实例状态异常”结果发现是IDC机器处于休眠状态云助手心跳断了被健康检查判定为不健康。这种情况直接去现场把机器唤醒就好。5.2 伸缩组总在扩容停不下来账单一路上涨这是渠道商最怕的故障之一。现象很典型CPU报警每隔几分钟触发一次ECS实例数量一路飙到最大实例数。原因通常有两个方向。一是伸缩配置本身太激进了阈值设得太低、冷却时间太短、扩容步长太大。二是健康检查误判托管实例因为网络抖动被标记为不健康伸缩组为了维持最小实例数疯狂创建ECS来“补位”结果托管实例恢复健康后组内实例数量又远大于期望值两边的动作叠加起来扩容活动就停不下来。我的处理方式是三层同时调。先把冷却时间从默认300秒调到600秒再抬高报警阈值比如CPU从80%改成85%且持续10分钟最后把扩容步长从“2台”改成“1台”让系统一步步试探而不是一步到位。同时去伸缩活动历史里看具体是什么原因触发扩容。如果确认是托管实例心跳不稳定导致的误判还要回头修云助手通道和网络质量光调伸缩组参数治标不治本。5.3 缩容时托管实例被误移出业务直接断流这个场景我见过不止一次。某天高峰过后伸缩组执行缩容结果客户IDC的机器从组里消失了云上实例还在业务反而比高峰时更不稳定。原因很简单移出策略是“最早创建的实例先移出”托管实例因为注册时间早被当成“最旧”的先移走了。别紧张托管实例被移出伸缩组不等于线下机器被删除或关机。它还在只是伸缩组不再管理它健康检查、生命周期挂钩都不再覆盖到它。真正的风险是业务流量还在往伸缩组转发而这台机器已经不在组内调度范围内造成流量分配异常。解决办法前面说过给托管实例开保护移出策略改“最新创建的实例先移出”。另外和客户沟通时也一定要提前打预防针告诉他们“移出”不等于“删除”避免客户自己操作时被这个现象吓到。5.4 跨账号用SDK操作时权限不足报错不断渠道商做到后面一定会走批量自动化这条路。用OpenAPI/SDK操作时最容易遇到的就是权限问题。报错往往很直接比如“Forbidden”或者“NoPermission”。这时候别急着怀疑代码先查RAM角色授权阿里云账号是不是授了AliyunESSFullAccess角色信任策略里有没有允许渠道商主账号扮演子账号有没有AccessKey权限。推荐的做法是先在OpenAPI Explorer里把接口调通再落成SDK脚本。比如“AttachInstances”这个接口可以用Python SDK这么写from aliyunsdkcore.client import AcsClient from aliyunsdkess.request.v20140828 import AttachInstancesRequest client AcsClient(AccessKeyId, AccessKeySecret, cn-hangzhou) req AttachInstancesRequest.AttachInstancesRequest() req.set_ScalingGroupId(asg-xxxxx) req.set_InstanceIds([i-xxxxx, mi-xxxxx]) resp client.do_action_with_exception(req) print(resp)这里的InstanceIds既可以是普通ECS实例ID也可以是托管实例ID。实际参数格式以官方API文档为准但整体逻辑就是这样。安全上我强烈建议不要在主账号下创建长期AccessKey子账号加RAM角色才是干净的路子权限范围要收敛到具体功能。5.5 一句话速查表症状可能原因处理办法托管实例注册失败云助手进程异常/网络不通/激活码过期先查进程再查网络重生成激活码托管实例加不进伸缩组地域不一致/已加入其他组/实例不健康核对地域、原组归属、健康状态扩容停不下来冷却时间短/阈值低/托管心跳抖动调大冷却、抬高阈值、修云助手通道缩容误移托管实例移出策略默认为最早实例改“最新实例先移出”开启保护跨账号API权限不足RAM角色未授权或未配置信任策略检查AliyunESSFullAccess和信任关系期望实例数与实际不一致手动添加实例后未同步期望值添加后主动调整期望实例数6. 渠道商进阶把弹性伸缩整体包装成可交付的服务6.1 用OpenAPI和SDK做批量交付摆脱控制台点鼠标渠道商如果要一周交付好几个客户再靠控制台手工点就太慢了。我的思路是把交付动作模板化把“客户名、地域、VPC ID、交换机ID、镜像ID、安全组ID”这些差异项做成输入参数然后用SDK脚本批量创建伸缩组、添加实例、配置伸缩规则。关键接口主要是这么几个CreateScalingGroup创建伸缩组CreateScalingConfiguration创建伸缩配置AttachInstances把已有实例和托管实例加入伸缩组CreateScalingRule创建伸缩规则EnableScalingGroup启用伸缩组。脚本写好之后交付一个新客户就是填几个参数的事。这里要提醒一下幂等性同一套脚本如果重复执行可能会提示资源已存在脚本里要写一个“先查再建”的逻辑避免重复创建。我一直觉得渠道商把“服务”卖出价值靠的正是这种标准化交付能力。客户第一次看到你10分钟把伸缩组搭好和自己折腾一天的效果一样他对你的专业认可就不一样了。这个口碑是用OpenAPI和SDK堆出来的。6.2 生命周期挂钩运维编排机器加入后自动初始化托管实例加入伸缩组后往往需要做一些自定义初始化改主机名、装监控Agent、同步配置文件、拉取最新发布包。如果每台都手动做又回到了人肉运维的老路。用生命周期挂钩可以把“加入实例”这个动作暂停住等你的脚本执行完再继续后续流程。生命周期挂钩的典型用法是和运维编排服务OOS配合。伸缩活动进行到某一步时触发一个OOS模板模板里定义了要跑的脚本或命令脚本执行完发送确认信号伸缩活动继续。托管实例加入时可以自动完成标准化安装云上扩容出来的ECS也可以通过伸缩配置里的自定义数据在一启动就完成初始化。这里有一个大坑脚本必须幂等。生命周期挂钩可能因为超时或重试而被执行两次如果你的脚本重复执行会出问题比如重复挂载目录、重复添加定时任务那就麻烦了。我习惯在脚本里加一个标记文件执行完就留下标记下次检测到标记就跳过这样即使重复调用也只有第一次真正干活。调试时先用一台测试机跑通再放到正式伸缩组上这是铁律。6.3 交付后的监控看板与成本透明是渠道商的口碑分水岭技术基本盘稳定之后渠道商拼的就是服务体验。客户最关心的两个问题永远是你帮我省了什么你有没有乱花钱弹性伸缩天然就是一个“省钱工具”和“成本风险点”并存的产品所以交付后一定要给客户一个看得懂的视角。我习惯给客户开一个“伸缩活动日报”当天扩容了几次、每次创建了几台ECS、平均运行了多久、释放了什么实例、目标机器是否健康。再配合钉钉群通知客户每天醒来扫一眼就知道昨晚系统发生了什么。遇到异常时间段的扩容客户甚至会主动截图发给你这时候你们已经从“甲乙方变成战友”了。成本透明加响应及时续约率自然就上去了。这个层面的价值已经超出了单纯“调参数”的技术范畴。最后再分享一个个人习惯。我做混合云弹性伸缩交付三年最大的心得就是“算数比调参更重要”。不管是托管实例还是普通ECS在伸缩组里统统只是一个数字。每次改最小、期望、最大这三个参数之前先数一数组里现有各类实例的数量算清楚这个调整会让系统处于什么状态。顺序上永远是先注册、再加组、再设保护事后才去调规则。这个顺序别乱基本就能把大部分坑挡在门外。毕竟弹性伸缩这东西用得好是业务救星用不好是账单加速器。希望这篇实战记录能帮你少走几步弯路。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进