浅谈K8s下的应用变更
创始人
2025-05-28 10:59:09

这里的“应用变更”,是指应用程序的升级更新,也即应用的日常的版本变更。

跟传统的物理机/虚拟机下的应用变更相比,K8s下的应用变更具有如下特点:

  • 变更粒度不同:物理机/虚拟机下部署的粒度一般是机器,一台机器部署一个应用实例;K8s下,POD才是部署和升级的基本单位,一个POD代表一个应用实例;

  • 部署产物不同:物理机/虚拟机下的部署制品是CI构建好的二进制包(一般会存在FTP服务器),K8s下则是制作好的镜像(一般会存放在镜像仓库里);

  • 自动程度不同:K8s下的部署变更的自动化程度会更高,从POD的删除、重新调度、拉镜像、容器启动等,都是交由K8s会自动完成;

接下来将会聊聊业内有哪些应用变更方式(k8s原生的变更、POD原地升级、容器热升级、容器内发布)及其优缺点、适用场景等。

注:本文并不是去比较各种发布模式(如灰度发布、蓝绿发布等) ,这方面在网上已有很多资料讲的很详尽,不再赘述


变更发布的基本要求

生产环境的应用变更,一般会有如下基本要求:

  • 灰度原则:能够做到分批逐步变更,如先变更少量实例,待验证通过后,再对剩余的实例分批变更。

  • 业务无损:在发布期间对业务造成的影响尽可能小,一般是指发布期间,业务流量不受影响。

  • 发布效率:控制发布的总时长,这里的时长主要是消耗在流量剔除和恢复、镜像拉取、容器启动、变为ready状态这几个环节 。

为了降低变更风险,保证变更的稳定性,每个企业对于各自生产环境的变更发布,也会有自身的一些要求,这方面业内比较知名的是阿里提出的“变更三板斧“:

  • 可灰度:任何变更,都必须是可以灰度的,即控制变更的生效范围。先做小范围内变更,验证通过之后才扩大范围;

  • 可观测:在灰度过程中,必须能做到可监控,能了解到变更之后对系统的应用。如果没有可监控,则可灰度也就没有意义了;

  • 可回滚:当通过监控发现变更后会引发问题时,还需要有方法可以回滚,将版本快速回退到变更前的原版本;


K8s原生的滚动更新

K8s是通过工作负载来管理POD的创建、运行、销毁等,K8s原生的工作负载(Deployment、DaemonSet、StatefulSet等)都支持滚动更新,即通过启动一些新的POD,等这些新的POD启动完成后,再杀掉一些老的POD,循环此过程,直至完成更新。

虽然K8s原生的这种滚动更新策略可以在大部分情况下,实现零宕机时间和无生产中断的升级,但也存在一些没有解决的问题,主要包括以下几点:

  • 支持的发布策略有限:K8s 原生仅支持停机发布、滚动发布两类变更策略。如果应用有蓝绿发布、金丝雀发布(即灰度发布)、A/B 测试等需求,需要进行二次开发或使用第三方工具。

  • 缺乏可控升级的机制:K8s缺乏发布之后的验证控制,即发布完成后,readness probe成功了,K8s就会认为服务发布成功,自动继续滚动更新。K8s原生的滚动更新是全自动的,中途无法做到发布暂停,以灰度验证,而很多企业在实际生产环境的应用变更上,往往是有这方面的要求的,例如要求有手工确认的过程,确认后再进行下一批次的变更 或者 至少前面的灰度阶段可以支持手工确认。

  • 无法指定实例变更 :即无法让用户指定任意实例进行变更,例如无法按节点灰度,或按照指定条件选择指定的实例进行灰度等。

  • 不支持容器热重启:K8s原生的应用变更都是基于标准的镜像发布,即需要销毁老POD、重新调度创建新POD、再去仓库拉取新版本镜像、启动容器等,由于整个POD要销毁重建,不支持POD不重建,更不支持POD内的容器不重建。

  • 无法分批逐步扩缩容:同前面第2点,有些应用在扩容或缩容时同样需要分批逐步执行,需要可控的、能暂停进行灰度验证的扩缩容,k8s 还不支持。

