深度剖析 PaaS 平台上的联邦集群

5月26日,时速云企业级容器  PaaS 技术沙龙第9期在深圳成功举办,时速云容器架构负责人魏魏就联邦集群社区现状、联邦集群亟待解决的问题等做出了细致的讲解。

以下是本次分享实录:

魏魏:根据现场的反馈,大家对联邦集群的认识可能还处在初级阶段,因此后面介绍的时候会先介绍一些概念,介绍概念的过程当中再逐步深入。

今天主要讲两点,第一个联邦集群在社区里面的现状是什么样的。主要分为两部分,第一个是联邦集群 V1,第一个版本,另外就是讲联邦集群 V2。V2 是联邦集群现在社区里面最新的进展,但是现在联邦集群V2的版本还处在早期的阶段。

另外要讲的一点就是联邦集群需要解决的问题,这里主要讲两个方面。第一全局性的负载均衡,第二跨集群的分布式存储。比如说,不同集群之间存储如何实现同步和复制,可能会有这种场景的需要。

联邦集群社区现状

为什么要做联邦集群?第一是要保证业务可以正常运营,要符合当地的法律法规,这就是业务的敏感性。第二,平台大都不希望被特定的厂商锁定,不希望所有的业务都布在  Kubernetes 之上。

Federation-V1

首先介绍一下 Federation-V1 相关的资源。上面图表里的资源是联邦集群支持的资源,也就是说这些资源是可以在联邦集群上创建出来的。除了这个列表以外的其它资源,你在联邦集群上是没有办法创建的,而这些资源和 Kubernetes 本身的资源是有差异性的。这是联邦 V1 版本里面现在面临最大的问题,你要想扩展相关的资源,你必须要自己扩建。

Federation-V2

FederationV2 相关的概念,第一个概念成员集群,不管是联邦集群 V1 版还是 V2 版,它都有成员集群的概念。第二个是 Template,Template 在 V1 里面是没有的。它更多是指资源的定义,而这种资源的定义在 V2 里面可以通过模板,定义所有资源,任何的资源都需要通过以模板的方式定义出来。并且这些资源之所以称之为模板关键性原因,就是模板里面有很大一部分参数是可以被替换掉的。

第三个概念是 Overrides,这个在联邦集群V1版里面也没有。这个东西更多强调的是我前面讲的两种场景,比如说 VPN 这种业务场景。我部署了一个 Pod,它分布在不同的集群上,如果我不希望这个业务部署某个地区,就可以通过 Overrides 覆盖掉原来的里面的业务,这就是它典型的使用场景。

然后是 Placement,它主要是用来决定哪些资源调度到哪些集群上,它更多是影响这些东西,但是 Placement 本身并不是调度过程,调度的过程最终是靠下面来完成的。

还有另外一个概念就是 Propagation,它和 Placement 不太一样,它是一个过程,一个机制。在不同的集群上,如何去真正的把这些资源创建出来。比如说你想创建出来一个  Pod,具体就是由它把资源在不同的集群上创建出来的。通过这种机制把资源创建出来之后,我要知道资源是创建成功还是失败了,可以根据这个状态做下一步的处理。

联邦集群里面 V2 和 V1 不太一样的点,V1 的资源大致了解之后,我们再看 V2 版,V2 资源主要分成两部分,一个是基本的联邦资源。另外一种是辅助性的联邦资源。我们先看基本的联邦资源。

联邦集群 V1 版里面,一个联邦集群里面就是一个,直接创建就可以了。但是在V2版里面,联邦集群的资源就变了,变成 Federation existing group、ResourceNames,我们通常定义一种联邦资源的时候,都会变成 Federation resource。任何一种联邦资源都是这样的。另外,任何一种联邦资源的结构都是 Template 和 Overrides。这是它定义资源两个关键性的东西。

刚才介绍的是联邦 V2 版本里的基本资源,再介绍一些辅助资源,主要有以下几种。一个是 Placement Preferences,这种主要是用来定义用户偏好,主要是用来影响调度的。用户希望某一个特定的业务调度到某一个特定的集群上,一般情况下是由系统管理员完成这件事情。

