Linux内核在网络堆栈中支持挂载BPF Hook,可用于运行BPF程序。Cilium数据路径使用这些钩子加载BPF程序,组合使用并创建高级别的网络结构。
下面是Cilium使用的钩子列表和简要说明。有关每个挂钩的详细信息,请参阅BPF和XDP参考指南。
容器通常使用称为veth对的虚拟设备,该虚拟设备充当将容器连接到主机的虚拟线路。通过连接到该veth对主机侧的TC入口钩子,Cilium可以监视并强制执行离开容器的所有流量的策略。通过将BPF程序附加到与每个容器相关联的veth对,并将所有网络流量路由到主机侧虚拟设备,同时将另一个BPF程序连接到tc入口钩子,Cilium可以对进入或离开节点的所有流量进行监控并实施策略。
将上述挂钩与虚拟接口(cilium_host、cilium _net)、可选overlay接口(cilium_vxlan)、Linux内核加密支持和用户空间代理(Envoy)cilium相结合,可以创建以下网络对象。
在出口处,首先使用目的地IP执行映射查找,以确定是否应该加密分组,如果应该,则确定目的地节点上有哪些密钥可用。选择两个节点上可用的最新密钥,并将数据包标记为加密。然后将数据包传递到Linux xfrm层,在那里对其进行加密。在接收到现在加密的数据包后,通过将其发送到Linux堆栈进行路由,或者在使用Overlay的情况下执行直接尾部调用,将其传递到下一层。
根据使用的Linux内核版本,eBPF数据路径可以完全在eBPF中实现不同的功能集。如果某些必需的功能不可用,则使用传统iptables实现提供该功能。有关更多详细信息,请参见IPsec要求。
下图显示了kube proxy安装的iptables规则与Cilium安装的iptable规则的集成。
首先,我们展示了本地端点到端点流,其中包含可选的ingress/egress L7策略。然后是启用套接字层强制执行的同节点端点到端点流。在为TCP通信启用套接字层强制执行的情况下,发起连接的握手将遍历端点策略对象,直到TCP状态ESTABLISHED为止。在ESTABLISHED连接之后,只需要L7策略对象。
接下来,我们将显示要使用可选的Overlay网络从本地端点发出数据包。在可选的overlay中,网络流量被转发到对应于overlay的Linux网络接口。在默认情况下,覆盖接口名为cilium_ vxlan。与上述类似,当启用套接字层强制并且使用L7代理时,我们可以避免在端点和TCP流量的L7策略之间运行端点策略块。如果启用,可选的L3加密块将加密数据包。
最后,我们还展示了通过可选的overlay网络进入本地端点。与上述套接字层类似,可以使用强制执行来避免代理和端点套接字之间的一组策略遍历。如果数据包在接收时被加密,则首先对其进行解密,然后通过正常流进行处理。
这就完成了数据路径概述。更多的BPF细节可以在BPF和XDP参考指南中找到。有关如何扩展L7策略的更多详细信息,请参阅Envoy部分
所有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 |