cilium 官方文档翻译(5)eBPF 数据路径

概述

Linux内核在网络堆栈中支持挂载BPF Hook,可用于运行BPF程序。Cilium数据路径使用这些钩子加载BPF程序,组合使用并创建高级别的网络结构。

下面是Cilium使用的钩子列表和简要说明。有关每个挂钩的详细信息,请参阅BPF和XDP参考指南。

  • XDP: XDP BPF钩子尽可能早地出现在网络驱动程序中,网络设备收到数据包时触发BPF程序的运行。因为程序在所有其它处理发生之前直接在分组数据上运行,它对性能提升的收益。此挂钩非常适合运行过滤程序,以丢弃恶意或意外流量,以及其他常见的DDOS保护机制。
  • Traffic Control Ingress/Egress: 流量控制(tc)ingress 挂钩的BPF程序连接到网络接口,但将在网络堆栈完成数据包的初始处理后运行。与XDP相同的是钩子在堆栈的L3层之前运行,但可以访问与数据包相关联的大部分元数据。这是进行本地节点处理的理想选择,例如应用L3/L4端点策略和将流量重定向到端点。对于面向网络的设备,tc ingress钩子可以与上述XDP钩子耦合。完成此操作后,可以合理地假设此时的大部分流量都是合法的,并且目的地是主机。

容器通常使用称为veth对的虚拟设备,该虚拟设备充当将容器连接到主机的虚拟线路。通过连接到该veth对主机侧的TC入口钩子,Cilium可以监视并强制执行离开容器的所有流量的策略。通过将BPF程序附加到与每个容器相关联的veth对,并将所有网络流量路由到主机侧虚拟设备,同时将另一个BPF程序连接到tc入口钩子,Cilium可以对进入或离开节点的所有流量进行监控并实施策略。

  • Socket operations: 套接字操作挂钩连接到特定的cgroup,并在TCP事件上运行。Cilium将BPF套接字操作程序附加到root cgroup,并使用该程序监视TCP状态转换,特别是已建立的状态转换。当套接字转换为已建立状态时,如果TCP套接字具有节点本地对等方(可能是本地代理),则BPF会附加套接字发送/接收程序。
  • Socket send/recv: 套接字发送/接收钩子在TCP套接字执行的每个发送操作上运行。此时,钩子可以检查消息,或者丢弃消息,将消息发送到TCP层,或者将消息重定向到另一个套接字。Cilium使用它来加速数据路径重定向,如下所述。

将上述挂钩与虚拟接口(cilium_host、cilium _net)、可选overlay接口(cilium_vxlan)、Linux内核加密支持和用户空间代理(Envoy)cilium相结合,可以创建以下网络对象。

  • Prefilter: prefilter对象运行一个XDP程序,并提供一组预过滤器规则,用于过滤来自网络的流量以获得最佳性能。具体而言,Cilium代理提供的一组CIDR映射用于执行查找,并且数据包要么被丢弃(例如,当目标不是有效端点时),要么被允许由堆栈处理。这可以根据需要轻松扩展,以构建新的预过滤器标准/功能。
  • Endpoint Policy: 端点策略对象实现Cilium端点强制执行。使用映射查找与身份和策略相关的数据包,该层可以很好地扩展到许多端点。根据策略,该层可能会丢弃数据包、转发到本地端点、转发到服务对象或转发到L7策略对象以获取进一步的L7规则。这是Cilium数据路径中的主要对象,负责将数据包映射到身份并实施L3和L4策略。
  • Service: 服务对象对对象接收到的每个数据包在目标IP和可选的目标端口上执行映射查找。如果找到匹配条目,数据包将转发到配置的L3/L4端点之一。服务块可用于通过TC入口钩子在任何接口上实现独立负载平衡器,或者可集成在端点策略对象中。
  • L3 Encryption: 在Ingress方向L3加密对象标记要解密的数据包,将数据包传递到Linux xfrm(transform)层进行解密,数据包解密后,对象接收数据包,然后将其传递到堆栈上,供其他对象进一步处理。根据直接路由或Overlay模式,BPF尾部调用或将数据包传递给下一个对象的Linux路由堆栈。解密所需的密钥编码在IPsec报头中,因此在进入时,我们不需要进行映射查找来找到解密密钥。

在出口处,首先使用目的地IP执行映射查找,以确定是否应该加密分组,如果应该,则确定目的地节点上有哪些密钥可用。选择两个节点上可用的最新密钥,并将数据包标记为加密。然后将数据包传递到Linux xfrm层,在那里对其进行加密。在接收到现在加密的数据包后,通过将其发送到Linux堆栈进行路由,或者在使用Overlay的情况下执行直接尾部调用,将其传递到下一层。

  • Socket Layer Enforcement: 套接字层强制执行使用两个钩子:套接字操作钩子和套接字发送/接收钩子来监视和连接与Cilium管理的端点相关的所有TCP套接字,包括任何L7代理。套接字操作钩子将识别用于加速的候选套接字。这些包括所有本地节点连接(端点到端点)和到Cilium代理的任何连接。这些已识别的连接将由套接字发送/接收挂钩处理所有消息,并将使用sockmap快速重定向进行加速。快速重定向确保Cilium中实现的所有策略对于关联的套接字/端点映射都有效,并且假设它们是有效的,则将消息直接发送到对等套接字。这是允许的,因为sockmap send/recv钩子确保消息不需要由上述任何对象处理。
  • L7 Policy: L7策略对象将代理流量重定向到Cilium用户空间代理实例。Cilium使用Envoy实例作为其用户空间代理。Envoy然后将转发流量或基于配置的L7策略生成适当的拒绝消息。