另外一个概念就是 Template Substitution Preferences,它主要用来影响模板替换过程当中的偏好和设置。另外一个概念,就是模板的 Template Substitution Outputs,这个就是经过模板替换出来的结果。这个对应到 K8S 里面,V1 版本里面各种资源。这些资源都会由  Outputs 作为输出,它又重新作为了 Propagation 输入,然后经过 Propagation 具体把这些资源创建出来以后,然后返回一个 Propagation Status。

既然讲联邦集群 V2,我们就要了解一下它的历史,它最早是 2017 年下半年的时候,工程师最早搞了一个称之为 “fnord” 的一个项目,这个项目整体的结构就是这样,它里面涉及一些东西,像已有的联邦集群的 API,还有联邦集群的注册列表,以及相关生成的联邦集群资源的一些类型。这些最早是这个项目相关的资源,以及资源相互之间的作用。

上面这张图里最关键的东西就是这个,Push Reconciler,这个就是一种协调器。它主要协调这些资源通过 Kube 的 AP I创建到不同集群上去,它现在还处在雏形阶段。

联邦集群的辅助资源的主要影响有两个,一个是调度,二是模板替换的过程。而用户的资源都是通过模板的方式创建,以模板的方式创建出来之后,通过 Kubernetes 或者是调度,由它决定这些工作负载去哪里。

但是因为它是一个模板,模板当中可能有 Overrides,也可能没有 Overrides。如果说有  Overrides 就需要经过替换的过程,它最终会把模板化资源替换成最终具体的资源。替换成的最终资源就被称之为 outputs。它出来的这些资源最终交给了 Propagation,Propagation 再对应不同的开发集群上创建这些资源。创建这些资源以后就会有一个返回,返回的称之为 Propagation status。Propagation status 会调度这一块相应的结果,再把调度的状态反映给最终的过程。

以上主要讲联邦集群 V2 他们资源之间的相互作用,以及工作原理。这些资源已经有了,但刚才讲的这个循环,事实上在社区里面还没有真正的运行起来,只是一个雏形。

联邦集群面临的一些问题

以上主要介绍了联邦集群相关的 V1 和 V2 社区里面现状和进展,接下来我们主要从两个方面介绍一下联邦集群面临的一些问题。

刚才介绍联邦集群的时候,大家也注意到,联邦主要解决了资源的创建和资源的调度两个方面的问题。我们第一段说联邦集群有很多的问题,这些问题都没有得到很好的解决,目前社区里也没有成熟的方案去解决这些跨集群相关的问题。

今天讲的点主要分两个,第一个是全局性的 LB(Load balancing)。这里的全局性的LB可能需要跨云,比如说我们这里的一个场景,你可以把你的工作负载分散在不同的云上。但是你的工作负载或者你的程序部署在云上之后,你怎么向你的最终用户提供服务呢?现在实际的情况是,比如说 AWS 这种,他们都没有跨云的负载能力。以 GCE 为例,因为它对   K8S 的亲和力相对高一些,但是它本身提供的东西也根本没有办法实现跨云的 LB。它只能实现你所有开发的集群都部署在我的 GCE 上。但如果你想实现某些开发集群部署在 AWS 上,某些部署在 GCE 上的,它根本就实现不了。

第二个问题是有了负载之后,如果让某一个 EBS 上的服务挂掉了,你怎么在他们云之间做迁移,跨云的迁移怎么做呢? EBS 挂了,我的业务需要迁移,但是业务迁移的过程中,我希望外部用户对这个最好是无感知的。如果是对业务的连续性要求比较高的业务场景,肯定不希望用户感知到。这个应该怎么做,跨云的迁移,在实际的使用场景下,也是很令人头疼的问题。

基于地理位置的全局负载均衡

全局性的负载均衡,首先要考虑清楚以下几个问题。

第一个问题是如何做全局性的服务发现,比如说我的负载均衡器上这些后端的业务一个是跨云的,第二是它服务的实例是动态的,有增加或者是减少,会有一个伸缩的过程。这个伸缩的过程,我 LB 如何去动态感知,如何去做跨集群的动态负载均衡。

另外一个问题,某一个云上的业务因为请求用户多和少,你可能需要对某些资源进行释放或者是对某些资源进行重新申请,当用户量大的时候,我需要申请一些高配的资源,用户量小的时候,我需要申请一些低配置的资源,需要释放一些资源,这种问题又如何通过跨云的 LB 实现呢?

