【kubernetes/k8s概念】CNI源码分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhonglinzhang/article/details/82702007

https://github.com/containernetworking/cni

1、main函数

  • 配置文件目录netdir,如果未指定,则默认为/etc/cni/net.d
  • 调用libcni.LoadConfList(netdir, os.Args[2]),参数os.Args[2]为用户指定的的network的名字       
func main() {
	netdir := os.Getenv(EnvNetDir)
	if netdir == "" {
		netdir = DefaultNetDir
	}
	netconf, err := libcni.LoadConfList(netdir, os.Args[2])

	var capabilityArgs map[string]interface{}
	capabilityArgsValue := os.Getenv(EnvCapabilityArgs)

	var cniArgs [][2]string
	args := os.Getenv(EnvCNIArgs)
	if len(args) > 0 {
		cniArgs, err = parseArgs(args)
		if err != nil {
			exit(err)
		}
	}

	netns := os.Args[3]

	cninet := &libcni.CNIConfig{
		Path: filepath.SplitList(os.Getenv(EnvCNIPath)),
	}

	rt := &libcni.RuntimeConf{
		ContainerID:    "cni",
		NetNS:          netns,
		IfName:         "eth0",
		Args:           cniArgs,
		CapabilityArgs: capabilityArgs,
	}

	switch os.Args[1] {
	case CmdAdd:
		result, err := cninet.AddNetworkList(netconf, rt)

		exit(err)
	case CmdDel:
		exit(cninet.DelNetworkList(netconf, rt))
	}
}

    (1)、LoadConfList函数

  • 查找是否有以.conflist作为后缀的配置文件,如果有Name和参数os.Args[2]一致,返回NetConfigList填充配置。否则,查找是否存在以.conf或.json作为后缀的配置文件。如果存在Name一致的配置,则加载该配置文件。由于.conf或"json中都是单个的网络配置,因此需要读取包不返回一个NetConfig的NetworkConfigList
func LoadConfList(dir, name string) (*NetworkConfigList, error) {
	files, err := ConfFiles(dir, []string{".conflist"})
	if err != nil {
		return nil, err
	}
	sort.Strings(files)

	for _, confFile := range files {
		conf, err := ConfListFromFile(confFile)
		if err != nil {
			return nil, err
		}
		if conf.Name == name {
			return conf, nil
		}
	}

	// Try and load a network configuration file (instead of list)
	// from the same name, then upconvert.
	singleConf, err := LoadConf(dir, name)
	if err != nil {
		// A little extra logic so the error makes sense
		if _, ok := err.(NoConfigsFoundError); len(files) != 0 && ok {
			// Config lists found but no config files found
			return nil, NotFoundError{dir, name}
		}

		return nil, err
	}
	return ConfListFromConf(singleConf)
}

(2)、NetworkConfigList结构体  

type NetworkConfig struct {
	Network *types.NetConf
	Bytes   []byte
}

type NetworkConfigList struct {
	Name       string
	CNIVersion string
	Plugins    []*NetworkConfig
	Bytes      []byte
}

(3)、NetConf结构体

// NetConf describes a network.
type NetConf struct {
	CNIVersion string `json:"cniVersion,omitempty"`

	Name         string          `json:"name,omitempty"`
	Type         string          `json:"type,omitempty"`
	Capabilities map[string]bool `json:"capabilities,omitempty"`
	IPAM         struct {
		Type string `json:"type,omitempty"`
	} `json:"ipam,omitempty"`
	DNS DNS `json:"dns"`
}

(4)、RuntimeConf结构体

       容器运行时信息的数据结构

type RuntimeConf struct {
	ContainerID string
	NetNS       string
	IfName      string
	Args        [][2]string
	// A dictionary of capability-specific data passed by the runtime
	// to plugins as top-level keys in the 'runtimeConfig' dictionary
	// of the plugin's stdin data.  libcni will ensure that only keys
	// in this map which match the capabilities of the plugin are passed
	// to the plugin
	CapabilityArgs map[string]interface{}
}

(5)、AddNetworkList函数

  • 根据容器网络配置信息和容器运行时信息,执行加入容器网络的操作
// AddNetworkList executes a sequence of plugins with the ADD command
func (c *CNIConfig) AddNetworkList(list *NetworkConfigList, rt *RuntimeConf) (types.Result, error) {
	var prevResult types.Result
	for _, net := range list.Plugins {
		pluginPath, err := invoke.FindInPath(net.Network.Type, c.Path)
		if err != nil {
			return nil, err
		}

		newConf, err := buildOneConfig(list, net, prevResult, rt)
		if err != nil {
			return nil, err
		}

		prevResult, err = invoke.ExecPluginWithResult(pluginPath, newConf.Bytes, c.args("ADD", rt))
		if err != nil {
			return nil, err
		}
	}

	return prevResult, nil
}

2、libcni

       cni项目提供了一个library,定义了集成cni插件的接口libcni。Interface定义如下:

type CNI interface {
	AddNetworkList(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
	DelNetworkList(net *NetworkConfigList, rt *RuntimeConf) error

	AddNetwork(net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
	DelNetwork(net *NetworkConfig, rt *RuntimeConf) error
}

猜你喜欢

转载自blog.csdn.net/zhonglinzhang/article/details/82702007