文章目录
- vpp load balance plugin
- 当前情况
- 使用
- 分析
- 流量
- 参考
vpp load balance plugin
负载平衡器配有一组虚拟平衡器IP(VIP,可以是前缀),对于每一个,VIP,一组应用程序服务器地址(ASs)。
有四种方法导向不同的流量ASs: 1). IPv4 GRE ad IPv6 GRE encap类型:给定VIP(或VIP前缀)通过的流量通过GRE不同的隧道传输ASs,确保给定会话总是通过隧道传输到相同的。
2). IPv4 L3DSR encap类型:L3DSR用于克服直接服务器返回负载平衡的两层限制。VIP映射到DSCP位,并重用TOS位将DSCP位传输到服务器,服务器将VIP从DSCP映射到VIP。 VIP或ASs都可以是IPv4或IPv6.但是给定的VIP,所有ASs必须使用相同的encap。类型(即IPv4 GRE或IPv6 GRE或IPv4 L3DSR)。这意味着给定VIP,所有AS地址必须属于同一个家庭。
3). IPv4/IPv6 NAT4/NAT6 encap 类型:该类型在用户空间中提供 kube-proxy 替代数据平面 linux 内核基于 iptables 的 kube-proxy 代理。
负载平衡器插件目前支持三种服务类型:a)cluster IP添加端口:支持任何协议,包括TCP、UDP。b) NodePort IP加节点端口:目前只支持UDP。c) 外部负载平衡器。
对于为给定VIP(或VIP第一个数据包根据内部负载平衡算法选择接收到的特定会话AS,然后执行 DNAT 操作并发送到所选 AS。同时,将创建一个会话条目以存储为所选结果。该会话的以下数据包将首先查找会话表,这将确保给定会话始终路由到与相同的。
对于AS返回的数据包将执行SNAT操作并发送.
当前情况
本文主要介绍 IPv4/IPv6 NAT4/NAT6 类型,和 kube-proxy 数据面功能相同,可以向 kubernetes service 使用相同的方法。 目前社区代码的模块有问题,我提到了 PR 进行解决: https://gerrit.fd.io/r/c/vpp/ /36494
要实现 lb,需要考虑,tcp此时,一次业务访问有多个包,如握手和业务。此时,需要一个后端端点来处理。需要链接维护。 vpp 有实现,有时间再分析。
使用
举例,client 端访问 VIP 10.10.2.2/24 Port 8080 到 后端 server (192.168.1.2:80,192.168.1.3:80)。和 kubernetes 的 service 相似。
配置方法
#vpp lb set interface nat4 in GigabitEthernet0/9/0 lb vip 10.10.2.2/32 protocol tcp port 8080 encap nat4 type clusterip target_port 80 lb as 10.10.2.2/32 protocol tcp port 8080 192.168.1.1 192.168.1.3
客户端 访问 10.10.2.2:8080 会负载到 后端 192.168.1.1:80 和 192.168.1.3:80 服务
分析
配置项1: lb set interface nat4 in GigabitEthernet0/9/0 功能是设置下行流量入口 lb nat4,使该接口进入的包进入到 lb-nat4-in2out 节点做 SNAT
配置项2: lb vip 10.10.2.2/32 protocol tcp port 8080 encap nat4 type clusterip target_port 80 创建一个 vip 10.10.2.2 port 8080 后面 target port 是 80,在 vpp 上的实现
src/plugins/lb/lb.c L1163
//Update flow hash table lb_vip_update_new_flow_table(vip); // 为 vip 创建合适的 table,当为 vip 加 as 之后,该表将更新table 借鉴设计方案 meglav 可以看上章。 //Create adjacency to direct traffic lb_vip_add_adjacency(lbm, vip, &vip_prefix_index); // 将 vip adjacency 加到 ip4 或者 ip6 table。
lb_vip_add_adjacency 将 10.10.2.2/32 加到 ip4 table 中,并 为 ip 设置的 dpo 类型为 nat4_port,和指定的 vip 的 vip_prefix_index
最后将该 vip 存 bihash key 是 vip_idx protocol port value 是 vip 索引 配置项3: lb as 10.10.2.2/32 protocol tcp port 8080 192.168.1.1 192.168.1.3 该配置 为 vip 配置 两个后端断点。 创建了 lb as后,为 as 写 fib_table,并设置 dpo lb.c L681 为下行包写 snat static mapping
L752
lb_vip_update_new_flow_table(vip);
更新 flow table 表
流量
上行流量,当 vpp 收到 目的是 vip port 流量时,丢失 lb4-nat4-port 节点处理 处理过程大致如下:
- vip 收到报文,传到dpo 即 vip 的索引, 拿 索引和报纸协议号和端口 vip
- 从 lb_main 申请 sticky_table hash bucket。
- 计算报文 hash
lb_hash_get (sticky_ht, hash0, vip_index0, lb_time, &available_index0, &asindex0);
若发现已有,返回 asindex0 (as 并在 packet from existing sessions中加 1.匹配之前的连接; 若没有,新建 asindex0,在 first session packet 加1、查处理过程并更新 hash 4. 若报文为指定 encap 类型 src/plugins/lb/node.c L489 报文的目的ip和端口 (vip 将目的和端口转换为后端 as (hash 得到的 asindex0)的ip 和 port; checksum 后发到 lookup 节点处理
-
回包时,先进入 lb-nat4-in2out 节点处理 node.c L778
-
分析报文,查询 nat44_mapping,获得需要还原的 ip port (vip port),处理,checksum 后发到 LB_NAT4_IN2OUT_NEXT_LOOKUP 进行 lookup 即后续处理。
参考
https://s3-docs.fd.io/vpp/22.06/developer/plugins/lb.html?highlight=load balance plugin