为了降本增效,网关部署到了业务的节点上,参考 eBPF Talk: 善用 TCP option 来支持网关 ping。然而,业务节点上可能会配置不少 iptables 规则,从该节点 ping 另一台网关的时候,可能会被 iptables 规则丢包。
为了解决这个问题,可以使用隔离的 netns 来避免 iptables 规则干扰 ping 包的收发。
准备隔离的 netns
在隔离的 netns 里,怎么收发 ping 包呢?
- 通过 veth pair 连接隔离的 netns 和 host netns;
- 在隔离的 netns 里,配置 MAC 地址;
- 在隔离的 netns 里,配置 IP 地址;
- 在隔离的 netns 里,配置默认路由;
- 在隔离的 netns 里,配置网关的 ARP 表项;
- 在 host netns 里,使用 XDP 将从隔离的 netns 发出的 ping 包转发到真实的网关;
- 在 host netns 里,使用 XDP 将接收到的 ping 包转发到隔离的 netns;
- 在隔离的 netns 里,开启 veth GRO 用来接收 ping 包。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
NETNS="ns-ping"
VETH0="vpingh"
VETH1="vpingn"
IP="${1}"
MAC="${2}"
GW_IP="${3}"
GW_MAC="${4}"
ip netns add ${NETNS}
ip link add ${VETH0} type veth peer name ${VETH1}
ip link set ${VETH1} netns ${NETNS}
ip link set ${VETH0} up
ip netns exec ${NETNS} bash -c "
ip link set ${VETH1} address ${MAC}
ip link set ${VETH1} up
ip addr add ${IP}/24 dev ${VETH1}
ip route add default via ${GW_IP} dev ${VETH1}
ip neigh add ${GW_IP} dev ${VETH1} lladdr ${GW_MAC} nud permanent
ethtool -K ${VETH1} gro on
"
|
使用 XDP 转发 ping 包的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
#define PING_TCP_DPORT 10086
static const volatile u32 ETH_IFINDEX = 0;
static const volatile u32 VETH_IFINDEX = 0;
SEC("xdp")
int tx_ping(struct xdp_md *xdp)
{
return bpf_redirect(ETH_IFINDEX, 0);
}
SEC("xdp")
int rx_ping(struct xdp_md *xdp)
{
struct ethhdr *eth = ctx_ptr(xdp, data);
struct iphdr *iph = eth + 1;
struct tcphdr *tcph;
if ((void *) (iph + 1) > ctx_ptr(xdp, data_end))
return XDP_PASS;
if (iph->protocol != IPPROTO_TCP)
return XDP_PASS;
tcph = (void *) iph + iph->ihl << 2;
if ((void *) (tcph + 1) > ctx_ptr(xdp, data_end))
return XDP_PASS;
if (tcph->source != bpf_htons(PING_TCP_DPORT))
return XDP_PASS;
return bpf_redirect(VETH_IFINDEX, 0);
}
|
其中,tx_ping()
用来将 ping 包转发到物理网口,rx_ping()
用来将 ping 包转发到隔离的 netns。
最终,便能复用原有的基于 rawsocket 的收发 ping 包的代码逻辑了;只是在准备 rawsocket 的时候,需要进入到隔离的 netns 里。
小结
通过使用隔离的 netns,可以避免 iptables 规则干扰 ping 包的收发,从而更好地支持网关跟业务节点混部的场景。毕竟,还得继续降本增效嘛。