zoukankan      html  css  js  c++  java
  • CNI插件实现框架---以loopback为示例

    以最简单的loopback插件作为实例,来分析CNI plugin的执行流程

    // cni/plugins/loopback/loopback.go

    1、func main()

    main函数只是简单地调用skel.PluginMain(cmdAdd, cmdDel, version.All),注册插件中的插入和删除方法

    // cni/pkg/skel/skel.go
    
    // PluginMain is the core "main" for a plugin which includes automatic error handling.
    
    // The caller must also specify what CNI spec versions the plugin supports.
    
    // When an error occurs in either cmdAdd or cmdDel, PluginMain will print the error
    
    // as JSON to stdout and call os.Exit(1).
    
    // To have more control over error handling, use PluginMainWithErro() instead.
    

    2、func PluginMain(cmdAdd, cmdDel func(_ *CmdArgs) error, versionInfo version.PluginInfo)

    该函数仅仅调用e := PluginMainWithError(cmdAdd, cmdDel, versionInfo)

    若e不为nil,调用e.Print()并os.Exit()

    // cni/pkg/skel/skel.go

    3、func PluginMainWithError(cmdAdd, cmdDel func(_ *CmdArgs) error, versionInfo version.PluginInfo) *types.Error

    该函数仅仅调用return (&dispatcher{

        Getenv:  os.Getenv,

        Stdin:   os.Stdin,

        Stdout:   os.Stdout,

        Stderr:   os.Stderr,

    }).pluginMain(cmdAdd, cmdDel, versionInfo)

    dispatcher 结构如下所示:

    type dispatcher struct {
      Getenv   func(string) string
      Stdin:   io.Reader
      Stdout:   io.Write
      Stderr:    io.Write
    
      ConfVersionDecoder  version.ConfigDecoder
      VersionReconciler    version.Reconciler
    }

    // cni/pkg/skel/skel.go

    4、func (t *dispatcher) pluginMain(cmdAdd, cmdDel func(_ *CmdArgs) error, versionInfo version.PluginInfo) *types.Error

    1、先调用cmd, cmdArgs, err := t.getCmdArgsFromEnv()解析出,操作指令(ADD ,DEL或者VERSION),和操作参数

    2、再根据不同的cmd,调用相关的函数。对于"ADD",调用t.checkVersionAndCall(cmdArgs, versionInfo, cmdAdd)

    // cni/pkg/skel/skel.go

    5、func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, error)

    该函数从环境变量和stdin中提取信息,填充数据结构CmdArgs,如下所示:

    cmdArgs := &CmdArgs{
      ContainerID:    contID,
      Netns:        netns,
      IfName:       ifName,
      Args:        args,
      Path:        path,
      StdinData:     stdinData,    // StdinData中的数据其实是network配置
    }
    

      

    // cni/pkg/skel/skel.go

    6、func (t *dispatcher) checkVersionAndCall(cmdArgs *CmdArgs, pluginVersionInfo version.PluginInfo, toCall func(*CmdArgs) error) error

    1、调用confiVersion, err := t.ConfVersionDecoder.Decode(cmdArgs.StdinData)获取网络配置中的版本

    2、调用verErr := t.VersionReconciler.Check(configVersion, pluginVersionInfo)

    3、最后调用return toCall(cmdArgs)

    // cni/plugins/loopback/loopback.go

    7、func cmdAdd(args *skel.CmdArgs) error

    1、因为loopback比较特殊,因此直接忽略args,设置args.IfName = "lo"

    2、调用ns.WithNetNSPath(args.Netns, do func(_ ns.NetNS) error),在args指定的net ns中执行函数do

    3、loopback比较简单,net ns中的执行函数只是调用link, err := netlink.LinkByName(args.IfName)找到lo设备,再调用netlink.LinkSetUp(link)启动而已

    4、调用result := current.Result{}并return result.Print()

    综上完成CNI插件的执行流程

  • 相关阅读:
    (转)Dockerfile安全介绍
    (转)浅析Docker运行安全
    (转)网络安全设备默认密码
    docker kali 相关初始化工作
    hibernate(结合springboot)入门
    idea 通过 Generate POJOs.groovy 生成实体类
    linux jdk 安装
    docker pstgres安装
    使用docker搭建FastDFS文件系统
    [docker]离线环境导入镜像
  • 原文地址:https://www.cnblogs.com/YaoDD/p/6410725.html
Copyright © 2011-2022 走看看