CNI插件初始化

// ocicni.go

1、func InitCNI(pluginDir string) (CNIPlugin, error)

(1)、先调用plugin := probeNetworkingPluginsWithVendorCNIDirPrefix(pluginDir, "")

先初步创建一个默认的cniNetworkPlugin的结构,并调用plugin.nsenterPath, err = exec.LookPath("nsenter")

(2)、调用err = getDefaultCNINetwork(plugin.pluginDir, plugin.vendorCNIDirPrefix),检查默认的network

是否存在,若不存在,则停止CNI插件的搜索,直接返回一个&cniNoOp{}结构

(3)、生成一个goroutine,调用plugin.SyncNetworConfig()周期性地和pluginDir进行同步,从而检查网络状态的更新

(4)、最后,return plugin, nil

cniNetworkPlugin结构如下所示:

type cniNetworkPlugin struct {
  loNetwork     *cniNetwork
  sync.RWMutex
  defaultNetwork   *cniNetwork
  nsenterPath     string
  pluginDir      string
  vendorCNIDirPrefix string
}

  

cniNetwork结构如下所示:

type cniNetwork struct {
  name      string
  NetworkConfig  *libcni.NetworkConfig
  CNIConfig    libcni.CNI
}

  

// ocicni.go

2、func probeNetworkPluginsWithVendorCNIDirPrefix(pluginDir, vendorCNIDirPrefix string) (*cniNetworkPlugin)

(1)、创建plugin := &cniNetworkPlugin{

  defaultNetwork:      nil,

  loNetwork:          getLoNetwork(vendorCNIDirPrefix),

  pluginDir:          pluginDir,

  vendorCNIDirPrefix:    vendorCNIDirPrefix,

}

(2)、调用plugin.syncNetworkConfig()  ---> sync NetworkConfig in best effort during probing

(3)、最后,return plugin

// ocicni.go

3、func getLoNetwork(vendorDirPrefix string) *cniNetwork

(1)、调用loConfig,err := libcni.ConfFromBytes([]byte(`{"cniVersion": "0.1.0", "name": "cni-loopback", "type": "loopback"}`))

(2)、调用cninet := &libcni.CNIConfig{Path: []string{vendorCNIDir(vendorDirPrefix, loConfig.Network.Type), DefaultCNIDir}},其中vendorCNIDir返回的就是这样一个目录:$vendorDirPrefix/opt/$type/bin

(3)、创建loNetwork := cniNetwork{

  name:      "lo"

  NetworkConfig:   loConfig,

  CNIConfig:    cninet

}

再return loNetwork

// ocicni.go

4、func (plugin *cniNetworkPlugin) syncNetworkConfig()

该函数仅仅调用network, err := getDefaultCNINetwork(plugin.pluginDir, plugin.vendorCNIDirPrefix)

再调用plugin.setDefaultNetwork(network)

// ocicni.go

5、func getDefaultCNINetwork(pluginDir, vendorCNIDirPrefix string) (*cniNetwork, error)

(1)、当pluginDir为""时,设置pluginDir = DefaultNetDir

(2)、调用files, err := libcni.ConfFiles(pluginDir),从pluginDir中加载文件,若err不为nil,或者len(files) == 0,则报错

(3)、遍历files,调用conf, err := libcni.ConfFromFile(confFile),加载CNI config file

再设置cninet := &libcni.CNIConfig{Path: []string{DefaultCNIDir, vendorDir},}

最后设置network := &cniNetwork{name: conf.Network.Name, NetworkConfig: conf, CNIConfig: cninet}

// ocicni.go

6、func setDefaultNetwork(n *cniNetwork)

该函数仅仅设置plugin.defaultNetwork = n而已

CNI插件创建POD

// cri-o端的调用为:

podNamespace := ""

s.netPlugin.SetUpPod(netNsPath, podNamespace, id, containerName)

// ocicni.go

1、func (plugin *cniNetworkPlugin) SetUpPod(netnsPath string, namespace string, name string, id string) error

(1)、首先调用plugin.checkInitialized(),该函数确定plugin.defaultNetwork是否为nil,若为nil则报错

(2)、调用plugin.loNetwork.addToNetwork(name, namespace, id, netnsPath)

(3)、调用plugin.getDefaultNetwork().addToNetwork(name, namespace, id, netnsPath)

// ocicni.go

2、func (network *cniNetwork) addToNetwork(podName string, podNamespace string, podInfraContainerID string, podNetnsPath string) (*cnitypes.Result, error)

(1)、调用rt, err := buildCNIRuntimeConf(podName, podNamespace, podInfraContainerID, podNetnsPath)

(2)、调用netconf, cninet := network.NetworkConfig, network.CNIConfig

(3)、调用res, err := cninet.AddNetwork(netconf, rt)

(4)、最后return res, nil

// ocicni.go

3、func buildCNIRuntimeConf(podName string, podNs string, podInfraContainerID string, podNetnsPath string) (*libcni.RuntimeConf, error)

该函数仅仅创建rt := &libcni.RuntimeConf{

  ContainerID:  podInfraContainerID,

  NetNS:       podNetnsPath,

  IfName:     DefaultInterfaceName,

  Args:    [][2]string{

      {"IgnoreUnknown", "1"},

      {"K8S_POD_NAMESPACE", podNs},

      {"K8S_POD_NAME", podName},

      {"K8S_POD_INFRA_CONTAINER_ID", podInfraContainerID},

  }

}

最后,return rt, nil

获取pod的网络状态

1、func (plugin *cniNetworkPlugin) GetContainerNetworkStatus(netnsPath string, namespace string, name string, id string) (string, error)

