Table of Contents
本文档介绍了Cilium体系结构。它着重于记录用于实现Cilium数据路径的BPF数据路径挂钩,Cilium数据路径如何与容器编排层集成以及在层之间共享的对象(例如BPF数据路径和Cilium代理)。
数据路径
Linux内核在网络堆栈中支持一组BPF挂钩,可用于运行BPF程序。Cilium数据路径使用这些挂钩来加载BPF程序,这些程序一起使用时会创建更高级别的网络结构。
以下是Cilium使用的钩子的列表和简要说明。有关每个挂钩的详细信息,请参阅《BPF和XDP参考指南》。
-
XDP: XDP BPF挂钩最早出现在网络驱动程序中,并在接收数据包时触发BPF程序的运行。由于程序在任何其他处理可能发生之前直接在数据包数据上运行,因此可以实现最佳的数据包处理性能。该挂钩非常适合运行筛选程序,这些程序会丢弃恶意或意外流量以及其他常见的DDOS保护机制。
-
流量控制入口/出口:附加到流量控制(tc)入口挂钩的BPF程序已附加到与XDP相同的网络接口上,但是将在网络堆栈完成对数据包的初始处理之后运行。挂钩在堆栈的L3层之前运行,但是可以访问与数据包关联的大多数元数据。这是进行本地节点处理(例如应用L3 / L4端点策略并将流量重定向到端点)的理想选择。对于面向网络的设备,tc入口挂钩可以与上述XDP挂钩耦合。完成此操作后,可以合理地假设此时的大多数流量都是合法的,并已发往主机。
容器通常使用称为veth对的虚拟设备,该设备充当将容器连接到主机的虚拟线路。通过连接到此第ve对主机侧的TC入口挂钩,Cilium可以监视和执行对退出容器的所有流量的策略。通过将BPF程序附加到与每个容器相关联的第五对,并通过将另一个BPF程序附加到tc入口挂钩上,将所有网络流量路由到主机侧虚拟设备,Cilium可以监视和执行有关进入或退出节点的所有流量的策略。
根据使用情况,容器也可以通过ipvlan设备而不是veth对连接。在此模式下,主机中的物理设备是ipvlan主设备,在容器中设置了从属模式的虚拟ipvlan设备。ipvlan相对于第ve对的好处之一是,堆栈需要较少的资源才能将数据包推入另一个网络名称空间的ipvlan从设备,因此可以实现更好的延迟结果。此选项可用于非特权容器。然后,将tc的BPF程序附加到容器网络名称空间内ipvlan从设备上的tc出口钩子上,以使Cilium应用L3 / L4端点策略,例如,
-
套接字操作:套接字操作挂钩连接到特定的cgroup并在TCP事件上运行。Cilium将BPF套接字操作程序附加到根cgroup,并使用它监视TCP状态转换,尤其是ESTABLISHED状态转换。如果TCP套接字具有节点本地对等方(可能是本地代理),则当套接字转换为ESTABLISHED状态时,将附加套接字发送/接收程序。
-
套接字发送/接收:套接字发送/接收钩子在TCP套接字执行的每个发送操作上运行。此时,挂钩可以检查消息,然后删除消息,将消息发送到TCP层或将消息重定向到另一个套接字。Cilium使用它来加速数据路径重定向,如下所述。
将以上挂钩与虚拟接口(cilium_host,cilium_net),可选的覆盖接口(cilium_vxlan),Linux内核加密支持和用户空间代理(Envoy)Cilium结合使用,可以创建以下网络对象。
-
预过滤器:预过滤器对象运行XDP程序,并提供一组预过滤器规则,用于过滤来自网络的流量以实现最佳性能。具体来说,使用Cilium代理提供的一组CIDR映射进行查找,然后丢弃数据包(例如,当目的地不是有效端点时),或者允许堆栈进行处理。可以根据需要轻松扩展此功能,以构建新的预过滤条件/功能。
-
端点策略:端点策略对象实现Cilium端点强制。使用映射查找与数据包相关的身份和策略的数据包,该层可以很好地扩展到许多端点。根据策略,此层可能会丢弃数据包,转发到本地终结点,转发到服务对象或转发到L7策略对象以获取进一步的L7规则。这是Cilium数据路径中的主要对象,负责将数据包映射到身份并实施L3和L4策略。
-
服务:服务对象针对对象接收的每个数据包在目标IP和目标端口上执行映射查找。如果找到匹配的条目,则数据包将转发到已配置的L3 / L4端点之一。Service块可用于使用TC入口挂钩在任何接口上实现独立的负载平衡器,也可以集成在端点策略对象中。
-
L3加密:在入口处,L3加密对象将数据包标记为解密,将数据包传递到Linux xfrm(转换)层进行解密,在数据包解密后,对象接收到数据包,然后将其向上传递到堆栈进行进一步处理对象。根据模式,直接路由或覆盖,这可能是BPF尾调用或将数据包传递到下一个对象的Linux路由堆栈。解密所需的**被编码在IPsec标头中,因此在进入时,我们无需进行映射查找即可找到解***。
在出口上,首先使用目标IP执行映射查找,以确定是否应加密数据包,以及如果需要,则在目标节点上可以使用哪些**。选择两个节点上可用的最新**,并将数据包标记为加密。然后,将数据包传递到Linux xfrm层,在此对其进行加密。接收到现在加密的数据包后,将其发送到Linux堆栈进行路由,或者如果正在使用覆盖,则直接进行尾部调用,从而将其传递到下一层。
-
套接字层强制:套接字层强制使用两个钩子,套接字操作钩子和套接字发送/接收钩子来监视并附加到与Cilium管理的端点关联的所有TCP套接字,包括任何L7代理。套接字操作挂钩将标识要加速的候选套接字。这些包括所有本地节点连接(端点到端点)以及与Cilium代理的任何连接。然后,这些已标识的连接将由套接字send / recv挂钩处理所有消息,并将使用sockmap快速重定向对其进行加速。快速重定向可确保在Cilium中实现的所有策略对于关联的套接字/端点映射都是有效的,并假定它们将消息直接发送到对等套接字。之所以允许这样做,是因为sockmap send / recv挂钩可确保不需要任何上述对象来处理消息。
-
L7策略: L7策略对象将代理流量重定向到Cilium用户空间代理实例。Cilium使用Envoy实例作为其用户空间代理。然后,Envoy将根据配置的L7策略转发流量或生成适当的拒绝消息。
连接这些组件以创建Cilium使用的灵活高效的数据路径。下面,我们显示以下可能的流,这些流将单个节点上的端点连接到端点,并将端点连接到出口网络设备。在每种情况下,都有一个附加的图,显示了启用套接字层强制时可用的TCP加速路径。
端点到端点
首先,我们显示本地端点到端点的流,以及有关出口和入口的可选L7策略。随后是启用了套接字层强制的同一端点到端点流。为TCP流量启用套接字层强制后,发起连接的握手将遍历端点策略对象,直到建立TCP状态为止。然后,建立连接后,仅需要L7策略对象。
从端点出站
接下来,我们将显示本地端点与可选覆盖网络的出口。在可选的覆盖网络中,流量被转发出对应于覆盖的Linux网络接口。在默认情况下,覆盖接口名为cilium_vxlan。与上述类似,当启用套接字层强制并且使用了L7代理时,我们可以避免在端点和用于TCP流量的L7策略之间运行端点策略块。如果启用,可选的L3加密块将对数据包进行加密。
进入端点
最后,我们还通过可选的覆盖网络向本地端点显示了入口。与上述套接字层类似,可以使用强制层来避免在代理服务器和端点套接字之间进行一组策略遍历。如果数据包在接收时被加密,则首先将其解密,然后通过正常流程进行处理。
基于veth与基于ipvlan的数据路径
基于ipvlan的数据路径目前仅在技术预览中,并用于实验目的。在将来的Cilium版本中将取消此限制。
默认情况下,Cilium CNI在基于veth的数据路径模式下运行,该模式提供了更大的灵活性,因为所有BPF程序都由Cilium在主机网络名称空间之外进行管理,因此可以为容器授予其名称空间(如CAP_NET_ADMIN)的特权,而不会影响安全性,因为BPF强制执行点主机中的容器无法访问。如果BPF程序是从主机的网络名称空间附加的,则BPF还具有接管并有效管理本地容器和主机之间的大多数转发逻辑的能力,因为始终有可访问的网络设备。但是,这也带来了延迟成本,因为在基于veth的模式下,当将数据包从一个veth设备移交给另一网络名称空间中的对等设备时,需要在内部重新遍历网络堆栈。
为了获得更多延迟优化的数据路径,Cilium CNI还支持ipvlan L3 / L3S模式,但有很多限制。为了支持没有ipvlan发夹模式的较早内核,Cilium在tc出口层的容器网络名称空间内的ipvlan从设备上附加了BPF程序,这意味着此数据路径模式只能用于未与CAP_NET_ADMIN和CAP_NET_RAW特权!ipvlan使用内部转发逻辑进行从站到从站或从站到主站的直接重定向,因此,不从BPF程序本身执行到设备的转发。网络名称空间切换在ipvlan模式下更有效,因为不需要像在基于veth的外部包数据路径中那样重新遍历堆栈。主机到容器网络名称空间的切换直接发生在L3层,而不必将数据包排队和重新安排以供以后的入口处理。在本地端点之间进行通信的情况下,执行从上到下的切换一次,而不必执行两次。
对于ipvlan模式下的Cilium,当前的实现中存在许多其他限制,这些限制将在以后的工作中加以解决:此时无法启用NAT64,也无法通过代理实施L7策略。当前未启用到本地端点的服务负载平衡,也未启用容器到主机本地通信。如果需要这些功能之一,则建议使用默认的基于veth的数据路径模式。
可以通过运行Cilium守护进程来启用Cilium的CNI中的ipvlan模式,例如,后者通常指定物理联网设备,然后该物理网络设备还充当ipvlan主设备。请注意,如果在Kubernetes的L3S模式下部署ipvlan数据路径模式,请确保使用包含以下ipvlan修复程序的稳定内核运行:d5256083f62e。--datapath-mode=ipvlan --ipvlan-master-device=bond0
这样就完成了数据路径概述。有关BPF的更多详细信息,请参见《 BPF和XDP参考指南》。“使节”部分中提供了有关如何扩展L7策略的其他详细信息。
规模
BPF映射限制
所有BPF映射都是以容量上限创建的。超出限制的插入将失败,从而限制了数据路径的可伸缩性。下表显示了地图的默认值。每个限制都可以在源代码中修改。如果需要,可根据要求添加配置选项。
| 地图名称 | 范围 | 默认限制 | 规模影响 |
|---|---|---|---|
| 连接跟踪 | 节点或端点 | 1M TCP / 256K UDP | 最多1M并发TCP连接,最大256K预期UDP答案 |
| 终点 | 节点 | 64k | 每个节点最多64k本地端点+主机IP |
| IP缓存 | 节点 | 512K | 所有群集中最多256K个端点(IPv4 + IPv6),最多512k端点(IPv4或IPv6) |
| 负载均衡器 | 节点 | 64k | 所有集群中所有服务的最大64k累积后端 |
| 政策 | 终点 | 16k | 特定端点允许的最大16k身份+端口+协议对 |
| 代理地图 | 节点 | 512k | 最多512k并发重定向TCP连接到代理 |
| 隧道 | 节点 | 64k | 所有群集中最多32k节点(IPv4 + IPv6)或64k节点(IPv4或IPv6) |
Kubernetes集成
下图显示了kube-proxy安装的iptables规则和Cilium安装的iptables规则的集成。
©版权所有2017-2019,Cilium作者 修订415a7f00。
使用Sphinx使用Read the Docs 提供的 主题构建。
参考阅读
《深入理解 Cilium 的 eBPF(XDP)收发包路径:数据包在Linux网络协议栈中的路径》
《eBPF.io eBPF文档:扩展的数据包过滤器(BPF)》
《介绍Calico eBPF数据平面:Linux内核网络、安全性和跟踪(Kubernetes、kube-proxy)》
《Linux eBPF和XDP高速处理数据包;使用EBPF编写XDP网络过滤器;高性能ACL》
《Understanding (and Troubleshooting) the eBPF Datapath in Cilium》
《kubernetes(K8s):管理云平台中多个主机上的容器化的应用》
《Cilium提供并透明地保护应用程序工作负载之间的网络连接和负载平衡:什么是eBPF和XDP?》