searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Calico中的IPIP工作模式

2025-03-28 06:19:40
3
0

 1 介绍

Calico 是一个强大的 Kubernetes CNI(容器网络接口)插件,它支持多种网络模式,包括直接路由(BGP)和封装模式(IPIP 或 VXLAN)。
在云上IPIP是常见的一种使用方式。Calico 支持几种 IPIP 模式,可以通过 IP 池的配置(ipipMode)来控制:
  • Always(始终使用):所有跨主机的 Pod 通信都使用 IPIP 封装,即使主机在同一子网内。
  • CrossSubnet(跨子网使用):仅当源主机和目标主机位于不同子网时使用 IPIP 封装;同一子网内的通信直接路由,不封装。
  • Never(从不使用):禁用 IPIP,完全依赖底层网络的路由能力(通常需要 BGP 或静态路由支持)。
 
部署Calico+IPIP模式之后,可以看到只有一个IPIP隧道接口tun0。IPIP是如何确定其他节点的remote-ip并与其节点通信?

2 NBMA模式

在Linux的IPIP实现中,隧道分为两种:
  • 点对点(Point-to-Point)隧道:通过 ip tunnel add 指定了 remote IP,数据包直接发送到该地址。
  • NBMA 隧道:没有指定 remote IP(或为 0.0.0.0),需要通过路由表决定数据包的下一跳。
Calico使用了NBMA隧道。
 
NBMA(Non-Broadcast Multi-Access,非广播多址访问)隧道模式是一种特殊的隧道配置方式,它不依赖广播,而是通过显式配置路由来决定数据包的发送目标。在 IPIP 中,NBMA 模式通常表现为没有指定 remote IP的隧道(默认设备为 tunl0),或者通过路由表指定多个可能的下一跳IP
 
配置举例:

ip tunnel add tunl0 mode ipip
ip route add 10.0.0.0/24 via 192.168.1.1 dev tunl0 onlink

在这里,tunl0 是一个 NBMA 隧道,数据包的目标由路由表中的下一跳(192.168.1.1)决定。

3  IPIP NBMA简单分析

隧道设备初始化
 
ipip.c 中,ipip_init_net 函数初始化网络命名空间中的 IPIP 设备:
static int ipip_init_net(struct net *net)
{
    // 创建默认设备 tunl0
    return ip_tunnel_init_net(net, ipip_net_id, &ipip_link_ops, "tunl0");
}
  • tunl0 是默认的 NBMA 设备,remotelocal IP初始为 0.0.0.0
  • 用户可以通过 ip tunnel add 创建自定义 NBMA 隧道。