可以看到,在如何保证应用在企业生产环境的变更升级过程中,更加安全、可控、自动化上,K8s还有待进一步优化和提升,以满足更多面向生产场景的发布需求。

目前K8s对于使用了K8s Service的应用能够做到自动摘除流量和恢复流量,但实际生产环境中使用K8s service作为服务发现的应用占比还是比较低(很低)的,因此大部分应用如果要保证在发布期间流量无损,一般还需要二次开发,例如在发布系统或自建的云平台中,去调用服务发现平台来摘除和恢复流量(在发布前摘除流量,在发布后恢复流量),即先将业务切流,再升级版本(这可能是目前采用最多的一种流量无损的变更升级方式)。当然,也可以在应用编排里,设置preStop的事件处理(如主动去切流),这样POD在停止前会调用该preStop事件对应的处理(可以是一个脚本或一个tcp/http接口),尽量降低POD停止(即销毁删除)时对业务流量的影响。


POD原地升级

所谓原地升级模式,就是在应用变更过程中避免将整个 Pod 对象删除、新建,而是基于原有的 POD对象,只对该POD内的某一个或多个容器的镜像版本进行更新。

K8s原生的工作负载并不直接提供原地升级能力,但其实kublet组件隐藏地支持这个能力。对于某个正常运行的POD,可以通过patch的方式更新pod spec中的镜像,kublet感知到这变化后,会自动杀掉POD内旧版本镜像的容器,再拉起一个新版本镜像的容器。在整个过程中,POD并不需要销毁重建,依旧保持运行。

K8s 的更新策略是删除旧 Pod,新建一个 POD,然后调度等一系列流程,才能运行起来,而且 POD原先的绑定的资源(本地磁盘、IP 等)都会变化。而原地升级受影响的只是容器(容器会重建,但POD不会重建),但本地磁盘不变、IP 不变,能大大地减少变更带来的性能损失以及服务不可用,进一步降低变更带来的影响,。

具体来说,原地升级能够带来如下收益:

  • 节省了调度的耗时,POD 的位置、资源都不发生变化;

  • 节省了分配网络的耗时,POD 还使用原有的 IP;

  • 节省了分配、挂载远程盘的耗时,POD 还使用原有的 PV(且都是已经在 Node 上挂载好的);

  • 节省了大部分拉取镜像的耗时,因为 Node 上已经存在了应用的旧镜像,当拉取新版本镜像时只需要下载很少的几层 layer。

一般需要基于现有的K8s机制去自研新的工作负载来支持原地升级,不过,目前已开源的K8s平台或组件都已提供了支持原地升级的工作负载,例如阿里云的OpenKruise中的CloneSet/Advanced StatefulSet、蚂蚁的CafeDeployment、腾讯TKE的TApp/StatefulSetPlus 等。


容器热升级

跟上面的原地升级(POD不重建,但POD内的容器会重建)相比,容器热升级则更进一步,POD内的容器也不需要重建,容器能自动完成镜像热更新,容器内的业务进程也可以实现热重启,最大限度减少变更发布对业务产生的影响。

以DaemonSet为例,目前K8s标准的DaemonSet 滚动升级过程,是通过先删除旧Pod、再创建新 Pod 的方式来做的。在绝大部分场景下这样的方式都是可以满足的,然而如果这个 daemon Pod 的作用还需要对外提供服务,那么滚动的时候可能对应 Node 上的服务就不可用了,也即事实上是流量有损的。

另外,不仅仅是DaemonSet,对于即使像Deployment这种用于部署无状态应用的工作负载,虽然可以采用”先对业务切流,再升级版本“(即先切走应用的流量,等待一段时间没有请求之后,再升级应用版本,然后再恢复流量)这种形式来变更升级,但这种方式下,POD需要销毁、重新调度、重建,带来较大开销的同时,也可能影响业务的稳定性。并且有的企业因业务场景的需要,也会对部分非常敏感、及其重要的场景的应用,要求尽量热重启,则此时,原地升级是无法满足要求的。

