OpenKruisev0.5.0发布,支持无损流式批量发布策略Deployment/StatefulSet等控制器,但OpenKruise提供更多增强功能,如优雅就地升级、发布优先级/分散策略、多区工作负载抽象管理、统一sidecar容器注入管理等,都是经历了阿里巴巴超大规模应用场景磨练出来的核心能力。这些特性帮助我们应对更多样化的部署环境和需求,为集群维护者和应用开发者带来更灵活的部署和发布组合策略。目前,在阿里巴巴内部的云原生环境中,大部分应用统一使用OpenKruise的能力进行Pod部署和发布管理。不过,阿里云上的很多行业企业和客户也转而使用OpenKruise作为应用部署载体。背景问题在介绍OpenKruise的新能力之前,我们先了解一下原生K8s工作负载提供的发布能力:Deployment目前支持maxUnavailable和maxSurge;StatefulSet目前支持分区;DaemonSet等其他工作负载仅支持maxUnavailable。以上策略在测试环境或小场景下是可行的,但不能完全满足大规模应用场景。例如:第一,Deployment不支持灰度批量发布。你只想灰度升级20%的Pod做验证?抱歉,无法完成。用户只能设置较小的maxUnavailable,等待全部释放,或者释放出现问题紧急暂停;StatefulSet确实支持灰度分区,但目前只能对Pod逐个升级。如果副本总数是数百或数千,那么发布可能要等到天黑。v0.5.0新功能这里只介绍v0.5.0版本中CloneSet和SidecarSet的两个主要功能变化。感兴趣的同学可以在Githubchangelog上查看版本变更详情:https://github.com/openkruise/kruise/blob/master/CHANGELOG.md。CloneSet支持maxSurge策略。在阿里巴巴内部的云原生环境中,大部分无状态应用都是由CloneSet来管理的。为了满足超大规模应用的极端部署需求,我们支持:原地升级(发布前后Pod对象、IP、卷不变,只升级容器的镜像)减少副本DesignatePods删除了丰富的发布策略(Streaming、灰度批处理、优先级、拆分等),在今年2月份的Kruisev0.4.0版本中,我们推出了CloneSet开源。CloneSet自发布以来受到广泛关注,目前已有多家知名互联网公司在研究和使用。CloneSet初始版本不支持maxSurge(先扩后缩释放),只支持maxUnavailable、partition等策略。这对于阿里巴巴内部的大型应用来说不是问题,但是很多社区用户在平台上都有小规模的应用。如果配置不能配置为先扩后缩,在发布阶段可能会影响应用的可用性。在收到社区关于问题#250#260的反馈后,我们在CloneSet中添加了对maxSurge策略的支持,并在v0.5.0版本中提供了它。我们还要感谢fatiershiyan2016等社区成员的贡献和宝贵建议。至此,CloneSet已经涵盖了K8s原生工作负载的所有发布策略。下图构建了CloneSet目前提供的发布功能:这里不对CloneSet的发布策略进行详细的讲解,后面会有专门的文章介绍。我们就来看看新增的maxSurge是如何实现流式批量发布的?我们来看几个简单的例子:setmaxSurge+maxUnavailable+partitionPublish:apiVersion:apps.kruise.io/v1alpha1kind:CloneSet#...spec:replicas:5#Pod总数为5updateStrategy:maxSurge:20%#Expand5*20%=1Pod(roundup)maxUnavailable:0#Guaranteedreleaseprocess5-0=5Podavailablepartition:3#Keep3oldversionPods(onlyrelease5-3=2Pod)当release开始,CloneSet会根据maxSurge再扩展一个Pod。此时Pod总数为6(5个旧版本,1个新版本):$kubectlgetclonedemoNAMEDESIREDUPDATEDUPDATED_READYREADYTOTALAGEdemo5105617m随后,CloneSet会逐步删除并创建新的Pod在保证maxUnavailable直到满足partition=3的前提,即还剩下3个老版本的Pod。此时,因为已经达到了想要的最终状态,CloneSet会删除一个新版本的Pod。此时Pod总数为5(3个旧版本,2个新版本):$kubectlgetclonedemoNAMEDESIREDUPDATEDUPDATED_READYREADYTOTALAGEdemo5225517m这里,可以观察一段时间。当需要继续发布时,再次修改分区为0。然后,CloneSet会再次根据maxSurge扩容一个Pod。此时Pod总数为6(3个旧版本,3个新版本):$kubectlgetclonedemoNAMEDESIREDUPDATEDUPDATED_READYREADYTOTALAGEdemo5325617m之后,CloneSet会在保证maxUnavailable的前提下,逐渐删除并创建新的Pod,直到满足partition=0,即所有Pod升级到新版本。最后,CloneSet会删除一个新版本的Pod。此时Pod总数为5(5个新版本):$kubectlgetclonedemoNAMEDESIREDUPDATEDUPDATED_READYREADYTOTALAGEdemo5555517mmaxSurgewithin-placeupgrade:CloneSet提供Podoriginallocal的两种升级方式upgrade和reconstructionupgrade可以结合maxSurge/maxUnavailable/partition等策略发布。apiVersion:apps.kruise.io/v1alpha1kind:CloneSet#...spec:updateStrategy:type:InPlaceIfPossiblemaxSurge:20%如果原地升级方式配置了maxSurge,CloneSet会先扩容pods的maxSurge数量,然后updatetheoldversion原地升级Pod(updatetheimageimageinthePodspec),最后在满足partition的finalstate后清理删除maxSurge数量的Pod。这样既保证了发布过程的服务可用性,又尽可能保持Pod发布过程中的IP、volume等信息不变。SidecarSet支持体积注入和合并SidecarSet是Kruise提供的另一个重要功能。与管理业务Pod工作负载的CloneSet/StatefulSet不同,SidecarSet负责集群中sidecar容器版本和注入的统一管理。v0.5.0版本新增功能解决注入sidecar容器时SidecarSet与Pod中重复定义volume的冲突。这也是社区问题#254的反馈。他们使用SidecarSet来管理日志收集sidecar,并希望以旁路的方式注入到所有的Pod中。例如,我们需要在集群中的每个Pod中注入一个日志收集sidecar容器。但是首先,我们不能让每个应用开发者都在自己的CloneSet/Deployment中添加这个容器的定义,其次,即使在所有应用工作负载中都添加了,如果我们想升级这个日志收集容器的镜像版本,你必须更新所有应用程序的工作量,这样做的成本太高了!OpenKruise提供的SidcarSet就是为了解决上述问题。我们只需要将sidecar定义写入一个全局的SidcarSet即可。不管用户是通过CloneSet、Deployment、StatefulSet等任何方式进行部署,扩展后的Pod都会被注入到我们定义的sidecar容器中。以日志采集为例,我们可以先定义一个SidecarSet:apiVersion:apps.kruise.io/v1alpha1kind:SidecarSetmetadata:name:log-sidecarspec:selector:matchLabels:app-type:long-term#添加长期标签all将容器注入Pod:-name:log-collectorimage:xxx:latestvolumeMounts:-name:log-volumemountPath:/var/log#将log-volume的volume挂载到/var/log目录并收集在这个目录下logvolumes:-name:log-volume#定义一个名为log-volumeemptyDir:{}的volume:{}这里你可能会问,如果每个应用程序输出日志的目录路径不一样怎么办?别着急,这就是本卷合并的作用。比如此时有一个应用A扩展的原始Pod如下:apiVersion:v1kind:Podmetadata:labels:app-type:long-termspec:containers:-name:appimage:xxx:latestvolumeMounts:-name:log-volumemountPath:/app/logs#Applyyourownlogdirectoryvolumes:-name:log-volume#定义一个名为log-volumepersistentVolumeClaim的volume:claimName:pvc-xxx然后kruisewebhook会注入定义在中的logsidecar容器SidecarSet到Pod:apiVersion:v1kind:Podmetadata:labels:app-type:long-termspec:containers:-name:appimage:xxx:latestvolumeMounts:-name:log-volumemountPath:/app/logs#ApplyyourownlogsDirectory-name:log-collectorimage:xxx:latestvolumeMounts:-name:log-volumemountPath:/var/logvolumes:-name:log-volume#定义一个名为log-volumepersistentVolumeClaim:claimName:pvc-As的卷从xxx可以看出,因为SidecarSet和Pod中定义的logvolume的名字是log-volume,Pod中定义的volume以注射时为准。比如这里的Pod中的volume是使用pvc挂载pv,那么在注入sidecar之后,volume也会被挂载到sidecar容器中的/var/log目录下,然后就可以进行日志收集了。这样,sidecar容器以SidecarSet的形式进行管理,不仅与应用的部署和发布解耦,还可以与应用容器共享volume,实现日志收集、监控等sidecar相关功能。综上所述,本次v0.5.0版本升级主要带来应用无损发布、sidecar容器管理等更便捷的能力。未来,OpenKruise将继续在应用部署/发布能力上做进一步的优化。我们也欢迎更多同学加入OpenKruise社区,共同构建更丰富、更完善的K8s应用管理和交付扩展能力,可以面向更大规模、更复杂、更极致的性能场景。上云,看云栖号:更多云资讯、云案例、最佳实践、产品介绍,访问:https://yqh.aliyun.com/本文为阿里云原创内容,未必未经许可不得转载