数据包发送:
void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
		    const struct iphdr *tnl_params, u8 protocol)
{
       ...

	inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
	connected = (tunnel->parms.iph.daddr != 0);

	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));

	dst = tnl_params->daddr;
 	// remote IP为0.0.0.0的情况下,认为是NBMA隧道,从路由中取到路由下一跳地址作为remote IP
	if (dst == 0) {
		/* NBMA tunnel */
		struct ip_tunnel_info *tun_info;

		if (!skb_dst(skb)) {
			dev->stats.tx_fifo_errors++;
			goto tx_error;
		}

		tun_info = skb_tunnel_info(skb);
		if (tun_info && (tun_info->mode & IP_TUNNEL_INFO_TX) &&
		    ip_tunnel_info_af(tun_info) == AF_INET &&
		    tun_info->key.u.ipv4.dst)
			dst = tun_info->key.u.ipv4.dst;
		else if (skb->protocol == htons(ETH_P_IP)) {
			rt = skb_rtable(skb);
			dst = rt_nexthop(rt, inner_iph->daddr);
		}
           ...
 
NBMA 模式的运行流程
  1. 发送端
    • 用户发送数据包到 NBMA 隧道设备( tunl0)。
    • 如果 remote 未指定,内核查询路由表获取下一跳。
    • 数据包被封装,外层 IP 头使用本地地址(local)和路由表中的下一跳地址。
    • 封装后的数据包通过底层网络接口发送。
  2. 接收端
    • 接收到封装数据包后,内核根据外层 IP 头查找匹配的隧道设备。
    • 如果找到( tunl0),解封装内层数据包并转发到协议栈。
 
 


0条评论
作者已关闭评论
c****w
3文章数
0粉丝数
c****w
3 文章 | 0 粉丝
c****w
3文章数
0粉丝数
c****w
3 文章 | 0 粉丝
原创

Calico中的IPIP工作模式

2025-03-28 06:19:40
3
0

 1 介绍

Calico 是一个强大的 Kubernetes CNI(容器网络接口)插件,它支持多种网络模式,包括直接路由(BGP)和封装模式(IPIP 或 VXLAN)。
在云上IPIP是常见的一种使用方式。Calico 支持几种 IPIP 模式,可以通过 IP 池的配置(ipipMode)来控制:
  • Always(始终使用):所有跨主机的 Pod 通信都使用 IPIP 封装,即使主机在同一子网内。
  • CrossSubnet(跨子网使用):仅当源主机和目标主机位于不同子网时使用 IPIP 封装;同一子网内的通信直接路由,不封装。
  • Never(从不使用):禁用 IPIP,完全依赖底层网络的路由能力(通常需要 BGP 或静态路由支持)。
 
部署Calico+IPIP模式之后,可以看到只有一个IPIP隧道接口tun0。IPIP是如何确定其他节点的remote-ip并与其节点通信?

2 NBMA模式

在Linux的IPIP实现中,隧道分为两种:
  • 点对点(Point-to-Point)隧道:通过 ip tunnel add 指定了 remote IP,数据包直接发送到该地址。
  • NBMA 隧道:没有指定 remote IP(或为 0.0.0.0),需要通过路由表决定数据包的下一跳。
Calico使用了NBMA隧道。
 
NBMA(Non-Broadcast Multi-Access,非广播多址访问)隧道模式是一种特殊的隧道配置方式,它不依赖广播,而是通过显式配置路由来决定数据包的发送目标。在 IPIP 中,NBMA 模式通常表现为没有指定 remote IP的隧道(默认设备为 tunl0),或者通过路由表指定多个可能的下一跳IP
 
配置举例:

ip tunnel add tunl0 mode ipip
ip route add 10.0.0.0/24 via 192.168.1.1 dev tunl0 onlink

在这里,tunl0 是一个 NBMA 隧道,数据包的目标由路由表中的下一跳(192.168.1.1)决定。

3  IPIP NBMA简单分析

隧道设备初始化
 
ipip.c 中,ipip_init_net 函数初始化网络命名空间中的 IPIP 设备:
static int ipip_init_net(struct net *net)
{
    // 创建默认设备 tunl0
    return ip_tunnel_init_net(net, ipip_net_id, &ipip_link_ops, "tunl0");
}
  • tunl0 是默认的 NBMA 设备,remotelocal IP初始为 0.0.0.0
  • 用户可以通过 ip tunnel add 创建自定义 NBMA 隧道。
数据包发送:
void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
		    const struct iphdr *tnl_params, u8 protocol)
{
       ...

	inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
	connected = (tunnel->parms.iph.daddr != 0);

	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));

	dst = tnl_params->daddr;
 	// remote IP为0.0.0.0的情况下,认为是NBMA隧道,从路由中取到路由下一跳地址作为remote IP
	if (dst == 0) {
		/* NBMA tunnel */
		struct ip_tunnel_info *tun_info;

		if (!skb_dst(skb)) {
			dev->stats.tx_fifo_errors++;
			goto tx_error;
		}

		tun_info = skb_tunnel_info(skb);
		if (tun_info && (tun_info->mode & IP_TUNNEL_INFO_TX) &&
		    ip_tunnel_info_af(tun_info) == AF_INET &&
		    tun_info->key.u.ipv4.dst)
			dst = tun_info->key.u.ipv4.dst;
		else if (skb->protocol == htons(ETH_P_IP)) {
			rt = skb_rtable(skb);
			dst = rt_nexthop(rt, inner_iph->daddr);
		}
           ...
 
NBMA 模式的运行流程
  1. 发送端
    • 用户发送数据包到 NBMA 隧道设备( tunl0)。
    • 如果 remote 未指定,内核查询路由表获取下一跳。
    • 数据包被封装,外层 IP 头使用本地地址(local)和路由表中的下一跳地址。
    • 封装后的数据包通过底层网络接口发送。
  2. 接收端
    • 接收到封装数据包后,内核根据外层 IP 头查找匹配的隧道设备。
    • 如果找到( tunl0),解封装内层数据包并转发到协议栈。
 
 


文章来自个人专栏
文章 | 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0