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插件的执行流程
最新文章
- Eclipse调试时附加匹配版本的JAR包源码:Edit Source Loopup
- C#使用DataSet Datatable更新数据库的三种实现方法
- mysql创建外键出错(注意数据库表字段排序)
- .net 调用C++类库
- 《Python基础教程(第二版)》学习笔记 ->; 第九章 魔法方法、属性和迭代器
- CocoaPods 安装和使用
- [Elasticsearch] 部分匹配 (一) - 前缀查询
- 疯狂java讲义--笔记
- ftok函数的使用
- Java.MyEclipse Web项目导入Eclipse
- python3之序列化(pickle&;json&;shelve)
- [Swift]LeetCode804. 唯一摩尔斯密码词 | Unique Morse Code Words
- 20175320 2018-2019-2 《Java程序设计》第6周学习总结
- YUV420序列转成图片
- 如何取得select结果数据集的前10条记录。postgresql
- html文件中jquery与velocity变量中的$冲突的解决方法
- Flask源码解析:Flask上下文
- 13 python 常用的内置方法介绍
- 使用sos查看.NET对象内存布局
- Django(出版社功能)
热门文章
- PHP7:10件事情你需要知道的
- 浏览器在线打开pdf
- FormatUtil类型格式转换
- root权限NPM全局安装(-g)仍会权限不够,认识下参数 --unsafe-perm
- redission计数器实现,redisTemplate计数器
- head管理EC下载,配置启动
- 64位系统下,一个32位的程序究竟可以申请到多少内存,4GB还是更多?(一)
- 【BZOJ】3314: [Usaco2013 Nov]Crowded Cows(单调队列)
- 《C++程序设计》朝花夕拾
- (转)Unity笔记之编辑器(BeginFadeGroup、BeginHorizontal、BeginScrollView) ... ...