Published at 2020-11-13 | Last Update 2020-11-13
本文其实是前一篇文章 迈入 Cilium+BGP 的云原生网络时代 的铺垫,二者合起来,是近期在公司所做的一次技术分享的内容。 抛砖引玉,希望可以引起大家一些思考。
过去二十多年网络发生了很多的变化,比如,
Fig 1-1. Various network solutions over the past years
具体到一些我们所熟悉的计算平台,
那么,我们的一个问题是,为什么会有这么多网络方案呢? 或者说,网络架构和解决 方案为什么在不断演进呢?这其中当然有很多方面的原因,我们今天尝试从 不断增长的计算规模 来分析一下这个问题。
Fig 1-2. The ever-increasing compute endpoints' scale
这里的计算资源基本单位可以是一台 BM、VM,也可以是容器。相应的对应三个时代:
Fig 2-1. Logical BM cluster topology and traffic patterns
如图所示,BM 时期计算平台的特点有:
这种计算模型给网络提出的需求也很简单:
首先,能够比较高效地处理南北向流量;
第二,集群内应用之间的互访(东西向流量),也就是节点间的网络连通性,这与本文 讨论的主题(计算实例规模)密切相关;
第三,在连通性的基础上,要有必要的访问控制和安全措施。例如可以基于硬件防火墙做网 段级别的控制、基于 iptables 做一些简单的主机防火墙功能等等。这些内容不在本文 讨论范围。
针对以上需求,业界设计了经典的接入、汇聚、核心三级网络架构,如下图所示:
Fig 2-2. Typical network solution for BM platforms
在这种模型中,由于节点/应用之间通信都可能要经过核心,因此核心交换机需要记录所 有节点的 IP 和 MAC 地址信息。
在这种网络方案中,与计算节点规模相关的瓶颈最可能出现在核心交换机,因为要实现 任何两台之间节点之间可达,核心交换机需要占用硬件表项(FIB TCAM)来记录集群内所有 主机的 IP/MAC 信息。
Fig 2-3. Bottleneck analysis
我们来算一下。假设,
那可以算出整个机房有 2000 台服务器。假设每个 node 占用一到两个 IP 地址,核心交 换机将占用 2k~4k 条表项。
假设使用的核心交换机有 16K 条表项,其中能用到 70% 左右(太高会导致哈希冲突, 包只能交由交换机 CPU 软件处理,导致 CPU 升高、丢包甚至宕机),因此有效表项 是 11K 条。
2K~4K
与 11K
相比可以得出结论:转发表项非常充裕,核心交换机没有表项瓶颈。
2008 年以后,业界开始对计算资源做大规模虚拟化,我们来到了云计算时代。
Fig 3-1. Logical VM cluster topology and traffic patterns
这一时期的特点:
代表性的计算平台有:
这时对网络的需求:
首先肯定虚拟机之间的网络连通性,需要考虑的问题包括,
第二,虚拟机的 IP 和 MAC 地址要在虚拟机的生命周期内保持不变,这一点特别重要。本 质上来说这是由 IAAS 计算模型决定的:在 IAAS 模型中,交付给用户的是一台一台的 虚拟机资源,因此用户看到的就是 虚拟机这一层抽象,而 IP 和 MAC 是虚拟机的资源 属性,底层虚拟机迁移要做到用户无感知,因此 IP/MAC 地址不能变。
此外还有硬多租户(hard multi-tenancy)和安全,这两点也非常重要,但跟本文要讨论的 关系不大,因此这里也不展开。
Fig 3-2. Typical network solution for VM platforms
针对以上需求,典型的解决方案是所谓的大二层网络,如上图所示:
首先,在每个宿主机内运行一个虚拟交换机(vswitch),虚拟交换机向上连接到物理交换 机,向下连接到每个虚拟机。因此网络的边界从原来的接入交换机(顶置交换机)这一层, 下沉到宿主机内部,我们开始有了网络虚拟化(network virtualization)。 这样整张网络成为一个大二层网络。
这里大二层的意思是,同网段的虚拟机,不管它们是否在同一台宿主机上,彼此都能 够通过二层(MAC)访问到对方。即,逻辑上它们位于同一个二层网络(二层域)。
和这种模型对应的是一个全局的(或中心式的)负责 IP 地址分配和管理的服务(IPAM)。
大二层网络可以基于数据中心网络实现,也可以在宿主机内用虚拟网络实现,例如 VxLAN 隧道,如果需要动态下发配置,还可以引入 SDN。
如果是基于数据中心网络的大二层,那核心交换机此时不仅需要记录宿主机的 IP/MAC 信息 ,还需要记录所有虚拟机的 IP/MAC 信息,这样才能支持虚拟机全网可迁移。OpenStack 的 provider network 模型就是这样的设计,如下图所示:
Fig 3-3. OpenStack provider network model
OpenStack 网络方案中有如下几个组件:
Provider 模型中,网关配置在数据中心网络设备(例如核心交换机)上,所有跨网段的 包要经过核心交换机转发。图中从 1 到 18 的数字连起来,就是跨网段的两个虚拟机之间的转发路径。
Fig 3-4. Bottleneck analysis
我们来算一下此时核心交换机的表项规模。假如这时我们机房更大了一些,
那可以算出总共有 30k
虚拟机,需要占用核心交换机 ~30K
表项。
如果使用的是主流交换机,核心有 64K
表项,乘以 70% 是 44K
,也就是能支撑 4 万
左右实例,大于 ~30K
,因此能满足需求。
所以我们得出结论,大二层方案是适合 VM 或 IAAS 模型的。
2016 年开始,我们进入了大规模容器时代。容器也被称为轻量级虚拟机,所以它的很多 网络需求与虚拟机类似,但部署密度高了一个数量级。典型的容器平台:
如果还是用前面的大二层模型,只是将虚拟机换成容器,如下图所示:
Fig 4-1. If still using large L2 network
如果没有一些很特殊的业务需求,只是单纯基于已有大二层网络实现这样一套容器方案,其 技术难度和开发量都不是很大,例如,如果要将 Kubernetes 接入OpenStack Neutron 网络 ,开发一个针对 Neutron+OVS 的 CNI 插件就可以了 [1]。
但前面提到,这种 global IPAM + central gateway 方案中,核心交换机需要记录 每个实例的 IP/MAC 信息,再考虑到容器的部署密度,可以预见的是,交换机硬件表项将 撑不住。我们来具体算一下。
假设还是 2/3 节点做虚拟化,平均每台 node 部署 75 个容器,那总容器将达到 150K
,
远远超过了核心的表项规模。所以这种物理的大二层网络是无法支撑容器规模的。
除了硬件交换机表项这个瓶颈,在软件上,其实 global IPAM 也已经无法在性能上满足容 器频繁的漂移、创建、销毁的需求了。所以大二层方案在软件和硬件上都已经陷入了困境。
因此,网络在容器时代必须做出变化了。
刚才提到的 64K 表项交换机其实在今天还不算过时,那如何在这张物理网络上支撑 15万、 20 万甚至 30 万以上容器呢(刚才的计算中,还有 1/3 的节点没有做虚拟化,而且容器部 署密度可以进一步提高)?
显然,最重要的一点就是不能让核心交换机记录所有的容器的 IP 信息。怎么做到这一 点呢?
Fig 4-2. If still using large L2 network
比较主流的方式是,
采用这样的设计之后,
前面看到,只要对网络方案做出一些变化,就可以避免交换机的硬件瓶颈和 IPAM 的软件瓶 颈。
现在我们来重新审视一下容器的特点,以便从需求的角度来讨论什么样的方案才是最适合容 器平台的。
Fig 4-3. Container platform vs. VM paltform
容器编排平台,例如 Kubernetes,跟 OpenStack 这样的虚拟机编排平台相比,最大的不 同之一就是抽象的层次更高。
这带来的一个重要变化就是:客户端不再关心服务的具体实例数量,以及每个实例的 IP/MAC 等信息。因此实例的 IP/MAC 地址没有那么重要了,例如 Kubernetes 里大部 分类型的 Pod 在重新发布之后 IP 都会变化。
此时,容器的核心网络需求:
综合以上需求,合理的容器网络解决方案就是:
如下图所示,
Fig 4-4. Typical network solution for container platforms
那么,和这种模型对应的容器网络方案有:
Spine-Leaf 架构
实际上数据中心网络拓扑近些年也有一个变化,从原来的接入-汇聚-核心三级架构变成了现 在的 Spine-Leaf 量级架构,如下图所示:
Fig 4-5. Typical network solution for container platforms, with Spine-Leaf
Spine 层和 Leaf 层组成一个全连接网络,换句话说,任何一个 Leaf 都连接到了任何一个 Spine。这种架构的好处:
Spine-Leaf 拓扑下,容器的网络方案是类似的,还是基于小二层加 local IPAM,只是 BGP 建连会稍有不同 [2]。
这里稍微就 Cilium 网络展开一些讨论,这是最近一两年流行起来的网络方案。
Fig 4-6. Cilium powered Kubernetes cluster [5]
Cilium 的组件如上图所示,主要包括,
Cilium 的核心基于 eBPF,这是 4.8 内核 引入的一项革命性技术:它使得内核变得可编程 。这里可编程的意思是,以前要改变内核行为,需要修改内核代码、编译调试、重新打镜像、 安装运行等等,而且还要维护自己的内核分支,现在可能写几行 eBPF 代码然后动态加载到 内核就能实现同样的效果。
eBPF 目前主要用在两个方向:动态跟踪(tracing) 和网络(networking)。
有了 eBPF/XDP 之后,我们可以看到数据平面处理(dataplane processing)有一个趋势:
Cilium 是基于 eBPF 实现的一个网络方案,主打高性能和安全。 对内核要求较高,但也不是非常高,根据我们的使用经验,
更多关于 Cilium+BGP 的实践,可以参考我们之前的文章 [2,3]。
网络方案的演进是一个复杂的过程,涉及到很多因素,本文尝试从计算规模的角度对这一问 题进行了分析。从中可以看出,每种网络方案或网络模型都不是凭空出现的,它们本质上都 是业务需求在网络层的反映;而所有业务需求中,最重要的可能就是规模。
如果对我们团队感兴趣,可以关注我们的技术博客 https://ctripcloud.github.io 。