1. cilium-高性能CNI
cilium 高性能的原因:其采用技术创新短路传统了 Kernel 框架,减少了数据包转发所需的指令。这些技术包括,eBPF 加持下的 redirect、redirect_peer、redirect_neigh、XDP、sockmap、sk redirect 等技术。
另外实现的Kubernetes service 数据面性能高,Service 规模扩大,控制面下发时间变化不大。 Kubernetes service 数据面性能高,分为集群内访问的 socket LB 技术,该技术使得不需要做数据包 skb 更改,直接将容器平台内部访问 service 流量转变成直接访问 Pod 效果,访问 Pod 路径也是经过加速的。南北向 Service(NodePort、external IP、HostPort)性能高的原因是其支持 Native XDP 加速,外加上路径跳转优化,对于 Remote Pod 的 Service 场景,还支持了 DR 模式,从逻辑上减少一跳路径。 Kubernetes service 控制面下发性能,这块主要采用了 eBPF map 技术,该技术实质会采用 Hash 方法,摆脱了变动 Service 就要全量下发 iptables 的问题,因此控制面下发时间随着 Service 规模的变大,策略更新延时变化不大。
2. cilium-srv6实现
1. 主要的MAP数据结构:其中用到的bpf数据结构类型包括 BPF_MAP_TYPE_LPM_TRIE,BPF_MAP_TYPE_LRU_HASH,BPF_MAP_TYPE_HASH。其中,SRV6_VRF_MAP4负责通过内网ip和目的cidr查找对应的vrf,SRV6_POLICY_MAP 根据vrf和dst cidr找到对应的目的sid,SRV6_SID_MAP 记录目的sid对应的vrf。SRV6_STATE_MAP记录的是内外网的ip映射。
#ifdef ENABLE_SRV6
# define SRV6_VRF_MAP(IP_FAMILY) \
struct { \
__uint(type, BPF_MAP_TYPE_LPM_TRIE); \
__type(key, struct srv6_vrf_key ## IP_FAMILY); \
__type(value, __u32); \
__uint(pinning, LIBBPF_PIN_BY_NAME); \
__uint(max_entries, SRV6_VRF_MAP_SIZE); \
__uint(map_flags, BPF_F_NO_PREALLOC); \
} SRV6_VRF_MAP ## IP_FAMILY __section_maps_btf;
struct srv6_vrf_key4 {
struct bpf_lpm_trie_key lpm;
__u32 src_ip;
__u32 dst_cidr;
};
// 对应的vrf值u32
# define SRV6_POLICY_MAP(IP_FAMILY) \
struct { \
__uint(type, BPF_MAP_TYPE_LPM_TRIE); \
__type(key, struct srv6_policy_key ## IP_FAMILY); \
__type(value, union v6addr); \
__uint(pinning, LIBBPF_PIN_BY_NAME); \
__uint(max_entries, SRV6_POLICY_MAP_SIZE); \
__uint(map_flags, BPF_F_NO_PREALLOC); \
} SRV6_POLICY_MAP ## IP_FAMILY __section_maps_btf;
# define SRV6_STATE_MAP(IP_FAMILY) \
struct { \
__uint(type, BPF_MAP_TYPE_LRU_HASH); \
__type(key, struct srv6_ipv ## IP_FAMILY ## _2tuple); /* inner header */ \
__type(value, struct srv6_ipv6_2tuple); /* outer header */ \
__uint(pinning, LIBBPF_PIN_BY_NAME); \
__uint(max_entries, SRV6_STATE_MAP_SIZE); \
} SRV6_STATE_MAP ## IP_FAMILY __section_maps_btf;
# ifdef ENABLE_IPV4
SRV6_VRF_MAP(4)
SRV6_POLICY_MAP(4)
SRV6_STATE_MAP(4)
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__type(key, union v6addr); /* SID */
__type(value, __u32); /* VRF ID */
__uint(pinning, LIBBPF_PIN_BY_NAME);
__uint(max_entries, SRV6_SID_MAP_SIZE);
__uint(map_flags, BPF_F_NO_PREALLOC);
} SRV6_SID_MAP __section_maps_btf;
/* Key of an a BPF_MAP_TYPE_LPM_TRIE entry */
struct bpf_lpm_trie_key {
__u32 prefixlen; /* up to 32 for AF_INET, 128 for AF_INET6 */
__u8 data[0]; /* Arbitrary size */
};
struct srv6_vrf_key4 {
struct bpf_lpm_trie_key lpm;
__u32 src_ip;
__u32 dst_cidr;
};
struct srv6_policy_key4 {
struct bpf_lpm_trie_key lpm;
__u32 vrf_id;
__u32 dst_cidr;
};
struct srv6_policy_key6 {
struct bpf_lpm_trie_key lpm;
__u32 vrf_id;
union v6addr dst_cidr;
};
// inner
struct srv6_ipv4_2tuple {
__u32 src;
__u32 dst;
};
struct srv6_ipv6_2tuple {
union v6addr src;
union v6addr dst;
};
tail_srv6_encap ->srv6_handling->srv6_handling4 -> srv6_encapsulation