前面介绍了很多各种各样的问题,比如说负载均衡,如何动态的负载均衡,伸缩的时候又怎么做。对于全局性负载均衡,现在社区里无外乎就是这几种做法。首先,你可以使用第三方厂商全局性的负载均衡器,比如你可以直接用谷歌的全局性负载均衡器,但前提是你全部的部署都在谷歌的 GCE 上。

第三种情况就是这种 Geo DNS,你可以借助 DNS 的方式来实现全局性的负载均衡,使用这种技术方案或者是这种思路去实现,当然你要考虑 DNS 本身的问题。DNS 本身会有缓存,如果你的服务出现故障之后,DNS 缓存的时间、故障的容错时间是否可以接受,业务场景是否可以接受,这些都是需要考虑的问题。

另外一种就是基于 CDN,现在社区里关于全局性负载均衡主要的思路就是这四种方式。你可以在技术方面做一些尝试,但是社区里目前没有比较好的推荐。现在真正能够把联邦集群用在生产环境的,应该是少之又少,或者是根本没有。哪怕谷歌本身,它也没有把联邦集群直接用于生产环境,在国内就更少,基本上都用联邦集群做开发环境和测试环境。

基于地理位置跨集群的存储复制

刚才在前面介绍了全局性的负载均衡,后面主要介绍一下存储问题,全局性的分布式存储。对于跨集群来说,不同集群之间,他们的工作负载都在 slave 上,它们之间是否会有数据同步呢。它们之间数据同步又应该怎么做,我们必须得有相应的分布式存储。比如说你的工作负载跑在 GCE 上,它可以直接跟 AWS 进行同步吗?显然是不行的,如果想要同步必须自己去做,必须要借助其它的办法和手段去做,因为谷歌本身并不做这种事情。谷歌更加希望你所有的业务都在我谷歌上,但是对于很多用户,都极力避免被厂商锁定,这就是他们的出发点。

上面这个图主要是以 ceph 为例。这张图里面主要介绍了在跨集群上如何去做这种 rbd mirroring,我这里的同步不是指跨机房,而是跨地域如何去做。比如说我某一个 ceph 集群部署在 AWS 上,另外一个集群部署在我们公司内部的 IDC 机房里,他们之间如何做这种同步。

当然 ceph 本身通过一些其它的技术手段可以支持 NFS、ISCSI 等等这些方式,这些方式其实也是可以通过底层下面的块或者是池的方式同步。

在跨集群上,假设已经解决分布式存储,是不是意味着任何业务都可以跨集群的部署了呢?显然不是,存储通常是和存储相关的业务场景是相联系的。可以是全局性分布式数据库,这些存储系统本身就具有数据全球化同步的能力。比如说它可以做全球性的部署,比如说在同一个集群里面某些节点是在纽约部署的,另外一些节点可能是在中国部署的,它可以跨地域。

但是有一些业务场景,就没有办法进行跨地域的部署。你想实现把它一个节点部署在香港,一个部署在北京,这是能接受的事情,因为延时实在太高了,延时无法把这两个或者三个节点组成一个集群。因为它们对延时或者是对数据同步的一致性要求特别高,但是上面的业务系统就可以做到。

所以通常部署这些存储性程序的时候,一般考虑的不是把他们做跨集群或者是跨机房的数据同步,而是把它放在同一个数据中心里面去,这样延时就会低很多。

前面介绍了很多联邦集群的好处,但联邦集群不是无所不能,联邦集群也有很多问题。联邦集群 V1 版从 1.9 之后,开始把联邦集群 V1 相关的代码从主仓库里独立出来了。独立出来以后,它能够独立的发展。但也带来一些问题,比如社区里面很多开发者在新仓库里的贡献相对来说没那么积极了。

第二个问题,前面介绍了很多联邦集群的功能,事实上有很多功能是处在不可用的状态,或者仅仅只有一个雏形,甚至连代码都没有,都是在等待社区开发人员积极的加入,做一些相应的开发。

另外一个问题,联邦集群 controlplane只有一个,一旦 controlplane 出了问题,整个联邦集群都会挂掉,它在架构设计上存在这种问题。

前面提到跨集群请求的访问,不管是跨集群的 LB,还是跨集群的数据同步,都要受到这样的限制,而在公有云上,最大的问题就是带宽的成本过高。

K8S中文社区微信公众号