zdq0394.github.com

Tech study and research.

Follow me on GitHub

Flannel VxLAN

VxLan 原理

Flanneld 源码分析Flannel HostGW源码分析两节中已经详细分析了network的主流程。 对于不同backend的network来说,就是对event事件的处理方式不同。VxLan Backedn也是如此。

  • EventAdded
    • 增加ARP:nw.dev.AddARP
    • 增加FDB:nw.dev.AddFDB
    • 增加Route:netlink.RouteReplace
  • EventRemoved
    • 删除ARP:nw.dev.DelARP
    • 删除FDB:nw.dev.DelFDB
    • 删除Route:netlink.RouteDel

针对Vxlan的实现原理,可以参考:vxlan

VxLan Backend

VxLanBackend的RegisterNetwork方法如下:

	devAttrs := vxlanDeviceAttrs{
		vni:       uint32(cfg.VNI),
		name:      fmt.Sprintf("flannel.%v", cfg.VNI),
		vtepIndex: be.extIface.Iface.Index,
		vtepAddr:  be.extIface.IfaceAddr,
		vtepPort:  cfg.Port,
		gbp:       cfg.GBP,
		learning:  cfg.Learning,
	}

	dev, err := newVXLANDevice(&devAttrs)
	if err != nil {
		return nil, err
	}
	dev.directRouting = cfg.DirectRouting

	subnetAttrs, err := newSubnetAttrs(be.extIface.ExtAddr, dev.MACAddr())
	if err != nil {
		return nil, err
	}
  1. 根据Subnet配置生成必要的vxlanDeviceAttributes:
  • vni默认值为1
  • vxlan设备名字:flannel.1 等,
  1. 调用newVXLANDevice方法在Node节点上创建VxLan设备,并以extIface为基础设备。
  2. 第二步骤执行完之后,vxlan设备的mac地址就有了。然后生成subnetAttrs,这个信息会在AcquireLease方法中存储到kube/etcd中。
	data, err := json.Marshal(&vxlanLeaseAttrs{hardwareAddr(mac)})
	if err != nil {
		return nil, err
	}

	return &subnet.LeaseAttrs{
		PublicIP:    ip.FromIP(publicIP),
		BackendType: "vxlan",
		BackendData: json.RawMessage(data),
	}, nil
  1. 给VxLan设备配置IP地址:

IP地址为:ip.IP4Net{IP: lease.Subnet.IP, PrefixLen: 32}。 比如整个flannel的网络为192.169.0.0/16,当前node分配的subnet为192.169.1.0/24,那么vxlan设备分配的地址就是192.169.1.0/32

  1. 创建network:
return newNetwork(be.subnetMgr, be.extIface, dev, ip.IP4Net{}, lease)

参数分别为:

  • subnetmanager
  • 物理设备
  • vxlan设备
  • 空的IP
  • 节点信息lease
    func newNetwork(subnetMgr subnet.Manager, extIface *backend.ExternalInterface, dev *vxlanDevice, _ ip.IP4Net, lease *subnet.Lease) (*network, error) {
      nw := &network{
          SimpleNetwork: backend.SimpleNetwork{
              SubnetLease: lease,
              ExtIface:    extIface,
          },
          subnetMgr: subnetMgr,
          dev:       dev,
      }
    
      return nw, nil
    }
    

    VxLan Network

    type network struct {
      backend.SimpleNetwork
      dev       *vxlanDevice
      subnetMgr subnet.Manager
    }
    
  • dev:指虚拟出来的VxLan设备,比如flannel.1。

对于vxlan network的MTU则定义:

func (nw *network) MTU() int {
	return nw.ExtIface.Iface.MTU - encapOverhead
}

其中encapOverhead=50,及MTU=ExternalInterface的MTU-50,默认为1500-50=1450。

重点分析handleSubnetEvents(batch []subnet.Event)方法:

  1. 生成Remote node的路由。
         sn := event.Lease.Subnet
         ...
         vxlanRoute := netlink.Route{
             LinkIndex: nw.dev.link.Attrs().Index,
             Scope:     netlink.SCOPE_UNIVERSE,
             Dst:       sn.ToIPNet(),
             Gw:        sn.IP.ToIP(),
         }
    
    • 设备:当前node的vxlan设备——flannel.1,此处用的是Index指定。
    • 目的地址:对端subnet的IP网络地址,比如192.169.2.0/24
    • 网关地址:对端subnet的IP网关地址,比如192.169.2.0

EventAdded事件:

  1. nw.dev.AddARP(neighbor{IP: sn.IP, MAC: net.HardwareAddr(vxlanAttrs.VtepMAC)})

增加ARP:增加remote node上vxlan设备的IP地址和MAC地址对应关系到本机ARP表 192.169.2.0/32->MAC地址(192.169.2.0)

  1. nw.dev.AddFDB(neighbor{IP: attrs.PublicIP, MAC: net.HardwareAddr(vxlanAttrs.VtepMAC)})

增加FDB:增加remote node上vxlan设备的mac地址的下一跳。 MAC地址(192.169.2.0)-> publicIP vtep地址

  1. netlink.RouteReplace(&vxlanRoute) 增加路由信息

EventRemoved事件:

将EventAdded中三个步骤增加的信息删除。