引子
随着云原生技术的普及,越来越多的企业使用Kubernetes来管理应用,并且集群规模也呈爆发式增长,企业也亟需应对随集群规模增长而带来的各种挑战。同时,为了更好地提供高可用、弹性伸缩的应用,企业也对容器混合云解决方案产生了极大的兴趣。
纵观容器混合云市场,主要的云服务提供商纷纷推出了自家的解决方案,例如华为云的MCP、Google的Anthos、Vmware的 Tanzu、IBM的 Cloud Pak、Red Hat的ACM for K8s等等。可以说,当前容器混合云市场纷繁嘈杂、百家争鸣,尽管各厂商不遗余力地鼓吹自家解决方案,但有个不争的事实是在容器混合云领域暂未出现领军产品。
混合云市场的乱象源于两点,一是各厂商均嗅到了商机,发现了这一广阔的蓝海市场,急于在这场竞争中抢占先机C位出道;二是开源界暂无统一的事实标准。根据历史规律,后者是解决这一乱象的关键所在,正像Kubernetes终结容器编排领域的纷争一模一样。
在开源领域,致力于混合云领域的项目数量与广阔的市场相比,显得极不相称。目前只有Rancher的Fleet、SAP公司力推的Gardener、以及Kubernetes社区的Kubefed。Fleet和Gardener要么缺乏创新,要么格局较低,难成大气,最有可能形成标准的便是被寄予厚望的、也是当前Kubernetes社区唯一的官方项目Kubefed。
K8s多集群历史
Kubernetes社区早在2015年便发布了集群联邦技术白皮书,并成立了“SIG-Federation”(后更名为SIG-Multicluster)特别兴趣小组致力于多集群领域的研究,该兴趣小组由华为领衔,同时也吸引了包括Google、Redhat在内的一线大厂。
SIG-Federation于2016年正式推出官方项目Federation,并在此基础上发展出了Kubefed项目,而且技术架构也发生了较大的变化,因此Federation项目常常被称为Federation V1,而Kubefed则被称为Federation V2。
Federation V1架构
第一代架构中,引入了Federated API Server,用于增加集群相关API,屏蔽集群差异,统一请求入口,同时提供一个Cluster Controller用于管理多个集群状态、集群级别对象创建,并且Service Controller用来实现跨集群服务发现。整体架构如下图所示:
V1架构兼容K8S原生API,从单集群到多集群演进可以变得很自然,但它也有几个不得不面对的缺陷。
• 集群信息嵌入原生API的Annotation中(如下图所示),会导致原生API体积膨胀而丑陋;
• 没有集群生命周期管理特有API,导致其生命周期管理能力无法扩展;
• 无法提供API对象版本控制,比如Deployment在K8S为GA,但在Federation中可能仍是Beta;
Federation V2架构
在第二代架构中,利用CRD来提供独立的API对象,新的API来封装K8S原生对象,同时也可以方便的对新增API提供版本管理。
整体架构如下图所示:
随架构升级,Federation项目也更名为Kubefed。在新的架构中,Kubefed提供两种配置类型:
• Type configuration(类型配置): 定义Kubefed接管的K8S的资源类型
• Cluster configuration(集群配置): 定义Kubefed接管的K8S集群
在类型配置中有三个关键的概念,用于控制资源向拖管集群分发策略:
• Templates(模版):定义一个原生的K8S资源类型;
• Placement(安置):定义资源将分发的集群;
• Overrides(修正):针对集群自由修正资源;
一个典型的Secret配置如下图所示:
apiVersion: types.kubefed.io/v1beta1 kind: FederatedSecret metadata: name: test-secret namespace: test-namespace spec: template: data: A: YWxhIG1hIGtvdGE= type: Opaque placement: clusters: - name: cluster2 - name: cluster1 overrides: - clusterName: cluster2 clusterOverrides: - path: /data value: A: null
上述配置中,通过template指定原生资源属性,通过placement指定资源将分发到cluster1 和 cluster2集群,最后overrides指示了分发到cluster2集群时,消除Secret的data信息。
K8s多集群现状
KubeFed的问题
Kubernetes社区当前已将Federation (v1)项目关闭,着重发展Kubefed,但该项目尚停留在beta阶段,社区开发几乎停滞,作为社区官方项目在该领域中的领导地位也在逐渐减弱。
Kubefed项目最大的问题是使用了非Kubernetes原生API来管理用户应用部署,用户必须先改造既有的工作流程才可迁移到Kubefed提供的API,这不仅抬高了使用门槛,而且Kubefed为每种资源类型均提供了CRD API,种类繁多的API也增加了用户的学习成本。某位社区致力于多集群管理的架构师坦言:“Kubefed项目强制用户使用非原生API,这个错误的决定很大程度上导致了它的发展不如预期。”
另外,多集群管理场景中,应用的多集群分发与监控应该是最基本的诉求,而Kubefed只完成了应用分发,对于应用的运行状态缺乏监管。用户使用Kubefed分发应用只能看到应用是否分发成功,对于应用运行状态,用户仍需要遍历集群分别获取。对用户使用造成了极大的不便。
K8s多集群管理标准化工作
当前Kubernetes社区针对Kubefed相关问题已经进行了多次讨论,目前多集群管理相关标准制定工作主要围绕在跨集群服务发现和工作负载配置管理,这两块也是实现多集群应用管理最基础的功能部分。
a.多集群Service API
在多集群应用背景下,用户已经习惯于将应用分发到多个集群,但对于Service应用而言,集群是个硬性障碍,运行于集群中的工作负载无法高效地访问其他集群中暴露的服务。多集群Service API旨在提供解决这个问题的标准,它主要包括:
1)定义一组API支持跨集群的Service服务发现和消费;
2)集群中应用跨集群访问Service行为与本集群一致;
该Service API提供ServiceExport对象表示单个集群中需要暴露到多集群的Service:
// ServiceExport declares that the associated service should be exported to // other clusters. type ServiceExport struct { metav1.TypeMeta `json:",inline"` // +optional metav1.ObjectMeta `json:"metadata,omitempty"` // +optional Status ServiceExportStatus `json:"status,omitempty"` }
每个需要暴露给其他集群的Service均对应一个ServiceExport对象。
此外,Service API还提供了ServiceImport对象,表示跨集群的Service定义:
// ServiceImport describes a service imported from clusters in a supercluster. type ServiceImport struct { metav1.TypeMeta `json:",inline"` // +optional metav1.ObjectMeta `json:"metadata,omitempty"` // +optional Spec ServiceImportSpec `json:"spec,omitempty"` // +optional Status ServiceImportStatus `json:"status,omitempty"` }
该Service API 提案已被社区接纳,该提案只定义了跨集群Service的声明方式,并没有对其实现细节进行约束,可以想见,将来会有多种具体的解决方案被提出。
b.多集群工作负载模型
关于联邦应用如何在多集群中分发,SIG-Multicluster也在进行尝试一种与现有Kubefed不同的处理思路。Kubefed当前从一系列FederatedXXX配置中剥离出Kubernetes原生应用分发到多集群,而新的尝试是提供一个通用的ManifestWork对象封装所有的应用,如下API设计:
// ManifestWork represents a manifests workload that hub wants to deploy on the managed cluster. // A manifest workload is defined as a set of kubernetes resources. // ManifestWork must be created in the cluster namespace on the hub, so that agent on the // corresponding managed cluster can access this resource and deploy on the managed // cluster. type ManifestWork struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` // Spec represents a desired configuration of work to be deployed on the managed cluster. Spec ManifestWorkSpec `json:"spec"` // Status represents the current status of work // +optional Status ManifestWorkStatus `json:"status,omitempty"` }
与Kubefed为每种应用类型均提供一个FederatedXXX 类型相比,这种新型的工作负载API则显得更加简单和通用。
未来展望
K8s多集群技术是容器混合云/多云解决方案的核心技术领域,涉及到资源、应用、数据、流量多个层面,以及统一配置、注册、可视化、自动弹性等多个功能领域。目前开源业界包括K8s社区的KubeFed项目、以及现有市面上的各种产品与解决方案都没有能够覆盖完整的多集群技术领域。
华为云MCP容器多云平台在K8s多集群技术领域属于较早也是实现较为全面的产品,而同时华为云作为KubeFed社区项目的发起者与领导者,将在未来致力于完善现有KubeFed的功能集,并且实现K8s多集群技术的标准化。下图描述了K8s多集群技术的全景,目前华为云已经在KubeFed自身以及周边关联的多个技术领域开展了相关工作。