本文已发表一年以上。较旧的文章可能包含过时内容。请检查页面中的信息自发布以来是否已不再准确。
Kubernetes 集群中的高性能网络策略
网络策略
自 Kubernetes 1.3 版本于 7 月发布以来,用户已经能够在集群中定义和强制执行网络策略。这些策略是防火墙规则,用于指定 Pod 之间、Pod 到外部以及外部到 Pod 的允许流量类型。如果请求,Kubernetes 会阻止所有未明确允许的流量。策略应用于通过共同标签标识的 Pod 组。标签可用于模拟传统的分段网络,通常用于隔离多层应用中的不同层:例如,您可以使用特定的“segment”标签标识前端和后端 Pod。策略控制这些分段之间的流量,甚至控制与外部源之间的流量。
流量分段
这对应用开发者意味着什么?终于,Kubernetes 获得了提供“纵深防御”所需的能力。流量可以进行分段,应用的不同部分可以独立地进行安全加固。例如,您可以通过特定的网络策略非常容易地保护您的每个服务:通过特定复制控制器标识的所有 Pod 都已经被特定标签标识。因此,您可以使用相同的标签将策略应用于这些 Pod。
纵深防御长期以来一直被推荐为最佳实践。这种应用不同部分或层之间的隔离在 AWS 和 OpenStack 上很容易通过将安全组应用于虚拟机实现。
然而,在网络策略出现之前,这种容器隔离是不可能的。VXLAN 叠加网络可以提供简单的网络隔离,但应用开发者需要对访问 Pod 的流量进行更精细的控制。正如您在这个简单的示例中看到的,Kubernetes 网络策略可以根据源和目的地、协议和端口管理流量。
apiVersion: extensions/v1beta1
kind: NetworkPolicy
metadata:
name: pol1
spec:
podSelector:
matchLabels:
role: backend
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: tcp
port: 80
并非所有网络后端都支持策略
网络策略是一个令人兴奋的功能,Kubernetes 社区为此付出了很长时间的努力。然而,它需要一个能够应用这些策略的网络后端。就其本身而言,简单的路由网络或常用的 flannel 网络驱动程序等,例如,无法应用网络策略。
目前只有少数几个支持策略的 Kubernetes 网络后端:Romana、Calico 和 Canal;Weave 表示将在不久的将来提供支持。Red Hat 的 OpenShift 也包含了网络策略功能。
我们选择 Romana 作为这些测试的后端,因为它将 Pod 配置为使用具有原生路由能力的 IP 地址,采用完整的 L3 配置。因此,网络策略可以直接由主机使用 Linux 内核中的 iptables 规则应用。这使得网络具有高性能且易于管理。
测试网络策略的性能影响
应用网络策略后,需要对照这些策略检查网络数据包,以验证这种流量是否被允许。但是,对每个数据包应用网络策略会有多大的性能损失?我们能否使用所有强大的策略功能而不影响应用性能?我们决定通过运行一些测试来找出答案。
在我们深入探讨这些测试之前,值得一提的是,“性能”是一个难以衡量的事情,尤其是网络性能。
吞吐量(即以 Gpbs 为单位测量的数据传输速度)和延迟(完成请求所需的时间)是衡量网络性能的常用指标。先前已在此和此处研究了运行叠加网络对吞吐量和延迟的性能影响。从这些测试中我们得知,Kubernetes 网络通常速度很快,服务器可以轻松地使 1G 链路饱和,无论是否使用叠加网络。只有当您拥有 10G 网络时,才需要开始考虑封装的开销。
这是因为在典型的网络性能基准测试中,主机 CPU 没有应用逻辑需要执行,因此可以用于所需的任何网络处理。因此,我们在不会使链路或 CPU 饱和的工作范围内运行测试。这样做可以隔离处理主机上网络策略规则的影响。对于这些测试,我们决定通过测量在不同响应大小范围内完成 HTTP 请求所需的平均时间来衡量延迟。
测试设置
- 硬件:两台服务器,配备 Intel Core i5-5250U CPU(2 核,每核 2 线程),运行频率 1.60GHz,16GB RAM 和 512GB SSD。网卡:Intel Ethernet Connection I218-V (rev 03)
- Ubuntu 14.04.5
- Kubernetes 1.3 用于数据收集(在 v1.4.0-beta.5 上验证了样本)
- Romana v0.9.3.1
- 客户端和服务器负载测试软件
在测试中,我们让一个客户端 Pod 向一个服务器 Pod 发送 2,000 个 HTTP 请求。客户端 Pod 以确保服务器和网络都不会饱和的速率发送 HTTP 请求。我们还通过禁用持久连接(即 HTTP keep-alive)确保每个请求都启动一个新的 TCP 会话。我们使用不同的响应大小运行每个测试,并测量平均请求持续时间(完成该大小的请求需要多长时间)。最后,我们使用不同的策略配置重复了每组测量。
Romana 在创建 Kubernetes 网络策略时检测到它们,将它们转换为 Romana 自己的策略格式,然后将它们应用到所有主机上。目前,Kubernetes 网络策略只应用于入站流量。这意味着出站流量不受影响。
首先,我们在没有任何策略的情况下进行测试,以建立基线。然后,我们再次运行测试,增加测试网络分段的策略数量。这些策略采用常见的“允许给定协议和端口的流量”格式。为了确保数据包必须遍历所有策略,我们创建了一些与数据包不匹配的策略,最后是一个将导致数据包被接受的策略。
下表显示了结果,以毫秒为单位测量,针对不同的请求大小和策略数量
响应大小
|策略 |.5k |1k |10k |100k |1M | |---|---|---|---|---| |0 |0.732 |0.738 |1.077 |2.532 |10.487 | |10 |0.744 |0.742 |1.084 |2.570 |10.556 | |50 |0.745 |0.755 |1.086 |2.580 |10.566 | |100 |0.762 |0.770 |1.104 |2.640 |10.597 | |200 |0.783 |0.783 |1.147 |2.652 |10.677 |
我们可以看到,随着策略数量的增加,处理网络策略引入了非常小的延迟,即使应用 200 个策略,延迟也从未超过 0.2 毫秒。实际上,应用网络策略几乎没有引入任何明显的延迟。另外值得注意的是,将响应大小从 0.5k 增加到 1.0k 几乎没有影响。这是因为对于非常小的响应,建立新连接的固定开销在总响应时间中占主导地位(即传输的数据包数量相同)。
注意:图表中 .5k 和 1k 的线在大约 .8ms 处重叠。
即使作为基线性能的百分比,影响仍然非常小。下表显示,对于最小的响应大小,在最多 200 个策略的情况下,最差情况下的延迟保持在 7% 或更少。对于较大的响应大小,延迟下降到大约 1%。
响应大小
策略 | .5k | 1k | 10k | 100k | 1M |
---|---|---|---|---|---|
0 | 0.0% | 0.0% | 0.0% | 0.0% | 0.0% |
10 | -1.6% | -0.5% | -0.6% | -1.5% | -0.7% |
50 | -1.8% | -2.3% | -0.8% | -1.9% | -0.8% |
100 | -4.1% | -4.3% | -2.5% | -4.3% | -1.0% |
200 | -7.0% | -6.1% | -6.5% | -4.7% | -1.8% |
这些结果中另一个有趣的地方是,随着策略数量的增加,我们注意到较大的请求经历的相对(即百分比)性能下降较小。
这是因为 Romana 安装 iptables 规则时,它会确保属于已建立连接的数据包首先被评估。完整的策略列表只需要在连接的第一个数据包时遍历一次。之后,连接被视为“已建立”,并且连接的状态存储在快速查找表中。因此,对于较大的请求,连接的大多数数据包通过在“已建立”表中进行快速查找来处理,而不是完整遍历所有规则。这种 iptables 优化使得性能基本上独立于网络策略的数量。
这种“流表”是网络设备中常见的优化技术,看起来 iptables 也有效地使用了相同的方法。
另外值得注意的是,在实践中,一个相对复杂的应用可能为每个分段配置几十条规则。同样正确的是,像 Websockets 和持久连接等常见的网络优化技术将进一步提高网络策略的性能(特别是对于小型请求),因为连接保持开放的时间更长,因此可以从已建立连接的优化中获益。
这些测试是使用 Romana 作为后端策略提供商进行的,其他网络策略实现可能会产生不同的结果。然而,这些测试表明,对于几乎所有的应用部署场景,使用 Romana 作为网络后端应用网络策略都不会对性能产生负面影响。
如果您想亲自尝试,我们邀请您查看 Romana。在我们的 GitHub 仓库中,您可以找到一个易于使用的安装程序,它适用于 AWS、Vagrant VM 或任何其他服务器。您可以使用它快速启动一个由 Romana 驱动的 Kubernetes 或 OpenStack 集群。