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. knockout.js的简介和简单使用

    1.knockout简介knockout是一个轻量级的UI类库,通过MVVM模式使JavaScript前端UI简单化knockout有四大重要概念:1)声明式绑定:使用简明移读的语法很容易地将模型(m ...

  2. Access restriction : The constructor BASE64Decoder() is not accessible due to restriction on required library

    1.问题描述 找不到包  sun.misc.BASE64Encoder 2. 解决方案 只需要在project build path中先移除JRE System Library,再添加库JRE Sys ...

  3. python爬虫——爬取NUS-WIDE数据库图片

    实验室需要NUS-WIDE数据库中的原图,数据集的地址为http://lms.comp.nus.edu.sg/research/NUS-WIDE.htm   由于这个数据只给了每个图片的URL,所以需 ...

  4. winform(数据导出、TreeView的使用)

    一.数据导出:目标: 将数据库的数据导出成Excel工作表或是Word文档 基本步骤: 1.首先将数据库中的数据封装成实体类 2.写好查询数据的方法,在主窗体中调用查看所有的数据 3.利用saveFi ...

  5. <<摩托车修理技术与禅>>读书笔记

    一旦想要求快,就表示你再也不关心它,而想去做别的事. 感触比较大的一句话.其实每个人看书,都有不同的侧重点,不同经历的人看同样的书,收获是不一样的,所以不能在乎收获多少,只要有收获就行.

  6. WCF Service部署在IIS上

    环境vs2010,WCF应用程序.如何将WCF部署在IIS上. 第一步:右键点击项目,选择生成部署包. 第二步:在你项目所在的文件目录下找到Package文件夹,这就是我们的部署包所在的地方.在这个p ...

  7. 将内表通过TXT文本输出

    PARAMETERS: num TYPE i. TYPE-POOLS: truxs. "类型组 DATA:w_filename TYPE string. TYPES:BEGIN OF ty_ ...

  8. Universal-Image-Loader完全解析(上)

    Universal-Image-Loader完全解析(上) 基本介绍及使用 大家平时做项目的时候,或多或少都会接触到异步加载图片,或者大量加载图片的问题,而加载图片时候经常会遇到各种问题,如oom,图 ...

  9. 二维数组 string[,]

    string[,] strArr = {                               {"101","电脑"},                 ...

  10. Python基础(7)--函数

    本篇文章将介绍如何将语句组织成函数,以及参数概念以及在程序中的用途 本文地址:http://www.cnblogs.com/archimedes/p/python-function.html,转载请注 ...