随着K8s和云原生技术的快速发展,以及各大厂商在自己的数据中心使用K8s的API进行容器化应用编排和管理,让应用交付本身变得越来越标准化和统一化,并且实现了与底层基础设施的完全解耦,为多集群和混合云提供了一个坚实技术基础。谈到多集群多云的数据中心基础架构,会想到为什么企业需要多集群?
集群上限5000个节点和15万个Pod。同时单集群的最大节点数不是一个确定值,其受到集群部署方式和业务使用集群资源的方式的影响。
避免被单家供应商锁定,不同集群的最新技术规划,或是出于成本等考虑,企业选择了多云架构。
正常情况下用户使用自己的 IDC 集群提供服务,当应对突发大流量时,迅速将应用扩容到云上集群共同提供服务,需具备公有云 IaaS接入,可以自动扩缩容计算节点,将公有云作为备用资源池。该模式一般针对无状态的服务,可以快速弹性扩展,主要针对使用 CPU、内存较为密集的服务,如搜索、查询、计算等类型的服务。
单集群无法应对网络故障或者数据中心故障导致的服务的不可用。通常主要服务的集群为一个,另一个集群周期性备份。或者一个集群主要负责读写,其他备份集群只读,在主集群所在的云出现问题时可以快速切换到备份集群。该模式可用于数据量较大的存储服务,如部署一个高可用的MySQL集群,一个集群负责读写,其他2个集群备份只读,可以自动切换主备。
数据是实时同步的,多集群都可以同时读写,这种模式通常针对极其重要的数据,如全局统一的用户账号信息等。
尽管国内互联网一直在提速,但是处于带宽成本的考量,同一调用链的服务网络距离越近越好。服务的主调和被调部署在同一个地域内能够有效减少带宽成本;并且分而治之的方式让应用服务本区域的业务,也能有效缓解应用服务的压力。
当前基于 K8s 多集群项目如下:
已经被社区废弃,主要原因在于 v1 的设计试图在 K8s 之上又构建一层 Federation API,直接屏蔽掉了已经取得广泛共识的 K8s API ,这与云原生社区的发展理念是相悖。
已经被社区废弃,提供了一个可以将任何 K8s API type 转换成有多集群概念的 federated type 的方法,以及一个对应的控制器以便推送这些 federated 对象 (Object)。而它并不像 V1 一样关心复杂的推送策略(V1 的 Federation Scheduler),只负责把这些 Object 分发到用户事先定义的集群去。这也就意味着 Federation v2 的主要设计目标,其实是向多集群推送 RBAC,policy 等集群配置信息。
参考Kubernetes Federation v2 核心实践,并融入了众多新技术,包括 Kubernetes 原生 API 支持、多层级高可用部署、多集群自动故障迁移、多集群应用自动伸缩、多集群服务发现等,并且提供原生 Kubernetes 平滑演进路径。
是一个兼具多集群管理和跨集群应用编排的开源云原生管控平台,解决了跨云、跨地域、跨可用区的集群管理问题。在项目规划阶段,就是面向未来混合云、分布式云和边缘计算等场景来设计的,支持海量集群的接入和管理、应用分发、流量治理等。
OCM 是一款 Kubernetes 多集群平台开源项目,它可以帮助你大大简化跨云/多云场景下的集群管理,无论这些集群是在云上托管,还是部署在自建数据中心,再或者是在边缘数据中心中。OCM 提供的基础模型可以帮助我们同时理解单集群内部的容量情况,也可以横跨多集群进行资源/工作负载的编排调度。与此同时,OCM 还提供了一系列强大的扩展性或者叫做插件框架(addon-framework)来帮助我们集成 CNCF 生态中的其他项目,这些扩展性也可以帮助我们无侵入地针对你的特定使用场景手工扩展特性。
以上多集群项目主要功能为资源分发和调度,还有如多云基础设施管理cluster-api,多集群检索Clusterpedia,多集群pod互通submariner,multicluster-ingress解决多集群的ingress,服务治理和流量调度 Service Mesh,如istio、cilium等网络组件实现的multi cluster mesh解决跨集群的mesh网络管理,以及结合存储相关项目实现跨集群存储管理和迁移等。
2.2.1 非联邦集群管理
非联邦多集群管理系统主要是进行资源管理、运维管理和用户管理,提供导入K8s集群权限功能,并通过统一 Web 界面进行查看和管理。这类工具不引入额外集群联邦的复杂,保持每个集群的独立性,同时通过统一的 Web 界面来查看多个集群的资源使用情况,支持通过 Web 界面创建 Deployment、Service 和负载均衡等,并且会集成持续集成、持续交付和监控告警等功能。由于集群联邦技术还在发展,大多数企业倾向于使用这种方式来运维和管理多集群 Kubernetes 环境。当前vivo主要是通过这种方式管理多集群。
2.2.2 联邦集群管理
联邦集群主要将资源联邦化,实现资源的统一管理和调度。随着K8s在数据中心大量使用,K8s已成为基础设施管理的标准,不同区域部署已非常普遍。如K8s运行在云上来托管集群、企业自建数据中心的私有云、边缘计算等。越来越多的企业投入到多集群管理项目,当然联邦集群肯定会增加整体架构的复杂度,集群之间的状态同步也会增加控制面的额外开销。尽管增加了所有的复杂性,但普遍存在的多集群拓扑引入了新的令人兴奋的潜力。这种潜力超越了目前所探索的通过多个集群进行的简单静态应用程序编排。事实上,多集群拓扑对于跨不同位置编排应用程序和统一对基础设施的访问非常有用。其中,这引入了一种令人兴奋的可能性,可以透明而快速地将应用程序从一个集群迁移到另一个集群。在处理集群灾难或关键基础设施干预、扩展或布局优化时,移动工作负载是可行的。
vivo在联邦集群的探索方向主要有以下四个方面:
本次主要分享资源分发和编排、弹性突发和多集群调度以K8s为核心的联邦多集群探索。网络为核心的能力建设,主要为不同集群的网络可以通过如 Service Mesh或者 Mesh Federation打通,就可以实现网络流量的灵活调度和故障转移。实际上,也有很多应用通过隧道或者专线打通多个集群,进一步保证了多集群之间网络通信的可靠性。vivo网络和服务发现主要是开源的基础上自研,可以持续关注后面分享。
云原生技术的发展是持续输出“事实标准的软件”,而这些事实标准中,应用的弹性、易用性和可移植性是其所解决的三大本质问题。
那么一个以应用为中心,围绕应用交付的多集群多集群管理具备统一的云原生应用标准定义和规范,通用的应用托管和分发中心,基于 Service Mesh 的跨云的应用治理能力,以及 K8s 原生的、面向多集群的应用交付和管理体系,将会持续不断的产生巨大的价值。vivo当前主要结合Karmada和CNCF周边项目来探索以上挑战。
3.1.1 应用发布
上图是面向应用的多集群持续发布架构,我们主要的工作如下:
图片
一个应用真正的能管理起来其实很复杂,如特定的场景需要原地升级和灰度发布等。为了可以提供更加灵活、高级和易用的应用发布能力,更好地满足应用发布的需求,最终选择使用Openkruise。比如上图有个游戏的应用game-2408。它涉及到K8s资源有configmap、secret、pv、pvc、service,openkruise的cloneset、自研的服务发现和访问资源、以及Karmada的PropagationPolicy和OverridePolicy等资源,都能达到12个资源配置。比如存储等资源都是按需申请和分配的,为了有效管理这些资源和关系,当前主要通过关联数据库进行管理,并打通cicd和容器平台的交互,记录应用发布的状态转换,实现应用的滚动、灰度等发布能力,达到可持续发布的能力。
为了方便问题定位、K8s资源和Karmada资源的策略关系,当前Karmada 策略命名规范如下:
遇到的问题总结:
3.1.2 Openkruise资源解析
当前vivo的应用主要通过OpenKruise的Cloneset(无状态)和AdvancedStatefulset(有状态)控制器进行发布。Kamrada目前只能识别K8s默认的资源,其它的资源都需要开发资源解析。为了解决上面提到的问题,Karmada 引入了 Resource Interpreter Webhook,通过干预从 ResourceTemplate-> ResourceBinding ->Work ->Resource 的这几个阶段来实现完整的自定义资源分发能力。
(1)InterpretReplica:
该 hook 点发生在从 ResourceTemplate 到 ResourceBinding 这个过程中,针对有 replica 功能的资源对象,比如类似 Deployment 的自定义资源,实现该接口来告诉 Karmada 对应资源的副本数。
(2)ReviseReplica:
该 hook 点发生在从 ResourceBinding 到 Work 这个过程中,针对有 replica 功能的资源对象,需要按照 Karmada 发送的 request 来修改对象的副本数。Karmada 会通过调度策略把每个集群需要的副本数计算好,你需要做的只是把最后计算好的值赋给你的 CR 对象。
(3)RetAIn:
该 hook 点发生在从 Work 到 Resource 这个过程中,针对 spec 内容会在 member 集群单独更新的情况,可以通过该 hook 告知 Karmada 保留某些字段的内容。
(4)AggregateStatus:
该 hook 点发生在从 ResourceBinding 到 ResourceTemplate 这个过程中,针对需要将 status 信息聚合到 Resource Template 的资源类型,可通过实现该接口来更新 Resource Template 的 status 信息。
3.2.1 弹性伸缩
跨集群HPA这里定义为FedHPA,使用了K8s原生的HPA,在Karmada控制平面通过FedHpaController实现跨集群的弹性调度扩缩容。
FedHPA流程:
3.2.2 定时伸缩
定时扩缩容是指应在固定时间点执行应用扩容来应对流量的高峰期。K8s本身没有这个概念,这里在Karmada控制平面定义了CronHpa资源,并通过Karmada-scheduler对多集群统一调度。避免非联邦化集群在多个member集群创建多个cronhpa。定时功能通过go-cron库实现。
CronHpa流程:
3.2.3 手动和指定扩缩容
手动扩缩容流程:
指定缩容,这里用到了openkruise能力。如训练模型需要将一批性能差的pod进行缩容。
指定缩容流程:
也可以尝试从Karmada控制平面指定删除pod和更改调度的结果,这样更加合理些,也不用添加Karmada资源解析。
3.3.1 多集群调度
Karmada多集群调度主要实现跨集群资源的合理分配和集群故障快速迁移业务。如上图所示主要通过Karmada scheudler和emulator配合实现,其中emulator主要负责每个集群的资源的估算。
workload调度流程:
故障调度:
3.3.2 重调度
重调度的存在主要解决应用下发到member集群没有真正的运行起来,导致出现这样的情况可能是集群资源在不断的变化,应用正在Karmada-scheduler多集群调度的时候可能满足,但经过member集群二次调度时候无法调度。
重调度流程:
3.3.3 单集群调度模拟器
目前社区单集群的调度估算器,只是简单模拟了4种调度算法。和实际的调度算法有很大差距,目前线上有很多自研的调度算法和不同集群需要配置不同算法,这样估算器的精确度就会下降,导致调度出现pod pending的情况。可以对单集群的调度模拟器进行优化。
3.4.1 应用迁移
对于通过非联邦化资源管理的应用,不能直接删除在创建,需要平滑迁移到Karmada管理,对于用户无感知。
主要流程如下:
3.4.2 应用回滚
有了应用迁移的能力,是否就可以保证整个流程百分百没有问题,其实是无法保证的。这就必须有应用回滚能力,提升用户的迁移满意度。
回滚的必要性总结:
回滚流程:
3.4.3 迁移策略
应用迁移Karmada原则:
vivo当前主要通过非联邦多集群管理,结合CICD实现了应用静态发布和管理,具备了应用的滚动、灰度、手动扩缩容、指定缩容和弹性扩缩容等能力。相对于非联邦多集群部分能力不足,如跨集群统一资源管理、调度和故障转移等,在联邦集群进行部分能力的探索和实践。同时联邦集群增加了整体架构的复杂度,集群之间的状态同步也会增加控制面的额外开销和风险。当前社区在联邦集群还处在一个探索和不断完善的阶段,企业在使用联邦集群应结合自身需求、建立完善的运维保障和监控体系。对于已经存在的非联邦化的资源需要建设迁移和回滚能力,控制发生故障的范围和快速恢复能力。