作者:Thomas Rampelberg
最近,Linkerd社区一直在花时间处理多集群Kubernetes的挑战。如何在多个Kubernetes集群之间应用Linkerd的零配置自动mTLS或流量分割等特性?服务网格应该做什么,而更重要的是:服务网格不应该做什么?
与任何优秀的工程项目一样,开始的最佳方式是明确需求。在这篇博客文章中,我们概述了多集群解决方案的最低要求,从而使跨集群的流量更加可靠、安全和可观察。在后续的博客文章中,我们将讨论一些实现选项。
多集群从何而来?
Kubernetes集群就像品客薯片——你不可能只有一个!事实上,像Zalando这样的组织大约有100个。通过运行多个集群,可以将每个集群的关注点分开。不必解决每个应用程序和解决方案的约束,而是缩小问题空间。这最终成为一个非常好的工具,允许以更灵活、更简单的方式构建解决方案。
不幸的是,每个新的集群都增加了系统的复杂性。还有更多的内容需要管理、更新,并且需要处理集群上运行的所有应用程序之间的连接。Linkerd能帮我们吗?为了理解这个解决方案,我们首先列出一组需求。
需求一:支持层次网络
Kubernetes是一个有趣的野兽。每个pod拥有一个IP地址的含义之一是,默认情况下每个集群最终都是自己的网络。覆盖网络(Overlay network)只能在集群内部路由和发现。可以使用Submariner或Project Calico之类的工具来解决这个问题。如果你对维护一个平面网络有严格的要求,并且每个pod与其他集群中的pod直接通信,那么这些解决方案非常棒。然而,它们引入了新的失败点,增加了需要管理的复杂性。
为了降低复杂性并且不需要其他工具,任何多集群实现都必须使用Kubernetes的当前状态。如果我们不能依赖平面网络,这就意味着需要某种网关来管理进入集群的流量,并将流量路由到正确的后端服务。
需求二:保持独立状态
在一个每个集群中的每个pod之间都有一个完全平坦的、可路由的网络的世界中,允许直接通信仍然是没有意义的。为了让每个pod直接与另一个pod对话,它需要以某种方式发现那个遥远的pod。这在每个集群之间引入了全局状态的需求。每个集群的故障区现在已经一起粉碎了!让我们在这里描述一个失败场景,以理解为什么会发生这种情况以及它可能意味着什么。
Kubernetes中pod之间的通信由服务(Service)资源管理。默认情况下,该资源创建一个虚拟IP地址:ClusterIP。当pod决定要与另一个服务通信时,DNS将返回该服务的集群IP。当pod尝试连接到集群IP时,本地节点上的iptables被配置为随机选择目标pod IP地址。kube-proxy负责在集群中的每个节点上配置iptables,并在服务更改、pod启动或停止时执行此任务。这些更改发生在每个节点上,而且由于iptables实现细节,开销非常高。
通过要求全局可见性,某些集群中的状态更改将影响所有集群。这将潜在的不同的集群移动到相同的故障区,并立即降低最大可能的规模。每个集群不再能够独立伸缩,而是由每个集群的大小定义最大伸缩。一个集群中的任何错误配置,例如启动大量的pod,都能够DoS其他集群。这似乎与多个集群应该做的事情正好相反!
保持状态独立并通过复制管理更新,允许实现对更新进行筛选,以精确地获得所需的数据。本地集群外部的问题将被隔离,并确保单独的组件不能相互替换。
需求三:有独立的控制平面
引入一个共享的控制平面是很诱人的。这有效地集中了状态,减少了不同组件的管理开销,并具有做出全局优化决策的潜力。除了与全局复制状态共享许多相同的参数之外,这还会带来其他一些负面影响。
对于初学者来说,连接问题是真实存在的。当集群位于网络的两端时,中间的任何问题都可能导致失败。这些问题可以表现为任何情况,从延迟的增加一直到连接的完全丧失。在完全丧失连接性的情况下,任何不能与中央控制平面通信的集群要么完全中断,要么开始出现奇怪的错误,因为状态不同于本地缓存和共享控制平面。再一次,潜在的分离故障区已经被合并,当最薄弱环节出现问题时,整个系统就会失效。
即使在网络故障从未发生的完美世界中,共享控制平面也会引入一个关键的缺点。随着集群被配置到离共享控制平面更远的地方,诸如发现更新或策略检查之类的操作就会变慢。这只是因为进程之间的延迟将会增加,并且任何需要与中央集群通信的操作将会变得越来越慢。
将控制平面(以及相关的数据平面)保持独立为每个集群提供了自由。这种自由让集群操作员以最适合他们的方式管理版本、连接和功能。松散耦合使系统具有更强的弹性,实际上降低了所需的总体复杂性。
迈向解决工程
有了这三个约束——支持层次网络、保持独立状态和拥有独立的控制平面——我们就有了实现一个解决方案所必需的约束,采用Linkerd使用的低复杂度模型并将其扩展到多个集群。
在之后的文章中,我们将概述我们已经找到的解决方案。同时,我们希望听到你对这组需求的反馈!请对需求文档进行评论,或者进入我们的Slack渠道,提出一些问题!
https://docs.google.com/document/d/1uzD90l1BAX06za_yie8VroGcoCB8F2wCzN0SUeA3ucw
https://slack.linkerd.io
Linkerd是一个社区项目,由CNCF托管。如果你有功能需求、问题或评论,我们欢迎你加入我们快速成长的社区!Linkerd代码由GitHub托管,我们在Slack、Twitter和邮件列表上有一个蓬勃发展的社区。快来加入我们的行列吧!