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 添加网络 流程分析的更多相关文章

  1. android添加账户流程分析涉及漏洞修复

    android修复了添加账户代码中的2处bug,retme取了很酷炫的名字launchAnyWhere.broadAnywhere(参考资料1.2).本文顺着前辈的思路学习bug的原理和利用思路. 我 ...

  2. PPTP协议握手流程分析

    一  PPTP概述 PPTP(Point to Point Tunneling Protocol),即点对点隧道协议.该协议是在PPP协议的基础上开发的一种新的增强型安全协议,支持多协议虚拟专用网,可 ...

  3. Netty 拆包粘包和服务启动流程分析

    Netty 拆包粘包和服务启动流程分析 通过本章学习,笔者希望你能掌握EventLoopGroup的工作流程,ServerBootstrap的启动流程,ChannelPipeline是如何操作管理Ch ...

  4. 【转】Netty 拆包粘包和服务启动流程分析

    原文:https://www.cnblogs.com/itdragon/archive/2018/01/29/8365694.html Netty 拆包粘包和服务启动流程分析 通过本章学习,笔者希望你 ...

  5. PPTP协议握手流程分析--转载

    一  PPTP概述   PPTP(Point to Point Tunneling Protocol),即点对点隧道协议.该协议是在PPP协议的基础上开发的一种新的增强型安全协议,支持多协议虚拟专用网 ...

  6. CNI插件编写框架分析

    概述 在<CNI, From A Developer's Perspective>一文中,我们已经对CNI有了较为深入的了解.我们知道,容器网络功能的实现最终是通过CNI插件来完成的.每个 ...

  7. elasticsearch indices.recovery 流程分析(索引的_open操作也会触发recovery)——主分片recovery主要是从translog里恢复之前未写完的index,副分片recovery主要是从主分片copy segment和translog来进行恢复

    摘自:https://www.easyice.cn/archives/231 elasticsearch indices.recovery 流程分析与速度优化 目录 [隐藏] 主分片恢复流程 副本分片 ...

  8. VLC架构及流程分析

    0x00 前置信息 VLC是一个非常庞大的工程,我从它的架构及流程入手进行分析,涉及到一些很细的概念先搁置一边,日后详细分析. 0x01 源码结构(Android Java相关的暂未分析) # bui ...

  9. Okhttp源码分析--基本使用流程分析

    Okhttp源码分析--基本使用流程分析 一. 使用 同步请求 OkHttpClient okHttpClient=new OkHttpClient(); Request request=new Re ...

随机推荐

  1. 重新想象 Windows 8 Store Apps (41) - 打印

    [源码下载] 重新想象 Windows 8 Store Apps (41) - 打印 作者:webabcd 介绍重新想象 Windows 8 Store Apps 之 打印 示例1.需要打印的文档Pr ...

  2. learning sql (second edition) script

    create database bank; use bank; /* begin table creation */ create table department (dept_id smallint ...

  3. JavaMail入门第五篇 解析邮件

    上一篇JavaMail入门第四篇 接收邮件中,控制台打印出的内容,我们无法阅读,其实,让我们自己来解析一封复杂的邮件是很不容易的,邮件里面格式.规范复杂得很.不过,我们所用的浏览器内置了解析各种数据类 ...

  4. 泛函编程(19)-泛函库设计-Parallelism In Action

    上节我们讨论了并行运算组件库的基础设计,实现了并行运算最基本的功能:创建新的线程并提交一个任务异步执行.并行运算类型的基本表达形式如下: import java.util.concurrent._ o ...

  5. ajax onblur 用法

    value为当前框中的值 <input  name="num"type="text"  onblur="changeorder(id,this. ...

  6. 前端技巧:禁止浏览器static files缓存篇(转)

    前端技巧:禁止浏览器static files缓存篇 由于CSS/JS文件经常需要改动,前端调试时是不希望浏览器缓存这些文件的. 本文记录博主的经验. Meta法 目前在chrome调试还没有遇到问题, ...

  7. (HY000): Cannot modify @@session.sql_log_bin inside a transaction

    昨天,线上发生一例(HY000): Cannot modify @@session.sql_log_bin inside a transaction代码缺少显示的start transaction控制 ...

  8. 从" ThinkPHP 开发规范 "看 PHP 的命名规范和开发建议

    稍稍水一篇博客,摘抄自Think PHP 的开发规范,很有引导性,我们可以将这些规范实践到原生 PHP 中. 命名规范 使用ThinkPHP开发的过程中应该尽量遵循下列命名规范: 类文件都是以.cla ...

  9. [ASP.NET MVC] ASP.NET Identity学习笔记 - 原始码下载、ID型别差异

    [ASP.NET MVC] ASP.NET Identity学习笔记 - 原始码下载.ID型别差异 原始码下载 ASP.NET Identity是微软所贡献的开源项目,用来提供ASP.NET的验证.授 ...

  10. jQuery对复选框(checkbox)的全选,全不选,反选等的操作

    效果截图: HTML代码: <body><ul id="list"> <li><label><input type=" ...