该函数先调用ip, err := getContainerIP(plugin.nsenterPath, netnsPath, DefaultInterfaceName, "-4")

最后return ip.String(), nil

CNI插件源码示例,对于github.com/rajatchopra/ocicni库的分析的更多相关文章

  1. [C] c99int(让VC等编译器自动兼容C99的整数类型)V1.02。源码托管到github、添加CMake编译配置文件、使用doxygen规范注释

    新版本—— http://www.cnblogs.com/zyl910/p/zlstdint_v100.html[C] zlstdint(让VC.TC等编译器自动兼容C99的整数类型)V1.0.支持T ...

  2. 如何查看google chrome 插件源码

    常用浏览器google chrome 有很多优秀的插件,寂寞的时候想看看人家是怎么实现的,说是快那就动手吧 插件代码位置 本人mac笔记本,chrome 插件位置如下 $ cd  /Users/vin ...

  3. Ocelot简易教程(七)之配置文件数据库存储插件源码解析

    作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/9852711.html 上篇文章给大家分享了如何集成我写的一个Ocelot扩展插件把Ocelot的配置存储 ...

  4. 手机端页面自适应解决方案—rem布局(进阶版,附源码示例)

    转自:https://segmentfault.com/a/1190000007350680 一年前笔者写了一篇 <手机端页面自适应解决方案—rem布局>,意外受到很多朋友的关注和喜欢.但 ...

  5. tinymce原装插件源码分析(四)-fullscreen

    fullscreen 作为一款文本编辑器,全屏功能是非常有必要的.在插件中主要是修改一些css style和触发resize事件. style问题(反例): 见github源码:https://git ...

  6. tinymce原装插件源码分析(一)-hr

    tinymce简介 tinymce是一款能方便无限扩展的网页富文本编辑器. tinymce原装插件已经十分丰富,对于文本编辑(blog等文章)是绰绰有余,但是应对一些复杂的应用,比如在上面开发html ...

  7. [C] tcharall(让所有平台支持TCHAR)v1.1。源码托管到github、添加CMake编译配置文件、使用doxygen规范注释

    作者:zyl910 v1.1版的改动如下—— 将源码上传到github. 调整目录结构. 添加CMake编译配置文件. 使用doxygen规范注释. 文件清单—— docs\ docs\images\ ...

  8. 安卓图表引擎AChartEngine(四) - 源码示例 嵌入Acitivity中的折线图

    前面几篇博客中都是调用ChartFactory.get***Intent()方法,本节讲的内容调用ChartFactory.get***View()方法,这个方法调用的结果可以嵌入到任何一个Activ ...

  9. 基于tomcat插件的maven多模块工程热部署(附插件源码)

    内容属原创,转载请注明出处 写在前面的话 最近一直比较纠结,归根结底在于工程的模块化拆分.以前也干过这事,但是一直对以前的结果不满意,这会重操旧业,希望搞出个自己满意的结果. 之前有什么不满意的呢? ...

随机推荐

  1. CodeFirst时使用T4模板(你肯定没用过的笨方法,还望园友指教)

    我们都知道T4模板用于生成相似代码. 在DBFirst和ModelFirst条件下我们很容易从.edmx下获取所有实体类和其名称,并且通过我们定义的模板和某些遍历工作为我们生成所需要的相似代码. 但是 ...

  2. 【Win10开发】自定义标题栏

    UWP 现在已经可以自定义标题栏了,毕竟看灰色时间长了也会厌烦,开发者们还是希望能够将自己的UI做的更加漂亮,更加与众不同.那么废话不多说,我们开始吧! 首先要了解ApplicationViewTit ...

  3. 什么是java 序列化,如何实现java 序列化?

    我们有时候将一个 java 对象变成字节流的形式传出去或者从一个字节流中恢复成一个java 对象,例如,要将java 对象存储到硬盘或者传送给网络上的其他计算机,这个过程我们可以自己写代码去把一个ja ...

  4. PHP工作笔记:数组转字符串与字符串转数组

    一个数组要入库,发现不可以,特定用函数转为字符串入库 $data = array( 'http://img4.bitautoimg.com/autoalbum/files/20110420/734/2 ...

  5. 几款开源的hybird移动app框架分析

    几款开源的Hybrid移动app框架分析 Ionic Onsen UI 与 ionic 相比 jQuery Mobile Mobile Angular UI 结论 很多移动开发者喜欢使用原生代码开发, ...

  6. 走进SVG

    什么是SVG?也许现在很多人都听说过SVG的人比较多,但不一定了解什么是SVG:SVG(Scalable Vector Graphics 一大串看不懂的英文)可伸缩矢量图形,它是用XML格式来定义用于 ...

  7. jquery实现表格的搜索功能

    版权声明:作者原创,转载请注明出处! HTML代码如下: <input type="text" id="txt" value="" / ...

  8. SharePoint 2013 自定义扩展菜单(二)

    接博文<SharePoint 2013 自定义扩展菜单>,多加了几个例子,方便大家理解. 例七 列表设置菜单扩展(listedit.aspx) 扩展效果 XML描述 <CustomA ...

  9. TFS online 自动部署配置

    概要 采用tfs online进行源码管理,并配置自动编译部署到外网上一台服务器上(阿里云虚拟机) 步骤; 下载angent,并运行脚本安装 配置release managemetn; 1)Copy ...

  10. ListView实现点击事件以及总结

    差点吓死我了,好不容易写的博客没有了,还好有自动保存功能,不然我真的是呜呜... ---恢复内容开始--- 开学一个月了,终于可以看见自己的作品雏形了. 从一个小白到现在半年了,觉得日子过得比较充实, ...