Iptables Usage

根据使用的Linux内核版本,eBPF数据路径可以完全在eBPF中实现不同的功能集。如果某些必需的功能不可用,则使用传统iptables实现提供该功能。有关更多详细信息,请参见IPsec要求。

kube-proxy Interoperability

下图显示了kube proxy安装的iptables规则与Cilium安装的iptable规则的集成。

cilium 官方文档翻译(5)eBPF 数据路径_第1张图片

数据包生命周期

Endpoint to Endpoint

首先,我们展示了本地端点到端点流,其中包含可选的ingress/egress L7策略。然后是启用套接字层强制执行的同节点端点到端点流。在为TCP通信启用套接字层强制执行的情况下,发起连接的握手将遍历端点策略对象,直到TCP状态ESTABLISHED为止。在ESTABLISHED连接之后,只需要L7策略对象。

cilium 官方文档翻译(5)eBPF 数据路径_第2张图片

Egress from Endpoint

接下来,我们将显示要使用可选的Overlay网络从本地端点发出数据包。在可选的overlay中,网络流量被转发到对应于overlay的Linux网络接口。在默认情况下,覆盖接口名为cilium_ vxlan。与上述类似,当启用套接字层强制并且使用L7代理时,我们可以避免在端点和TCP流量的L7策略之间运行端点策略块。如果启用,可选的L3加密块将加密数据包。

cilium 官方文档翻译(5)eBPF 数据路径_第3张图片

Ingress to Endpoint

最后,我们还展示了通过可选的overlay网络进入本地端点。与上述套接字层类似,可以使用强制执行来避免代理和端点套接字之间的一组策略遍历。如果数据包在接收时被加密,则首先对其进行解密,然后通过正常流进行处理。

cilium 官方文档翻译(5)eBPF 数据路径_第4张图片

这就完成了数据路径概述。更多的BPF细节可以在BPF和XDP参考指南中找到。有关如何扩展L7策略的更多详细信息,请参阅Envoy部分

eBPF Maps

所有BPF映射都是以容量上限创建的。超出限制的插入将失败,从而限制数据路径的可伸缩性。下表显示了贴图的默认值。每个限制都可以在源代码中实现。如果需要,将根据要求添加配置选项。

Map Name Scope Default Limit Scale Implications
Connection Tracking node or endpoint 1M TCP/256k UDP Max 1M concurrent TCP connections, max 256k expected UDP answers
NAT node 512k Max 512k NAT entries
Neighbor Table node 512k Max 512k neighbor entries
Endpoints node 64k Max 64k local endpoints + host IPs per node
IP cache node 512k Max 256k endpoints (IPv4+IPv6), max 512k endpoints (IPv4 or IPv6) across all clusters
Load Balancer node 64k Max 64k cumulative backends across all services across all clusters
Policy endpoint 16k Max 16k allowed identity + port + protocol pairs for specific endpoint
Proxy Map node 512k Max 512k concurrent redirected TCP connections to proxy
Tunnel node 64k Max 32k nodes (IPv4+IPv6) or 64k nodes (IPv4 or IPv6) across all clusters
IPv4 Fragmentation node 8k Max 8k fragmented datagrams in flight simultaneously on the node
Session Affinity node 64k Max 64k affinities from different clients
IP Masq node 16k Max 16k IPv4 cidrs used by BPF-based ip-masq-agent
Service Source Ranges node 64k Max 64k cumulative LB source ranges across all services
Egress Policy endpoint 16k Max 16k endpoints across all destination CIDRs across all clusters

对于某些BPF映射,可以使用cilium-agent的命令行选项覆盖容量上限。以下参数可以设置容量–bpf-ct-global-tcp-max, --bpf-ct-global-any-max, --bpf-nat-global-max, --bpf-neigh-global-max, --bpf-policy-map-max, --bpf-fragments-map-max --bpf-lb-map-max.

如果指定了--bpf-ct-global-tcp-max--bpf-ct-global-any-max,则NAT表大小(--bpf-nat-global-max)不得超过组合ct表大小(tcp+UDP)的2/3。如果未显式设置--bpf-nat-global-max,或者使用动态bpf映射大小,则会自动设置该值(见下文)。

使用--bpf-map-dynamic-size-ratio标志,在agent启动时根据给定的总系统内存比率确定几个大型bpf映射的容量上限。例如,给定的比率0.0025将导致这些映射使用的总系统内存的0.25%。
此标志影响以下消耗系统中大部分内存的BPF映射:cilium_ct_{4,6}_global, cilium_ct_{4,6}_any, cilium_nodeport_neigh{4,6}, cilium_snat_v{4,6}_external and cilium_lb{4,6}_reverse_sk.
kube-proxy根据机器拥有的内核数设置linux连接跟踪表中的最大条目数。kube-proxy的默认值为每个核心最多32768个条目,最小131072个条目,而不管机器拥有多少个核心。
Cilium有自己的连接跟踪表作为BPF映射,这些映射的条目数是根据节点中的总内存量计算的,最少有131072个条目,而不管机器拥有多少内存。
下表显示了kube-proxy和Cilium在配置Cilium时为自己的连接跟踪表设置的值—--bpf-map-dynamic-size-ratio:0.0025

vCPU Memory (GiB) Kube-proxy CT entries Cilium CT entries
1 3.75 131072 131072
2 7.5 131072 131072
4 15 131072 131072
8 30 262144 284560
16 60 524288 569120
32 120 1048576 1138240
64 240 2097152 2276480
96 360 3145728 4552960

你可能感兴趣的:(网络,kubernetes,云原生,linux)