有效的网站建设,住房建设部官方网站办事大厅,甘肃水利工程建设管理网站,织梦建站和WordPress建站的优缺点文章目录简介Ipvlan2同节点 Ns 互通Ns 内与宿主机 通信第三种方法Ns 到节点外部结论Ipvlan31. 同节点 Ns 互通Ns 内与宿主机 通信Ns 内到外部网络总结源码分析ipvlan 收包流程收包流程主要探讨使用 ipvlan 为 cni 通过虚拟网卡的实现。简介
ipvlan 和 macvlan 类似#xff0c…
文章目录简介Ipvlan2同节点 Ns 互通Ns 内与宿主机 通信第三种方法Ns 到节点外部结论Ipvlan31. 同节点 Ns 互通Ns 内与宿主机 通信Ns 内到外部网络总结源码分析ipvlan 收包流程收包流程主要探讨使用 ipvlan 为 cni 通过虚拟网卡的实现。简介
ipvlan 和 macvlan 类似都是从一个主机接口虚拟出多个虚拟网络接口。唯一比较大的区别就是 ipvlan 虚拟出的子接口都有相同的 mac地址与物理接口共用同个 mac 地址但可配置不同的 ip 地址。由于所有的虚拟接口共享同个mac地址因此有些地方需要注意当使用 DHCP 协议分配 ip 时一般会用 mac 地址作为机器的标识因此需要配置唯一的 ClientID 字段作为机器的标识 DHCP server 配置 ip 时需使用该字段作为机器标识而不是使用 mac 地址。
两种工作模式 ipvlan 有两种不同的工作模式L2 和 L3。一个父接口只能选择其中一种模式不能采用混用模式依附于它的所有虚拟接口都会运行在这个模式下。 1、L2 模式 Ipvlan 的 L2 模式和 macvlan 的 bridge 模式工作原理很相似父接口作为交换机来转发子接口的数据。同一个网络的子接口可以通过父接口来转发数据而如果想发送到其他网络报文则会通过父接口的路由转发出去。 2、L3 模式 L3 模式下ipvlan 有点像路由器的功能它在各个虚拟网络和主机网络之间进行不同网络报文的路由转发工作。只要父接口相同即使虚拟机/容器不在同一个网络也可以互相 ping 通对方因为 ipvlan 会在中间做报文的转发工作。该模式把宿主接口当成一个路由器完全不支持广播这个模式下的接口也比l2模式下的ipvlan接口多了一个 NOARP属性也不会发送广播报文
Ipvlan2
同节点 Ns 互通 // 创建 netns, 创建 ipvlannetns 内配置 iplink up配置路由
ip netns add node1ns
ip link add ipvl_10_1 link ens10 type ipvlan mode l2
ip link set ipvl_10_1 netns node1ns
ip netns exec node1ns ip link set ipvl_10_1 name eth0
ip netns exec node1ns ip a a 192.168.100.101/24 dev eth0
ip netns exec node1ns ip link set lo up
ip netns exec node1ns ip link set eth0 upip netns add node1ns2
ip link add ipvl_10_1 link ens10 type ipvlan mode l2
ip link set ipvl_10_1 netns node1ns2
ip netns exec node1ns2 ip link set ipvl_10_1 name eth0
ip netns exec node1ns2 ip a a 192.168.100.102/24 dev eth0
ip netns exec node1ns2 ip link set lo up
ip netns exec node1ns2 ip link set eth0 up// 到此两个 ns 的 ip 是互通的
192.168.100.101 -- 192.168.100.102 OKNs 内与宿主机 通信
因为要跟其他网段通信配置 ns 内的路由
//配置 ns 内部下一跳 192.168.100.1将 192.168.100.1/24 配置在 ens10 网卡上
ip netns exec node1ns ip r add default via 192.168.100.1
ip netns exec node1ns2 ip r add default via 192.168.100.1第一种方法
将 192.168.100.1/24 配置在 ens10 网卡上
ip a a 192.168.100.1/24 dev ens10192.168.100.101 -- 172.18.22.114 OK第二种方法
将 192.168.100.1/24 配置在 ens10 网卡上//在 宿主机上配置到 ns ip 的 路由
ip link add ipvl_10 link ens10 type ipvlan mode l2
ip link set ipvl_10 up
ip a a 192.168.100.1/32 dev ipvl_10
ip route add 192.168.100.101/32 dev ipvl_10
ip route add 192.168.100.102/32 dev ipvl_10第三种方法 // 在 ns 中配置宿主机 ip 的路由
ip netns exec node1ns ip r add 172.18.22.0/24 dev eth0
ip netns exec node1ns2 ip r add 172.18.22.0/24 dev eth0ens10 不配置 ip在 ipvl_10 配置 宿主机的 ip
ip a a 172.18.22.114/32 dev ipvl_10Ns 到节点外部
上面第一种和第二种将 ns 内部下一跳 ip 放到网卡上的情况会匹配宿主机路由从 ens3 出需要配置 snat。
$ iptables -t nat -A POSTROUTING -s 192.168.100.101/24 -j SNAT --to 172.18.22.114上面第三种ns 内部下一跳 ip 在宿主机外部的情况会直接从 ens10 出。
结论
保证业务流量走业务网卡使用第三种方法实现 host 到 ns 的通信将 需要通信的 host IP 配置到 业务网卡上其他流量默认从业务网卡出。
Ipvlan3
1. 同节点 Ns 互通 // 创建 netns, 创建 ipvlannetns 内配置 iplink up配置路由
ip netns add node2ns
ip link add ipvl_10_1 link ens10 type ipvlan mode l3
ip link set ipvl_10_1 netns node2ns
ip netns exec node2ns ip link set ipvl_10_1 name eth0
ip netns exec node2ns ip a a 192.168.100.201/24 dev eth0
ip netns exec node2ns ip link set lo up
ip netns exec node2ns ip link set eth0 up
ip netns exec node2ns ip r add default dev eth0ip netns add node2ns2
ip link add ipvl_10_1 link ens10 type ipvlan mode l2
ip link set ipvl_10_1 netns node2ns2
ip netns exec node2ns2 ip link set ipvl_10_1 name eth0
ip netns exec node2ns2 ip a a 192.168.200.201/24 dev eth0
ip netns exec node2ns2 ip link set lo up
ip netns exec node2ns2 ip link set eth0 up
ip netns exec node2ns2 ip r add default dev eth0// 到此两个 ns 的 ip 是互通的
192.168.100.201 -- 192.168.200.201 OKNs 内与宿主机 通信 // 宿主机起 ipvl_10配置需要访问的宿主机 ip设置到 ns 的路由
ip link add ipvl_10 link ens10 type ipvlan mode l3
ip a a 172.18.22.115/32 dev ipvl_10
ip r add 192.168.100.201 dev ipvl_10
ip r add 192.168.200.201 dev ipvl_10192.168.100.201 -- 172.18.22.115Ns 内到外部网络
需要为 ens10 配置 ip默认从 ens10 发出 外部回包时需要内部网络的路由
总结
l3 mode 的 ipvlan 网卡 NOARP不回复 arp 报文如果外部流量访问 ipvlan 上的 ip需要在 ens10 配置 ip然后外部配置到 ipvlan ip 的流量下一跳到 ens10 的 ip。
源码分析
ipvlan 收包流程
ipvlan_netdev_ops 中 收包函数 ipvlan_start_xmit
int ipvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
{struct ipvl_dev *ipvlan netdev_priv(dev);struct ipvl_port *port ipvlan_port_get_rcu_bh(ipvlan-phy_dev);if (!port)goto out;
...
// 获取 端口模式L2L3 或 L3S进行对应处理switch(port-mode) {case IPVLAN_MODE_L2:return ipvlan_xmit_mode_l2(skb, dev);case IPVLAN_MODE_L3:
#ifdef CONFIG_IPVLAN_L3Scase IPVLAN_MODE_L3S:
#endifreturn ipvlan_xmit_mode_l3(skb, dev);}
...
}L2 mode 收包
static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
{const struct ipvl_dev *ipvlan netdev_priv(dev);struct ethhdr *eth skb_eth_hdr(skb);struct ipvl_addr *addr;void *lyr3h;int addr_type;// 非 vepa 且源 mac 目的 mac 相等获取三层头指针和类型ipv4arpif (!ipvlan_is_vepa(ipvlan-port) ether_addr_equal(eth-h_dest, eth-h_source)) {lyr3h ipvlan_get_L3_hdr(ipvlan-port, skb, addr_type);if (lyr3h) {// 找到目的地址addr ipvlan_addr_lookup(ipvlan-port, lyr3h, addr_type, true);if (addr) {// ipvlan 如果是 private 则 drop。if (ipvlan_is_private(ipvlan-port)) {consume_skb(skb);return NET_XMIT_DROP;}// ipvlan 虚拟接口收包改 skb type 为 local使用该目的地址的接口收包。如 1 中 netns 互通和 2 中 第三种方法。return ipvlan_rcv_frame(addr, skb, true);}}
.../* Packet definitely does not belong to any of the* virtual devices, but the dest is local. So forward* the skb for the main-dev. At the RX side we just return* RX_PASS for it to be processed further on the stack.*/// 目的地址不是虚拟接口里的直接物理口收包接下来会进协议栈。如 2 中 netns 到 host 的第一二种方法。return dev_forward_skb(ipvlan-phy_dev, skb);// 多播包虚拟接口处理} else if (is_multicast_ether_addr(eth-h_dest)) {skb_reset_mac_header(skb);ipvlan_skb_crossing_ns(skb, NULL);ipvlan_multicast_enqueue(ipvlan-port, skb, true);return NET_XMIT_SUCCESS;}// 源目的 mac 不同且不是多播包直接物理网卡发出。skb-dev ipvlan-phy_dev;return dev_queue_xmit(skb);
}L3 mode 收包L3 和 L3S 相同和 L2 Mode 很像
static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev)
{const struct ipvl_dev *ipvlan netdev_priv(dev);void *lyr3h;struct ipvl_addr *addr;int addr_type;lyr3h ipvlan_get_L3_hdr(ipvlan-port, skb, addr_type);if (!lyr3h)goto out;if (!ipvlan_is_vepa(ipvlan-port)) {addr ipvlan_addr_lookup(ipvlan-port, lyr3h, addr_type, true);if (addr) {// ip 或 arp 三层包且目的地址是虚拟接口的目的地址的虚拟接口收包、if (ipvlan_is_private(ipvlan-port)) {consume_skb(skb);return NET_XMIT_DROP;}return ipvlan_rcv_frame(addr, skb, true);}}
out:// 目的地址不是本网卡接口交给物理口ip_route_output_flow查找路由表走三层转发。ipvlan_skb_crossing_ns(skb, ipvlan-phy_dev);return ipvlan_process_outbound(skb);
}收包流程
ipvlan 收包流程 物理卡收包后的处理分配区分 L2L3L3S mode
rx_handler_result_t ipvlan_handle_frame(struct sk_buff **pskb)
{struct sk_buff *skb *pskb;struct ipvl_port *port ipvlan_port_get_rcu(skb-dev);if (!port)return RX_HANDLER_PASS;switch (port-mode) {case IPVLAN_MODE_L2:return ipvlan_handle_mode_l2(pskb, port);case IPVLAN_MODE_L3:return ipvlan_handle_mode_l3(pskb, port);
#ifdef CONFIG_IPVLAN_L3Scase IPVLAN_MODE_L3S:return RX_HANDLER_PASS;
#endif}/* Should not reach here */WARN_ONCE(true, %s called for mode [%x]\n, __func__, port-mode);kfree_skb(skb);return RX_HANDLER_CONSUMED;
}L2 mode 收包
static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb,struct ipvl_port *port)
{struct sk_buff *skb *pskb;struct ethhdr *eth eth_hdr(skb);rx_handler_result_t ret RX_HANDLER_PASS;// 多播包ipvlan_external_frame 判断如果是本地子接口发的包且目的 ip 不是本物理网卡和子接口的 ip复制一份直接物理网卡的多播队列处理。if (is_multicast_ether_addr(eth-h_dest)) {if (ipvlan_external_frame(skb, port)) {struct sk_buff *nskb skb_clone(skb, GFP_ATOMIC);/* External frames are queued for device local* distribution, but a copy is given to master* straight away to avoid sending duplicates later* when work-queue processes this frame. This is* achieved by returning RX_HANDLER_PASS.*/if (nskb) {ipvlan_skb_crossing_ns(nskb, NULL);ipvlan_multicast_enqueue(port, nskb, false);}}} else {// 单播报文和 l3 mode 处理方法一致/* Perform like l3 mode for non-multicast packet */ret ipvlan_handle_mode_l3(pskb, port);}return ret;
}L3 mode 收包该模式同样适合 l2 mode 的单播包
static rx_handler_result_t ipvlan_handle_mode_l3(struct sk_buff **pskb,struct ipvl_port *port)
{void *lyr3h;int addr_type;struct ipvl_addr *addr;struct sk_buff *skb *pskb;rx_handler_result_t ret RX_HANDLER_PASS;lyr3h ipvlan_get_L3_hdr(port, skb, addr_type);if (!lyr3h)goto out;addr ipvlan_addr_lookup(port, lyr3h, addr_type, true);if (addr)// arp 或 ip 包且目的地址是本网卡和子接口的对应接口收包ret ipvlan_rcv_frame(addr, pskb, false);out:// 其他报文走物理网卡路由return ret;
}L3S mode case IPVLAN_MODE_L3S:return RX_HANDLER_PASS;直接走物理卡主机路由