cni 添加网络 流程分析
cnitool: Add or remove network interfaces from a network namespace cnitool add <net> <netns>
cnitool del <net> <netns>
cnitool的使用方式如下:其中<net>是配置文件所在目录,一般为/etc/cni/net.d/*.conf文件,<netns>为network namespace的目录文件,一般为/var/run/netns/NS-ID
1、cni/libcni/api.go
// AddNetwork executes the plugin with ADD command
func (c *CNIConfig) AddNetwork(net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
(1)、首先调用pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path),该函数用于在c.Path中寻找对应插件的可执行文件,然后返回路径
(2)、调用 return invoke.ExecPluginWithResult(pluginPath, net.Bytes, c.args("ADD", rt)),net.Bytes是配置文件的序列化二进制码,其中c.args函数主要的作用是填充并返回一个*invoke.Args类型:
return &invoke.Args {
Command: action,
ContainerID: rt.ContainerID,
NetNS: rt.NetNS,
PluginArgs: rt.Args,
IfName: rt.IfName,
Path: strings.Join(c.Path, string(os.PathListSeparator)),
}
NetworkConfig的数据结构如下所示,用于表示容器要加入的网络:
// libcni/api.go
type NetworkConfig struct {
Network *types.NetConf
Bytes []byte // 在初始化CNI的时候,会将配置文件写入Bytes
} // pkg/types/types.go
// NetConf describes a network
type NetConf struct {
CNIVersion string
Name string
IPAM string {
Type string
}
DNS DNS
}
Runtime的数据结构如下所示,用于表示加入网络的容器的信息:
type RuntimeConf struct {
ContainerID string
NetNS string
IfName string
Args [][2]string
}
CNIConfig的数据结构如下所示:CNIconfig包含的是bridge,dhcp等插件的可执行文件的目录的路径集合
type CNIConfig struct {
Path []string
}
2、cni/pkg/invoke/exec.go
func ExecPluginWithResult(pluginPath string, netconf []byte, args CNIArgs) (types.Result, error)
该函数只是简单地返回 return defaultPluginExec.WithResult(pluginPath, netconf, args)
其中defaultPluginExec是一个*PluginExec的类型变量,赋值过程如下所示:
var defaultPluginExec = &PluginExec{
RawExec: &RawExec{Stderr: os.Stderr}, --->RawExec又是在raw_exec.go中定义的一个结构类型,其中只有一个Stderr的io.Writer类型
VersionDecoder: &version.PluginDecoder{},
}
// 其中PluginExec的定义如下所示:
type PluginExec struct {
RawExec interface {
ExecPlugin(pluginPath string, stdinData []byte, environ []string) ([]byte, error)
}
VersionDecoder interface {
Decode(jsonBytes []byte) (version.PluginInfo, error)
}
}
3、cni/pkg/invoke/exec.go
func (e *PluginExec) WithResult(pluginPath string, netconf []byte, args CNIArgs) (*types.Result, error)
(1)、调用stdoutBytes, err := e.RawExec.ExecPlugin(pluginPath, netconf, args.AsEnv()),args.AsEnv()将args里的内容转变为环境变量返回,例如CNI_COMMAND=ADD等等
// Plugin must return result in same version as specified in netconf
(2)、调用versionDecoder := &version.ConfigDecoder{}和confVersion, err := versionDecoder.Decode(netconf)从netconf中解析处CNI的版本
(3)、最后调用return version.NewResult(confVersion, stdoutBytes)返回相应版本的Result
4、cni/pkg/invoke/args.go
func (args *Args) AsEnv() []string
1、调用env := os.Environ()获取已有的环境变量
2、若args.PluginArgsStr为"",则将args.PluginArgs拼接为“A=B;C=D”的形式
3、调用env = append(env,
"CNI_COMMAND=" + args.Command,
"CNI_CONTAINERID=" + args.ContainerID,
"CNI_NETNS=" + args.NetNS,
"CNI_ARGS=" + pluginArgsStr,
"CNI_IFNAME=" + args.IfName,
"CNI_PATH="+args.Path)
),将参数都作为环境变量传递给plugin
RawExec的结构如下所示:
type RawExec struct {
Stderr io.Writer
}
5、cni/pkg/invoke/raw_exec.go
func (e *RawExec) ExecPlugin(pluginPath string, stdinData []byte, environ []string) ([]byte, error)
(1)、首先获得stdout := bytes.Buffer{}作为输出缓冲器
(2)、创建执行命令并调用c.Run()运行
c := exec.Cmd {
Env: environ,
Path: pluginPath,
Args: []string{pluginPath},
Stdin: bytes.NewBuffer(stdinData),
Stdout: stdout,
Stderr: e.Stderr,
}
(3)、最后返回stdout.Bytes(),插件直接将结果输出到stdout
cni 添加网络 流程分析的更多相关文章
- android添加账户流程分析涉及漏洞修复
android修复了添加账户代码中的2处bug,retme取了很酷炫的名字launchAnyWhere.broadAnywhere(参考资料1.2).本文顺着前辈的思路学习bug的原理和利用思路. 我 ...
- PPTP协议握手流程分析
一 PPTP概述 PPTP(Point to Point Tunneling Protocol),即点对点隧道协议.该协议是在PPP协议的基础上开发的一种新的增强型安全协议,支持多协议虚拟专用网,可 ...
- Netty 拆包粘包和服务启动流程分析
Netty 拆包粘包和服务启动流程分析 通过本章学习,笔者希望你能掌握EventLoopGroup的工作流程,ServerBootstrap的启动流程,ChannelPipeline是如何操作管理Ch ...
- 【转】Netty 拆包粘包和服务启动流程分析
原文:https://www.cnblogs.com/itdragon/archive/2018/01/29/8365694.html Netty 拆包粘包和服务启动流程分析 通过本章学习,笔者希望你 ...
- PPTP协议握手流程分析--转载
一 PPTP概述 PPTP(Point to Point Tunneling Protocol),即点对点隧道协议.该协议是在PPP协议的基础上开发的一种新的增强型安全协议,支持多协议虚拟专用网 ...
- CNI插件编写框架分析
概述 在<CNI, From A Developer's Perspective>一文中,我们已经对CNI有了较为深入的了解.我们知道,容器网络功能的实现最终是通过CNI插件来完成的.每个 ...
- elasticsearch indices.recovery 流程分析(索引的_open操作也会触发recovery)——主分片recovery主要是从translog里恢复之前未写完的index,副分片recovery主要是从主分片copy segment和translog来进行恢复
摘自:https://www.easyice.cn/archives/231 elasticsearch indices.recovery 流程分析与速度优化 目录 [隐藏] 主分片恢复流程 副本分片 ...
- VLC架构及流程分析
0x00 前置信息 VLC是一个非常庞大的工程,我从它的架构及流程入手进行分析,涉及到一些很细的概念先搁置一边,日后详细分析. 0x01 源码结构(Android Java相关的暂未分析) # bui ...
- Okhttp源码分析--基本使用流程分析
Okhttp源码分析--基本使用流程分析 一. 使用 同步请求 OkHttpClient okHttpClient=new OkHttpClient(); Request request=new Re ...
随机推荐
- CentOS修改服务器系统时间
linux安装完毕后,一般都是国外的世界,一点都不方便设置任务,或者导致网站获取本地的时间错乱,所以就需要把服务器的时间改为和本地时间一致,也就是换成中国的时间. 第一条指令:date –s '201 ...
- Java生成公私钥对
public static synchronized KeyPair generateRSAKeyPair(int keysize, BigInteger publicExponent) { try ...
- 怎样在win7系统配置数据源
1.点击桌面的我Windows 图标,找打控制面板 2.进入控制面板主页,选择系统和安全,进入系统和安全 3.进入系统和安全主页后选择管理工具,点击进入 4.进入管理工具后,选择数据源,进行数据源的配 ...
- [iOS] 使用xib作为应用程序入口 with IDE
[iOS] 使用xib作为应用程序入口 with IDE 在「使用xib做为应用程序入口 with Code」这篇文章中,介绍了如何透过写Code的方式,来使用xib做为应用程序的入口.但其实在Xco ...
- Crash日志符号化
1.符号化crash日志需要3样东西: 1).crash日志本身(如:example.crash),从Xcode的organizer导出或者来自Itunes Connect. 2).crash日志所对 ...
- DOM应用实例(寻找房祖名)
在上一篇我讲到了DOM的一些总结,这一次我就用我前几天做的一个游戏demo来讲讲DOM的一些用法吧. 首先简单说说这个游戏,如下图所示(大家忽略样式/(ㄒoㄒ)/~~).当玩家点击开始后,只要选择了正 ...
- Sharepoint 2013 开启App和配置App
在任何站点中,点Add App,然后点Sharepoint Store,如果没有Enable apps,打开app store的时候出出现错误: Sorry, apps are turned off. ...
- 招聘一个靠谱的 iOS程序员
一个靠谱的简历 简历非常能反映一个人的性格和水平,相比于你在学校获得多少奖项,工作经历.项目经 历.熟悉的技术等更加关键,如果还有博客和一些 Github 上的项目,好感度++,但记得在去面试前收拾下 ...
- 如何创建可扩展表视图中的iOS 学习和拓展优化(有待更新)
首先介绍老外的文章:<How To Create an Expandable Table View in iOS>这是老外用Swift实现 的,对应的老外github项目源码:https: ...
- IOS应用沙盒文件操作
iOS沙盒机制 iOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文本文件等. 1 ...