github blog:https://xftony.github.io
sriov-cni简介
sriov-cni是hustcat/sriov-cni开发的一种容器网络插件(Container Network Interface),它使得容器可以直接使用物理机中扩展出来的VF(virtual functions)。Intel在此基础上,为其添加了dpdk功能。本文介绍的sriov-cni的版本为Intel版,修改也是基于Intel版本进行的修改。
sriov-cni代码简介
sriov-cni主要通过调用netlink包将vf修改到容器的namespace下,使得VF可以被容器直接调用。其中VF是指支持SRIOV的物理网卡所虚拟出的一个“网卡”或者说虚出来的一个实例,它会以一个独立网卡的形式呈现出来,每一个VF有它自己独享的PCI配置区域,并且可能与其他VF共享着同一个物理资源(公用同一个物理网口)
根据cni的标准定义两个函数cmdAdd和cmdDel,分别用于VF的添加和删除skel.PluginMain(cmdAdd, cmdDel)
cmdAdd和cmdDel基本是一对反过程,所以这里就只简单介绍一下cmdAdd函数。
func cmdAdd(args *skel.CmdArgs) error {
n, err := loadConf(args.StdinData) // 将输入参数转化为NetConf变量n
if err != nil {
return fmt.Errorf("failed to load netconf: %v", err)
}
// 获取container的net命名空间,args.Netns是container的在host中的网络命名空间路径
netns, err := ns.GetNS(args.Netns)
if err != nil {
return fmt.Errorf("failed to open netns %q: %v", netns, err)
}
defer netns.Close()
if n.IF0NAME != "" {
args.IfName = n.IF0NAME
}
// 核心函数,配置VF,将VF移动到container的命名空间
if err = setupVF(n, n.IF0, args.IfName, args.ContainerID, netns); err != nil {
return fmt.Errorf("failed to set up pod interface %q from the device %q: %v", args.IfName, n.IF0, err)
}
// 在DPDK 和L2模式下, 无需调用IPAM进行IP分配
var result *types.Result
if n.DPDKMode != false ||