calico overlay方案pod跨主机通信 -- 待更新

pod发出的包经过pod内的网卡,到达主机上的calixxx,经过tunl0封装后从主机网卡出去。
到达目的主机后,经过tunl0解封装到达主机的calixxx,再转发到pod内的网卡。

pod跨主机通信流程图

跨主机通信.png

深入整个流程,涉及到至少图中的6个步骤,eth0,cali1,tunl0,bond0等4个网络设备。有很多困扰的地方,针对如下问题,我们挨个探究一下

  • pod的eth0和主机上的cali1是一个网卡地址对,是如何实现跨命名空间通信的
  • 从cali1出来的包是如何到达tunl0的
  • tunl0做了什么事情
  • 包是如何从tunl0达到bond0的
  • 从容器出来的包的mac是何时被去掉,再进入ipip封包的

veth跨命名空间通信

https://www.jianshu.com/writer#/notebooks/50168089/notes/88915523

tunl0 的 封包处理

从veth中的peerdev进入协议栈后(ip_rcv),经过查找路由和出接口,经过prerouting后开始沿着forward -> postrouting转发包,进入到了tunl0的发送函数中(数据包将由三层转为二层)。


image.png

代码调用关系 :
ip_route_input_slow -> fib_lookup -> ip_mkroute_input -> __mkroute_input -> rth->dst.input=ip_forward, rt->dst.output=ip_output,再调用dst_input 函数,dst_output,最后出三层协议的是ip_finish_output2,调用neigh_output -> neigh_resolve_ouput -> dev_queue_xmit -> dev_hard_start_xmit -> __netdev_start_xmit,最终调用到ipip模块的ipip_tunnel_xmit。

接下来是tunnel的处理。
ipip_tunnel_xmit -> ip_tunnel_xmit -> ip_tunnel_encap -> iptunnel_xmit -> ip_local_output(相当于组装成一个数据包,重新在output链上再次进入协议栈)

内核ipip模块

tunl0 是modprobe ipip模块是创建的。

file   net/ipv4/ipip.c
static struct xfrm_tunnel ipip_handler __read_mostly = { 
     .handler = ipip_rcv,          // ipip tunl 收包
}

static const struct net_device_ops ipip_netdev_ops = {
    .ndo_init       = ipip_tunnel_init,
    .ndo_uninit     = ip_tunnel_uninit,
        // 发包
    .ndo_start_xmit = ipip_tunnel_xmit,
        // ioctl
    .ndo_do_ioctl   = ipip_tunnel_ioctl,
    .ndo_change_mtu = ip_tunnel_change_mtu,
    .ndo_get_stats64 = ip_tunnel_get_stats64,
    .ndo_get_iflink = ip_tunnel_get_iflink,
};

你可能感兴趣的:(calico overlay方案pod跨主机通信 -- 待更新)