但目前K8s原生的工作负载是无法做到热升级,往往需要自己实现,常见的一种思路是,修改docker和kubelet的源码支持镜像热更新,当把spec.updateStrategy.type配置为HostPatchUpdate时,就会通过更新POD中的容器镜像版本并添加annotation的方式,联动kubelet和docker完成容器镜像热更新的功能。在整个过程中,POD及POD内的容器均无需重建,此后,用户可以通过向容器中的进程发送信号(例如调用容器内业务进程的重启脚本)的方式,完成业务进程的reload,保证服务的不中断。

这种方式的前提是,该应用本身在物理机/虚拟机环境下就支持热重启(目前很多rpc框架已支持应用的热重启),因为在镜像热更新完成后,还需要复用该应用的热重启能力。

由于上面这种方式涉及到修改kubelet和docker源码,可能会造成依赖的K8s平台与特定版本的k8s和docker绑定耦合,对后续的K8s社区版本的同步升级会引入复杂度和风险,所以现在也有越来越多的企业通过sidecar的方式来实现容器热升级,例如蚂蚁开源的MOSN,通过自己实现的SidecarSet 提供了对业务无感的热升级方式。它开发了长连接迁移方案,把这条链接迁移到 New process 上,整个过程对 Client 透明,不需要重新建链接,达到请求无损的平滑升级。

注:更多关于MOSN容器热升级可详见https://mosn.io/docs/products/structure/smooth-upgrade/

但对于存量系统而言,尤其是业务很稳定、存在较多历史遗留问题的情况下,采用SideCar方式可能会对现有的系统有一定(甚至较大)的冲击,比如可能要求应用要进行较大改造,才能满足SideCar的引入要求,有时其收益比可能会相对较小。

如果是DaemonSet的热升级,也可以考虑阿里云开源的OpenKruise套件中的Advanced DaemonSet,它本身支持热升级。


容器内发布

容器内发布,本质上并不是直接基于镜像的发布,依旧是通过覆盖二进制文件的方式完成版本变更(这里的二进制文件可以是直接来自CI构建好的部署制品,也可以来自拉取镜像后的镜像文件),某种程度上,其实有点接近于 物理机/虚拟机 下的发布方式,因此,这是容器化环境下的一种并不云原生、非标准化的一种发布方式。

在容器化环境下,之所以会有这种“奇怪”的发布方式,是因为它也有一定的适用场景,它一般适用于因历史遗留问题,为了最大程度兼容现状,部分应用需要尽量平滑迁移上云的场景。

例如:

  • 复用现有能力:某些企业受限于自身的技术能力或资源有限,或者因为历史原因,相关微服务的技术组件或基础设施建设不太完善,尤其是服务发现组件不够成熟(比如服务发现流量摘除比较慢或不稳定),在物理机/虚拟机环境下,他们是通过应用的热重启(目前很多rpc框架已支持应用的热重启)来保证变更发布期间对业务流量的无损的,因此也希望上云后能继续复用起现有的热重启的能力,也希望现有的一些运营能力(如发布)也能尽量复用,而不想再投入资源去单独建设。

  • 富容器场景:因为历史原因,一些长尾业务,要完全按照上云的标准改造,改动成本会很大,但又想享受上云带来的红利,所以会先尝试采用富容器的方式,即一个POD内有一个业务容器,但该业务容器内有多个不同业务的进程,即把POD当做一台虚拟机来用。这种富容器模式下,如果要采用标准的镜像发布,则会带来很多问题,例如可能会因镜像体积过大、更新启动缓慢(漂移性能也堪忧),且一个业务要更新,则会连累同个容器内的其他业务也要跟着更新,扩大了变更风险。

