CNI flannel插件

// plugins/meta/flannel/flannel.go

func cmdAdd(args *skel.CmdArgs) error

  • 调用n, err := loadFlannelNetConf(args.StdinData)读取网络配置
  • 调用fenv, err := loadFlannelSubnetEnv(n.SubnetFile)读取flannel的配置结果
  • 确定n.Delegate["name"],n.Delegate["type"],n.Delegate["ipMasq"],n.Delegate["mtu"],n.Delegate["ipam"]等字段
  • 调用return delegateAdd(args.ContainerID, n.DataDir, n.Delegate)

NetConf的结构如下所示:

type NetConf struct {
  types.NetConf
  SubnetFile  string
  DataDir    string
  Delegate   map[string]interface{}
}

  

// plugins/meta/flannel/flannel.go

func loadFlannelNetConf(bytes []byte) (*NetConf, error)

  • 创建n := &NetConf{}其中设置SubnetFile为默认的defaultSubnetFile = /run/flannel/subent.env,defaultDataDir = /var/lib/cni/flannel
  • 再调用json.Unmarshal(bytes, n)将配置解析至n中

// plugins/meta/flannel/flannel.go

func loadFlannelSubnetEnv(fn string) (*subnetEnv, error)

  • 调用f, err := os.Open(fn)打开subnet file
  • 创建变量 se := &subnetEnv{},遍历subnet file从中提取FLANNEL_NETWORK, FLANNEL_SUBNET, FLANNEL_MTU, FLANNEL_IPMASQ填充至se中
  • 调用se.missing(),如果se中有任何一个字段为空则报错

// plugins/meta/flannel/flannel.go

func delegateAdd(cid, dataDir string, netconf map[string]interface{})

  • 调用netconfBytes, err := json.Marshal(netconf)
  • 再调用saveScratchNetConf(cid, dataDir, netconfBytes) ---> 创建目录dataDir,并且将netconf写入,当删除网络时,会从该目录读取配置
  • 接着调用result, err := invoke.DelegateAdd(netconf["type"].(string), netconfBytes),调用相应的插件,例如bridge
  • 最后调用return result.Print()
原文地址:https://www.cnblogs.com/YaoDD/p/6635633.html