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. 如何把maven项目转成web项目

    创建Web工程,使用eclipse ee创建maven web工程 1.右键项目,选择Project Facets,点击Convert to faceted from 2.更改Dynamic Web ...

  2. CentOS常用指令

    创建文件: 如touch a.txt 创建文件夹: mkdir -p 文件夹名,当文件夹不存在时候,创建这个文件夹 文件重命名: 把文件text.php得命名为index.php,可以是rename ...

  3. Picasso

    1.简介 Picasso是Square公司出品的一个强大的图片下载和缓存图片库1)在adapter中需要取消已经不在视野范围的ImageView图片资源的加载,否则会导致图片错位,Picasso已经解 ...

  4. 关于sap的字段和对象修改记录的查找

    sap的字段和对象的修改都会保存旧值,数据保存在CDHDR和CDPOS表中,对于提取旧值你可以采用两种方法 1)使用sap的标准函数CHANGEDOCUMENT_READ_HEADERS 和CHANG ...

  5. Arcengine实现创建网络数据集札记(二)

    四 ArcEngine实现创建网络数据集 ArcEngine创建网络数据集的过程,与ArcMap设置的过程类似,主要通过六个步骤即可以实现. 1 定义网络数据集对象,并设置基本属性,包括网络数据集名称 ...

  6. all things are difficult before they are easy

    刚开始接触一项新知识时,总是感觉很难,只要你用心钻研下去,它会慢慢变简单的.

  7. Ubuntu上安装Apache、MySql和PHP

    参考文献: http://developer.51cto.com/art/201110/299303.htm

  8. mac svn client 设置

    经过谷歌和百度N次后,终于搞定SVN的升级,Intellij Idea和Xcode5.1都可以正常使用. 步骤: 1. 下载Subverion的Max安装版.(推荐.使用其他brew和port都试过, ...

  9. Struts2--Helloworld

    搭建Struts2环境时,我们一般需要做以下几个步骤的工作: 1.找到开发Struts2应用需要使用到的jar文件. 2.创建Web工程 3.在web.xml中加入Struts2 MVC框架启动配置 ...

  10. MyBatis入门(二)---一对一,一对多

    一.创建数据库表 1.1.创建数据表同时插入数据 /* SQLyog Enterprise v12.09 (64 bit) MySQL - 5.6.27-log : Database - mybati ...