skel.CmdArgs数据结构如下所示:

type CmdArgs struct {

  ContainerID    string
  Netns        string
  IfName       string
  Args         string
  Path         string
  StdinData      []byte
}

  

// cni/plugins/ipam/host-local/main.go

1、func cmdAdd(args *skel.CmdArgs) error

1、调用ipamConf, confVersion, err := allocator.LoadIPAMConfig(args.StdinData, args.Args)加载IPAM的配置和版本号

2、若ipamConf.ResolvConf不为"",则调用dns, err := parseResolvConf(ipamConf.ResolvConf),并且将result.DNS = *dns

3、调用store, err := disk.New(ipamConf.Name, ipamConf.DataDir)

4、调用allocs := []*allocator.IPAllocator{} 获取allocator,保持该结构,当出错的时候,可以将所有IP地址释放

5、创建requestedIPs := map[string]net.IP{}并将ipamConf.IPArgs中的地址都填入其中

6、遍历for idx, ipRange := range ipamConf.Ranges,调用allocator := allocator.NewIPAllocator(ipamConf.Name, ipRange, store)

7、遍历requestedIPs,for k, ip := range requestedIPs,如果ipRange.IPInRange(ip)为nil,则说明请求的ip在可分配的地址范围内,

设置requestedIP = ip,并调用delete(requestedIPs, k)

8、调用ipConf, err := allocator.Get(args.ContainerID, requestedIP),并调用allocs = append(allocs, allocator)和result.IPs = append(result.IPs, ipConf)

9、如果最后len(requestedIPs)不为0,则释放所有的allocator并报错

10、设置result.Routes = ipamConf.Routes

11、最后return types.PrintResult(result, confVersion)

// cni/plugins/ipam/host-local/backend/allocator/config.go

// NewIPAMConfig creates a NetworkConfig from the given network name.

2、func LoadIPAMConfig(bytes []byte, envArgs string) (*IPAMConfig, string, error)

1、首先设置n := Net{},再调用json.Unmarshal(bytes, &n)进行解析

2、如果envArgs不为"",或者n.Args不为nil,则将他们都添加到n.IPAM.IPArgs中

3、如果n.IPAM.Range不为nil,说明使用的是老的配置方式,将n.IPAM.Range迁移到n.IPAM.Ranges中

4、遍历n.IPAM.Ranges,对IPv4或IPv6的range进行计数,若他们的数目大于1,切cni版本小于0.3.0则报错

5、检测各个range之间是否有重合

6、将n.IPAM.Name赋值为n.Name

7、最后return n.IPAM, n.CNIVersion, nil

Net数据结构如下所示:

type Net struct {
  Name       string
  CNIVersion    string
  IPAM       *IPAMConfig
  Args       *struct {
    A *IPAMArgs
  }
}

  

IPAMConfig数据结构如下所示:

// IPAMConfig represents the IP related network configuration
// 保留Range是为了向后兼容
type IPAMConfig struct {
  *Range
  Name      string
  Type       string
  Routes      []*types.Route
  DataDir      string
  ResolvConf    string
  Ranges       []Range
  IPArgs       []net.IP    // Requested IPs from CNI_ARGS and args
}

  

Range结构如下所示:

type Range struct {
  RangeStart    net.IP
  RangeEnd     net.IP
  Subnet      types.IPNet
  Gateway      net.IP
}

IPAMArgs结构如下所示:

type IPAMArgs struct {
  IPs    []net.IP
}

  

// cni/plugins/ipam/host-local/backend/disk/backend.go

3、func New(network, dataDir string) (*Store, error)

1、若dataDir为"",设置defaultDataDir为"/var/lib/cni/networks"

2、调用dir := filepath.Join(dataDir, network)并且调用os.MkdirAll(dir, 0755)创建目录

3、调用lk, err := NewFileLock(dir)

4、最后返回return &Store{*lk, dir}, nil

Store数据结构如下所示:

type Store struct {
  FileLock        // FileLock wraps os.File to be used as a lock using flock
  dataDir   string  // 默认为/var/lib/cni/networks/NETWORKNAME
}

  

// cni/plugins/ipam/host-local/backend/allocator/allocator.go

4、func NewIPAllocator(netName string, r Range, store backend.Store) *IPAllocator

1、调用rangeID := base64.URLEncoding.EncodeToString(r.RangeStart)

2、返回return &IPAllocator{......}

IPAllocator数据结构如下所示:

type IPAllocator struct {
  netName    string
  ipRange     Range
  store      backend.Store
  rangeID   string // Used for tracking last reserved ip
}

  

// cni/plugins/ipam/host-local/backend/allocator/allocator.go

5、func (a *IPAllocator) Get(id string, requestedIP net.IP) (*current.IPConfig, error)

1、调用gw := a.ipRange

2、如果requestedIP 不为nil,首先判断requestedIP和gw不能相等,否则报错

如果a.ipRange.IPInRange(requestedIP)返回错误,则报错,否则调用reserved, err := a.store.Reserve(id, requestedIP, a.rangeID)将结果保存

最后,设置reservedIP为requestedIP

3、如果requestedIP不为nil,先调用iter, err := a.GetIter(),再调用for循环遍历iter,获取下一个可用的IP,之后的动作和2中相同

4、最后返回return &current.IPConfig{....}, nil