容器内发布方式下,相对可能可以对现有体系冲击较小,例如原有的应用改造很小或几乎不用改造、可以最大程度复用原有的发布运营能力,应用侧的热重启能力也能继续复用 等,但同时也会引入版本发布时,版本不一致的风险,需要一些额外的手段来保证和消除因发布时POD重启带来的版本不一致。

容器内发布目前有两种实现方式:

方式一:类似于物理机/虚拟机下的变更发布,发布系统直接将CI构建好的二进制包,上传到目标机器,然后登录到POD内,覆盖容器下指定目录下的文件,再调用POD内业务容器里的业务重启脚本,以重启容器内的业务进程,完成变更。

方式二:POD内除了一个业务容器外,还会有一个SideCar容器。跟方式一相比,发布系统仅仅是触发,具体的执行都是交给了该SideCar容器,例如上面提到的拉取CI构建好的二进制包(这里则是直接去拉取镜像,不再是二进制包)、重启容器内的业务进程等都是SideCar容器负责。

两种方式的比较:

方式一下,也会基于最新的二进制包版本制作对应新版本的业务镜像,但制作好的业务镜像并不会直接用于变更发布(因为POD不会重启,不会去重新拉最新的镜像),而是只有在POD重启、扩容时才会用到,因此在变更的同时,如果POD刚好重启了,则此时该POD还是旧版本,需要检查出来,并再发布一次。

方式二下,POD内的SideCar容器会去拉取镜像,最后把镜像文件去覆盖业务容器的镜像,相对来说,方式二的版本一致性会更好一些,更有保证,即使覆盖时发生了POD重启,则拉取到的也是新版本的镜像,不会出现方式一那种版本不一致的情况。


最后的话

本文主要聊聊了k8s原生的变更、原地升级、容器热升级、容器内发布这4种变更方式,其实无论哪一种方式,都有其适用场景,并没有优劣之分,该采用哪一种变更方式,都是需要你结合实际场景需要来做出选择。

但无论哪一种,都要考虑好,在变更升级过程中,如何更加安全、可控、自动化,尤其是发布期间要尽量减少对业务的影响,让业务无感知。

生产无小事,变更需谨慎。

相关内容

热门资讯

