本文已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。
Kubernetes 集群中的高性能网络策略
网络策略
自从 7 月份 Kubernetes 1.3 发布以来,用户已经能够在他们的集群中定义和实施网络策略。这些策略是防火墙规则,用于指定允许进出 Pod 以及 Pod 之间传递的流量类型。如果请求,Kubernetes 会阻止所有未明确允许的流量。策略应用于由公共标签标识的 Pod 组。然后,可以使用标签来模拟传统的分段网络,这些网络通常用于隔离多层应用程序中的层:例如,您可以使用特定的“段”标签来标识您的前端和后端 Pod。策略控制这些段之间的流量,甚至控制进出外部来源的流量。
分段流量
这对应用程序开发人员意味着什么?最后,Kubernetes 获得了提供“纵深防御”的必要功能。可以对流量进行分段,并且可以独立保护应用程序的不同部分。例如,您可以非常轻松地通过特定的网络策略来保护您的每个服务:服务后面的复制控制器标识的所有 Pod 已经由一个特定的标签标识。因此,您可以使用相同的标签将策略应用于这些 Pod。
长期以来,纵深防御一直被推荐为最佳实践。通过将安全组应用于 VM,可以很容易地在 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 表示在不久的将来会支持。 红帽的 OpenShift 也包含网络策略功能。
我们选择 Romana 作为这些测试的后端,因为它将 Pod 配置为在完整的 L3 配置中使用本机可路由 IP 地址。因此,网络策略可以直接由 Linux 内核中的主机使用 iptables 规则来应用。这产生了一个高性能、易于管理的网络。
测试网络策略的性能影响
应用网络策略后,需要根据这些策略检查网络数据包,以验证这种类型的流量是否允许。但是,为每个数据包应用网络策略的性能损失是多少?我们能否在不影响应用程序性能的情况下使用所有强大的策略功能?我们决定通过运行一些测试来找出答案。
在我们深入研究这些测试之前,值得一提的是,“性能”是一件难以衡量的事情,尤其是网络性能。
吞吐量(即以 Gbps 为单位衡量的数据传输速度)和延迟(完成请求所需的时间)是衡量网络性能的常用指标。之前 此处 和 此处 已检查了在吞吐量和延迟方面运行覆盖网络的性能影响。我们从这些测试中了解到,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 线在 ~0.8 毫秒处重叠
即使作为基线性能的百分比,影响仍然非常小。下表显示,对于最小的响应大小,最坏情况下的延迟保持在 7% 或更少,最多可达 200 个策略。对于较大的响应大小,延迟降至约 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 集群。