CNI IPAM插件分析 --- 以hostlocal为示例的更多相关文章

  1. CNI bridge 插件实现代码分析

    对于每个CNI 插件在执行函数cmdAdd之前的操作是完全一样的,即从环境变量和标准输入内读取配置.这在http://www.cnblogs.com/YaoDD/p/6410725.html这篇博文里 ...

  2. Kubernetes CNI网络插件

    CNI 容器网络接口,就是在网络解决方案由网络插件提供,这些插件配置容器网络则通过CNI定义的接口来完成,也就是CNI定义的是容器运行环境与网络插件之间的接口规范.这个接口只关心容器的网络连接,在创建 ...

  3. 安装cni网络插件-非必须

    安装cni网络插件 安装cni # 安装 cni # 百度云链接:https://pan.baidu.com/s/1-PputObLs5jouXLnuBCI6Q 密码:tzqm cd /server/ ...

  4. RocketMQ源码分析之从官方示例窥探:RocketMQ事务消息实现基本思想

    摘要: RocketMQ源码分析之从官方示例窥探RocketMQ事务消息实现基本思想. 在阅读本文前,若您对RocketMQ技术感兴趣,请加入RocketMQ技术交流群 RocketMQ4.3.0版本 ...

  5. 利用webuploader插件上传图片文件,完整前端示例demo,服务端使用SpringMVC接收

    利用WebUploader插件上传图片文件完整前端示例demo,服务端使用SpringMVC接收 Webuploader简介   WebUploader是由Baidu WebFE(FEX)团队开发的一 ...

  6. 3.kubernetes的CNI网络插件-Flannel

    目录 1.1.K8S的CNI网络插件-Flannel 1.1.1.集群规划 1.1.2.下载软件.解压.软链接 1.1.3.最终目录结构 1.1.4.拷贝证书 1.1.5.创建配置 1.1.6.创建启 ...

  7. 基于RabbltMQ延迟插件实现延迟队列代码示例

    上一篇文章写了docker安装RabbitMQ及延迟插件的安装,这篇的话是基于RabbitMQ延迟插件实现延迟队列的示例 那么废话不多说 直接上代码!! 首先创建延迟队列配置类 DelayedQueu ...

  8. 第十章 Kubernetes的CNI网络插件--flannel

    1.简介 1.1前言 Kubernetes设计了网络模型,但却将它的实现讲给了网络插件,CNI网络插件最重要的功能就是实现Pod资源能够跨主机通信 常见的CNI网络插件如下: Flannel: Cac ...

  9. CNI portmap插件实现源码分析

    DNAT创建的iptables规则如下:(重写目的IP和端口) PREROUTING, OUTPUT: --dst-type local -j CNI-HOSTPORT_DNAT  // PREROU ...

随机推荐

  1. Linux高性能server编程——I/O复用

     IO复用 I/O复用使得程序能同一时候监听多个文件描写叙述符.通常网络程序在下列情况下须要使用I/O复用技术: client程序要同一时候处理多个socket client程序要同一时候处理用户 ...

  2. 阿里云ECS网站备案流程

    首先登录阿里云账号-->点击选项卡中的备案专区-->开始备案选项卡-->增加网站 然后是一大堆信息核查,之后填写网站备案信息,这里注意,有个文件审批号的选项可以不填(选择“请选择”) ...

  3. java之Thread Dump分析

    什么是Thread Dump Thread Dump是非常有用的诊断Java应用问题的工具.每一个Java虚拟机都有及时生成所有线程在某一点状态的thread-dump的能力,虽然各个 Java虚拟机 ...

  4. (译)Getting Started——1.3.1 Incorporating the Data(合并数据)

    在实现完应用的行为后,需要创建数据模型来支撑应用的界面.应用的数据模型定义了应用中数据的维护方法.数据模型可以是一个基本的dictionary类型,也可以是复杂的数据库,范围很广.好的数据模型可以更为 ...

  5. 数据库设计(四)数据库的规范化(Normalization)

    数据库的规范化 Database Normalization is a technique of organizing the data in the database. Normalization ...

  6. vim中ctags应用

    ctags(Generate tag files for source code)是vim下方便代码阅读的工具.尽管ctags也可以支持其它编辑器,但是它正式支持的只有VIM.并且VIM中已经默认安装 ...

  7. Oracle的REGEXP_INSTR函数简单使用方法

    REGEXP_INSTR函数让你搜索一个正則表達式模式字符串. 函数使用输入字符集定义的字符进行字符串的计算. 它返回一个整数,指示開始或结束匹配的子位置.这取决于return_option參数的值. ...

  8. vs 常用工具

    工欲善其事,必先利其器,没有好的工具,怎么能高效的开发出高质量的代码呢?本文为 ASP.NET 开发者介绍一些高效实用的工具,包括 SQL 管理,VS插件,内存管理,诊断工具等,涉及开发过程的各个环节 ...

  9. 请写出JavaScript中常用的三种事件。

    请写出JavaScript中常用的三种事件. 解答: onclick,onblur,onChange

  10. JavaWeb——监听器

    监听器简介 监听器是指专门用于在其他对象身上发生的事件或者状态改变进行监听和相应处理的对象,当被监听的对象发生变化时立即采取相应的行动. 例如我们要实现统计一个网站的在线人数,就可以在Web应用应用程 ...