“深夜AI轰炸”消费者起诉获赔... 日均接到2~3个推销电话,甚至深夜被AI客服“轰炸”,信用卡营销骚扰正成为消费者投诉的焦点。近期,上...
国投智能跌0.65%,成交额1... 6月27日,国投智能跌0.65%,成交额1.74亿元,换手率1.47%,总市值117.66亿元。 异...
硕世生物:肺炎支原体核酸检测试... 中证智能财讯 硕世生物(688399)6月27日晚间公告,公司近日收到国家药品监督管理局签发的关于肺...
V观财报|紫金矿业:拟12亿美... 【V观财报|紫金矿业:拟12亿美元收购哈萨克斯坦RAYGORODOK金矿项目】紫金矿业在港交所公告,...
事关科技强国,国常会最新定调|... 上周A股过去一周(6月23日—6月27日),A股三大指数全线上涨。截至6月27日收盘,沪指报3424...
江苏常熟农商银行借道上海银行,... 常熟农商银行南京江宁支行正式揭牌开业,意味着常熟农商银行成功进入省会南京。值得注意的是,南京江宁支行...
香港的稳定币准备怎么玩? 你可能存在一些误解,香港是中国的特别行政区,并不是一个独立的“主体”去“玩”稳定币等相关事物。香港在...
7年4败IPO,菊乐股份转道北... 斑马消费 陈晓京7年间4次冲刺深交所折戟,四川乳制品企业菊乐股份,选择了一条相对稳妥的上市之路。继去...
IPO周报|本周1只新股申购,... 本周新股申购迎来覆铜板领域电子树脂供应商的本土高新技术企业。澎湃新闻根据Wind及公开信息梳理统计,...
海康威视遭暗算!加拿大‘国家安... 6月27日,加拿大以所谓“国家安全”为由命令海康威视加拿大有限公司停止在加运营并关闭其加拿大业务。海...
市场对美联储降息预期增强 美债... 本报记者 韩昱 近日,美债收益率曲线“陡峭化”趋势愈发明显。Wind数据显示,6月26日,各期限美债...
南方区域电力市场连续结算试运行...   在6月28日举行的南方区域电力市场连续结算试运行启动会上,南方电网公司宣布南方区域电力市场将正式...
十大券商看后市|A股仍有上升空... 上证指数向上突破3400点后,进入7月交易时间,A股行情将如何演绎呢?澎湃新闻搜集了10家券商的观点...
原价九十九元的挂饰被炒至两千六... 来源:法治日报原价九十九元的LABUBU挂饰被炒至两千六百元线上线下疯狂扫货的盲盒“黄牛”该如何治理...
转向芯片供应商多元化,Open... 来源:环球时报【环球时报综合报道】“谷歌或助力OpenAI降低对英伟达的依赖”《印度时报》28日以此...
飞马国际控制权变更在即 再推大... 证券时报记者 张一帆在控制权可能发生变化的背景下,6月29日,飞马国际(002210)宣布计划将《关...
国际能源署最新报告预计:全球石... 国际能源署最新发布国际石油市场中期展望报告指出,由于受地缘政治风险升级和贸易摩擦冲突加剧等因素影响,...
特朗普力保以总理,称美国每年花... 当地时间28日,美国总统特朗普再次要求以色列撤销对以总理内塔尼亚胡的审判,称其严重干扰以色列与哈马斯...
就欧盟制裁,克宫最新回应 克宫... 据俄罗斯卫星社6月29日报道,俄罗斯总统新闻秘书佩斯科夫表示,施压或武力不可能迫使俄罗斯坐上谈判桌,...
被召回充电宝问题指向电芯原料,... 近日,罗马仕、安克等充电宝品牌宣布召回旗下多款充电宝;多款充电宝品牌的3C认证证书被“暂停”;民航局...
健身房,也是心理疗愈房 健身房,不仅仅是挥洒汗水、塑造身材的场所,更是一处心灵疗愈的房间。在这里,人们抛开生活的烦恼和压力,...
盘前必读丨A股主板ST股票涨跌... 【财经日历】09:30 中国6月官方制造业PMI14:00 英国第一季度GDP年率当地时间上周五,美...
经纬早班车|Meta称没用未发...   【隔夜重磅】  国际清算银行称世界经济面临“关键时刻”  据路透社报道,国际清算银行在对世界经济...
江沐洋:国际金价震荡偏空 今日... 6月27日,周四,国际黄金价格维持稳定,收报3327.60美元/盎司,跌幅约0.13%,盘中早些时候...
成都先导重组折戟 海纳医药曲线... 筹划近3个月,成都先导重大资产重组事项宣告终止。6月29日晚间,成都先导发布公告称,经公司充分审慎研...
沪深北交易所释放多维度改革信号... 6月28日至29日,2025上市公司论坛在温州举行。论坛上,上海证券交易所、深圳证券交易所和北京证券...
“光伏第一股”跳闸了 光伏一送... 打不完的官司,还不完的债,谁来接盘亿晶光电这个烫手的山芋。文/每日资本论常州的梅雨季节又闷又热,但对...
QDII投资额度持续放宽,“港... 随着年内QDII(合格境内机构投资者)投资额度持续放宽,叠加港股市场结构性反弹,境内资金布局港股资产...
科达自控拟收购海图科技控股权,... 6月27日晚间,科达自控披露公告称,公司拟以现金受让海图科技2550万股股份,占海图科技股本总额的比...
机构看好A股,“稳中向好”态势... 外部风险缓和叠加稳增长政策持续发力,上周A股市场情绪显著回暖,上证指数创下今年以来新高。盘面上,新兴...