写点什么

OpenKruise :SidecarSet 助力 Mesh 容器热升级

用户头像
极客good
关注
发布于: 刚刚

SidecarSet 是 Kruise 提供的独立管理 Sidecar 容器的 workload。用户通过 SidecarSet 能够便利的完成对 Sidecar 容器的自动注入独立升级,详情请参考:OpenKruise 官网


?


默认情况下,Sidecar 的独立升级顺序是先停止旧版本的容器,然后再创建新版本的容器。这种方式尤其适合不影响 Pod 服务可用性的 Sidecar 容器,例如日志收集 agent ,但是对于很多代理或运行时的 Sidecar 容器,如 Istio Envoy,这种升级方法就有问题了。Envoy 作为 Pod 中的一个 Proxy 容器代理了所有的流量,这种场景下如果直接重启升级,Pod 服务的可用性必然会受到影响,因此需要考虑应用自身的发布和容量情况,无法完全独立于应用做 Sidecar 的发布。


?



阿里巴巴集团内部拥有上万的 Pod 都是基于 Service Mesh 来实现相互间的通信,由于 Mesh 容器升级会导致业务 Pod 的不可用,因而 Mesh 容器的升级将会极大阻碍 Service Mesh 的迭代。针对这种场景,我们同集团内部的 Service Mesh 团队一起合作实现了 Mesh 容器的热升级能力。本文将重点介绍在实现 mesh 容器热升级能力的过程中 SidecarSet 是扮演了怎样的重要角色。


?


SidecarSet 助力 Mesh 容器无损热升级


===============================================================================================


?


Mesh 容器不能像日志采集类容器直接原地升级,其原因在于:**Mesh 容器必须要不间断地对外提供服务,而独立升级方式会导致 Mesh 服务存在一段不可用时间。**虽然社区中已有一些知名的 Mesh 服务如 Envoy 、Mosn 等默认能够提供平滑升级的能力,但是这些升级方式无法与云原生进行恰当地结合,且 kubernetes 本身也缺乏对此类 Sidecar 容器的升级方案。


?


OpenKruise SidecarSet 为此类 Mesh 容器提供了 Sidecar 热升级机制,能够通过云原生的方式助力 Mesh 容器实现无损热升级。


apiVersion: apps.kruise.io/v1alpha1


kind: SidecarSet


metadata:


name: hotupgrade-sidecarset


spec:


selector:


matchLabels:


app: hotupgrade


containers:


  • name: sidecar


image: openkruise/hotupgrade-sample:sidecarv1


imagePullPolicy: Always


lifecycle:


postStart:


exec:


command:


  • /bin/sh

  • /migrate.sh


upgradeStrategy:


upgradeType: HotUpgrade


hotUpgradeEmptyImage: openkruise/hotupgrade-sample:empty


  • **upgradeType **: HotUpgrade 代表该 sidecar 容器的类型是 Hot upgrade ,即热升级方案。

  • **HotUpgradeEmptyImage **: 当热升级 Sidecar 容器时,业务须要提供一个 empty 容器用于热升级过程中的容器切换。Empty 容器同 Sidecar 容器具有相同的配置(镜像地址除外),例如 command , lifecycle , probe 等。


?


SidecarSet 热升级机制主要包含注入热升级 Sidecar 容器和 Mesh 容器平滑升级两个过程。


?


注入热升级 Sidecar 容器




?


针对热升级类型的 Sidecar 容器,在 Pod 创建时 SidecarSet Webhook 将会注入两个容器:


?


  • {Sidecar.name} -1: 如下图所示 envoy -1,这个容器代表正在实际工作的 sidecar 容器,例如:envoy :1.16.0


?


  • {Sidecar.name} -2: 如下图所示 envoy-2,这个容器是业务提供的 HotUpgradeEmptyImage 容器,例如:empty :1.0


?![2-2.png](https://img-blog.csdnimg.cn/img_convert/b779


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


821939edcc989120a984f7150608.png)


上述 Empty 容器在 Mesh 容器运行过程中,并没有做任何实际的工作。


?


Mesh 容器平滑升级




?


热升级流程主要分为一下三个步骤:


?


  1. Upgrade: 将 Empty 容器替换为最新版本的 Sidecar 容器,例如:envoy-2.Image = envoy:1.17.0

  2. Migration : 执行 Sidecar 容器的 PostStartHook 脚本,完成 mesh 服务的平滑升级

  3. Reset: Mesh 服务平滑升级后,将老版本 Sidecar 容器替换为 Empty 容器,例如:envoy-1.Image = empty : 1.0


仅需上述三个步骤即可完成热升级中的全部流程,若对 Pod 执行多次热升级,则重复执行上述三个步骤即可。


?



?


Migration 核心逻辑




SidecarSet 热升级机制不仅完成了 Mesh 容器的切换,并且提供了新老版本的协调机制( PostStartHook ),但是至此还只是万里长征的第一步,Mesh 容器同时还需要提供 PostSartHook 脚本来完成 Mesh 服务自身的平滑升级(上述 Migration 过程),如:Envoy 热重启、Mosn 无损重启。


?


Mesh 容器一般都是通过监听固定端口来对外提供服务,此类 Mesh 容器的 migration 过程可以概括为:通过 UDS 传递 ListenFD 和停止 Accpet 、开始排水。针对不支持热重启的 Mesh 容器可以参考此过程完成改造,逻辑图如下:


?



热升级 Migration Demo




?


不同 Mesh 容器对外提供的服务以及内部实现逻辑各有差异,进而具体的 Migration 也有所不同,上述逻辑只是对其中一些要点做了一些总结,希望能对有需要的各位有所裨益,同时在 Github 上面我们也提供了一个热升级 Migration Demo 以供参考,下面将对其中的一些关键代码进行介绍。


?


1. 协商机制


?


Mesh 容器启动逻辑首先就需要判断第一次启动还是热升级平滑迁移过程,为了减少 Mesh 容器沟通成本,Kruise 在两个 sidecar 容器中注入了两个环境变量 **SIDECARSET_VERSION 和 SIDECARSET_VERSION_ALT ,**通过判断两个环境变量的值来判断是否是热升级过程以及当前 sidecar 容器是新版本还是老版本。


?


// return two parameters:


// 1. (bool) indicates whether it is hot upgrade process


// 2. (bool ) when isHotUpgrading=true, the current sidecar is newer or older


func isHotUpgradeProcess() (bool, bool) {


// 当前 sidecar 容器的版本


version := os.Getenv("SIDECARSET_VERSION")


// 对端 sidecar 容器的版本


versionAlt := os.Getenv("SIDECARSET_VERSION_ALT")


// 当对端 sidecar 容器 version 是"0"时,表明当前没有在热升级过程


if versionAlt == "0" {


return false, false


}


// 在热升级过程中


versionInt, _ := strconv.Atoi(version)


versionAltInt, _ := strconv.Atoi(versionAlt)

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
OpenKruise :SidecarSet 助力 Mesh 容器热升级