介绍

除了利用公共云提供基础设施服务外,Wayfair还运营大型数据中心。随着时间的推移,Wayfair基础设施团队选择在单个数据中心中引入多个逻辑区域,以简化网络维护,并将单个故障域分割为多个较小的故障域。

在本文中,我们的目标是展示过去几年从运行Kubernetes中获得的架构决策和经验教训。特别是,我们将详细介绍我们构建具有不同故障域的多区域Kubernetes集群的方法,包括我们在制定网络决策时对可靠性和可伸缩性的关注。

背景

我们部署Kubernetes的第一次尝试是基于一个简单的设计。在单区设计中,我们做了以下关键假设:

  • 所有的工作节点都在同一个第2层网络域中,允许我们在对网络架构进行最小更改的情况下操作。
  • 我们的CNI插件将是运河,“主机-gw”后端在法兰绒。这种设置避免了封装,因为网络数据包只是在节点之间路由。
  • 接入可以通过链接来实现MetalLB控制器和扬声器为服务提供外部iplayer2模式Nginx入口控制器提供Kubernetes进入资源支持。

单一区域设计的简单性支持了许多用例,并帮助我们快速起步。不过,我们有以下关切:

  • 所有进入的流量都由一个进入节点处理,这可能是一个瓶颈,如果它的网络接口饱和了,可能会导致问题。甚至拉克债券也有其局限性。
  • MetalLB Speaker故障转移将重置从外部网络到Kubernetes应用程序的所有已建立的连接。
  • 在出现重大网络中断的情况下,整个Kubernetes集群将受到影响。

这些问题促使我们探索和适应多区域模型。

分域Kubernetes架构

在多区域模型中,每个数据中心被划分为多个可用区域,每个区域都有自己独立的网络设备和电源。让我们快速看一下下面的网络图。

图1:多可用性区域网络拓扑。

每个可用性区域都是一个单独的第2层域。不幸的是,这意味着我们的带有“host-gw”法兰线的单一区域设置将不再有效,因为nexthop将只在同一区域内运行。来自不同可用性区域的节点从不同的网络地址获得ip,并且可以通过传输层路由。考虑到这些限制,我们有两个主要的选项来实现荚到荚的网络:封装(隧道)或者边界网关协议基于动态路由。

我们决定利用BGP的原因有很多,其中最重要的是:

  • 最小的性能影响:网络数据包只是在节点之间路由,这是第三层网络的基本功能。
  • 可伸缩性:BGP和路由在因特网的规模下工作。
  • 更简单更容易的故障排除:我们可以使用与调试任何其他网络问题相同的工具,比如“traceroute”和“tcpdump”。

边界网关协议的拓扑结构

下图说明了我们在多区域网络环境中的BGP拓扑。

图2:多可用性区域BGP拓扑。

在新的设计中,我们必须从“host-gw”后台的法兰绒切换到BGP后台的印花布,以支持多层2域和它们之间的动态路由。我们决定用一个边界网关协议是与每个节点相比,每个区域的BGP可伸缩性更好,简化了BGP的配置和管理。

BGP设置的关键组件是运行在Kubernetes主节点上的BGP路由反射器。我们在每个区域运行两个Kubernetes主节点,因此通过iBGP在同一个区域内使用两个Kubernetes主节点监视每个核心交换机。所有的Kubernetes节点也可以通过Calico使用iBGP来查看它们的本地主节点BGPPeer。使用路由反射器提供了更好的可伸缩性,简化了网络配置,并允许我们在Kubernetes主端完全自动化动态BGP配置(添加/删除Kubernetes工作节点)。

我们仍然使用一组专用的入口节点来服务所有外部流量。这些节点运行Nginx入口控制器提供Kubernetes进入资源支持。我们还继续使用MetalLB控制器,以实现应用程序从遗留集群到新集群的兼容性和无缝迁移。它负责为具有“LoadBalancer”类型的Kubernetes服务分配外部ip。

由于一些已知的问题在BGP模式下运行Calico和MetalLB,我们决定放弃MetalLB扬声器,使用Calico来宣布入口节点的外部ip。每个入口节点声明相同的/32前缀集,一个前缀为每个load均衡器服务的外部IP。通过这种方式,所有进入到每个IP的外部流量分布在所有可用区域的所有进入节点上,因为它们是通过等价多路径(又名ECMP)。

结论

基于BGP的新设计为我们提供了很好的服务。多亏了ECMP,我们可以水平伸缩进入层。此外,我们能够无缝地扩展节点占用空间,并优雅地处理单个AZ宕机。在接下来的文章中,我们将深入研究Calico和BGP/ECMP设计的配置。

确认

我要感谢所有为这个项目做出贡献的人:

  • Kubernetes团队负责设计、构建和运行全新的Kubernetes多区域集群。
  • 网络工程团队,在这个项目的设计和实施过程中提供了宝贵的帮助。