做者 | 徐迪、张晓宇mysql
导读:本文根据徐迪和张晓宇在 KubeCon NA 2019 大会分享整理。分享将会从如下几个方面进行切入:首先会简单介绍一下什么是 Sidecar 容器;其次,会分享几个阿里巴巴经济体的通用场景,以及他们是如何解决这些挑战的。git
Sidecar 容器并非一个新鲜事物。它是一种设计模式,主要用来作一些辅助的工做,好比网络连通性、下载拷贝文件之类的事情;若是你们熟悉 Docker Swarm 的话,就会发现 Docker Ambassador 其实就是 Sidecar。github
如上所示,Service Consumer 和 Redis Provider 强耦合,部署在同一个节点上。若是这个时候,Redis Provider 出现问题,须要链接到另一个 Redis 实例上,须要从新配置,并重启 Service Provider。sql
那么在引入了 Ambassador 之后,问题变得相对简单些,只须要重启这里的 Redis Ambassador 便可,并不须要 Service Consumer 进行任何变更。设计模式
固然这种模式,还能够进行跨节点通讯,好比下图。这样 Service Consumer 和 Redis Provider 就能够部署在不一样的节点上。在某种程度上,很容易地就将两种服务进行了解耦。网络
通常来说,Sidecar 容器能够:less
事实上,Sidecar 愈来愈被你们接受,而且使用愈来愈普遍。Sidecar 容器一般和业务容器(非 Sidecar 容器)部署在同一个 Pod 里,共享相同的生命周期,为业务容器提供辅助功能。这是一个很是好的模式,可以极大程度解耦应用,而且支持异构组件,下降技术壁垒。ide
但目前 Kubernetes 对 Sidecar 的管理还不完善,愈来愈不知足咱们的使用,尤为是在生产环境中使用 Sidecar。微服务
假设咱们在一个 Pod 内注入了多个 Sidecar,可是 Sidecar 之间或者 Sidecar 和业务容器之间有相互依赖关系。以下这个例子,咱们须要先启动 proxy Sidecar 容器用于创建网络链接,这样 mysql client 才能链接到远端的 mysql 集群,并在本地暴露服务。然后主的业务容器才能正常工做。ui
#1 proxy_container (sidecar) #2 mysql_client #3 svc_container
固然,有的人会以为这个地方,能够经过诸如更改镜像启动脚本延迟启动等方法来解决。可是这些方法侵入性太强,不利于扩展,还很难进行准确的配置。
咱们来看看另一个案例。Sidecar 容器和业务容器耦合在同一个 Pod 内,共享相同的生命周期。所以,单独来管控 Sidecar 容器很是不方,好比更新 Sidecar 的镜像。
好比,咱们已经给不少 Pod 注入了 Istio Proxy 这样的 Sidecar 容器,目前运行状态良好。可是若是这个时候咱们想升级这个 Proxy 镜像的话,该怎么办?
若是按照Istio 社区官方的文档,咱们须要从新注入这些 Sidecar 容器。具体来讲,须要删除原有 Pod,从新生成一份新的 Pod(有些 workload 关联的 Pod,会由相应的 workload 控制器自动生成)。
那若是咱们有不少个这样的 Pod 须要处理的话,怎么办?经过命令行的话,太不方便,并且容易出错。经过本身单独写的代码的话,可扩展性是个问题,须要频繁更改这些代码。
并且这里还有另一个问题,咱们确定不会一会儿升级全部的 Sidecar,确定要有个灰度的过程,也就是只升级一部分 Sidecar,这个时候又该怎么办呢?
这里咱们很是感谢 Joseph Irving (@Joseph-Irving) 提出了一个 Sidecar kep,经过定义 LifecycleType 来区分是不是 Sidecar 容器。
将来只须要在 Pod Spec 中,按以下方式标记便可:
name: sidecarContainer image: foo lifecycle: type: Sidecar
Pod 内容器的启动顺序按照:初始化容器->Sidecar 容器->业务容器 的顺序依次启动。
其中上述 kep 的 kubelet 端实现 正在进行中。
为了支持 Sidecar 更多的使用场景,咱们以此为基础提出了 PreSidecar 和 PostSidecar,分别用于在业务容器以前和以后启动。
具体的使用场景见 咱们的 PR。
为何咱们以为 Sidecar 应该区分前置和后置呢?
这是由于在一些场景下,咱们须要 Sidecar 容器优先于应用容器启动,帮助作一些准备工做。例如分发证书,建立共享卷,或者拷贝下载一些其余文件等。
而在另一些场景下,咱们须要一些 Sidecar 容器在应用容器以后启动。考虑到解耦和版本管理的因素,咱们将应用分为两部分,应用容器专一于业务自己,而一些数据和个性化的配置放在 Sidecar 容器中。一般状况下,这两个容器将会共享一个存储卷,后置的 Sidecar 容器会更新替换掉一些默认和过期数据。
固然考虑到将来更复杂的场景,咱们可能还会对容器的启动顺序作 DAG 编排,固然这个须要视生产实际须要而定。
为了解决 Sidecar 的管理工做,咱们须要一个更细粒度的 workload 方便咱们进行管理。这个 workload 咱们命名为 SidecarSet,目前已经开源,生产可用。你们能够访问 OpenKruise 这个项目,能够在项目的 roadmap 里了解咱们目前的一些新进展。OpenKruise 这个项目目前有三个生产可用的 workload,分别是 Advanced StatefulSet、BroadcastJob、SidecarSet。另外2个 workload(AdvancedHPA 和 PodHealer)正在加紧开发中, 很快会开源出来,敬请期待。相关使用 Demo,你们能够观看 Lachlan Evenson 的尝鲜视频。
spec 中的 SidecarContainer 的定义就是 Kubernetes 代码库中的 corev1.Container 定义。经过额外的一个 labelSelector,能够很方便地对指定的容器组进行操做。咱们支持滚动升级(RollingUpdate)的方式,让用户能够分批的升级 Sidecar,同时也提供了 pause 功能,能够在紧急状况下暂停 Sidecar 的升级。
若是只是简单升级 Sidecar 的镜像, SidecarSet 控制器仅仅会 patch 原有 pod 的,很是方便的就能够一键升级镜像。
咱们在生产实践过程当中,还发现了一些其余的挑战,目前还在寻找比较好的解法。
通常来说 Sidecar 容器占用的资源都比较小,那么这个资源要不要计算到整个 pod 当中?仍是能够直接共享业务容器的资源便可?相同的 Sidecar 在和不一样的应用容器搭配使用,如何准确给 Sidecar 容器分配资源这些都须要进行考虑。
通常来说,Sidecar 容器都是非主要容器,那么这类容器出现问题时,好比 liveness 探活,要不要对主容器的状态或者整个 pod 的状态也产生影响。再或者,Sidecar 镜像更新出现问题时,要不要直接标记整个 pod 出现问题。固然,还有一些其余的挑战,咱们只是列举了几个通用的。对于这些挑战,咱们须要你们一块儿集思广益,找到比较合理的解法。
随着 Sidecar 在生产环境使用愈来愈普遍,对其的管理愈发须要重视。Sidecar 虽然和业务容器部署在同一个 Pod 内,可是其本质上只是辅助性的容器。本文介绍了目前 Sidecar 的典型使用案例,以及面临的挑战,同时跟上游社区一块儿合做,将阿里经济体的技术解决方案在社区落地,帮助更多的用户.
做者简介:
徐迪 蚂蚁金服技术专家:负责蚂蚁金融云 PaaS 平台建设,Kubernetes 社区老兵,核心代码库贡献量社区前50;
张晓宇 阿里云技术专家:负责阿里巴巴云原生应用容器平台的生态建设,主要设计和研发节点稳定性和资源利用率相关解决方案,同时也是 Kubernetes 社区热心的成员和贡献者。
“阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,作最懂云原生开发者的技术圈。”