本篇主要是简单了解CNI的一个第三方插件SRIOV,这里需要说明的是有两个版本,一个是腾讯员工的原版,代码链接在此,另一个是intel fork后修改的版本,代码连接在此。我们会以intel版本为主进行学习,因为intel版本在原版上添加了mellanox网卡以及一些其他参数的支持。
概览
带有SR-IOV功能的网卡引入了PF和VF的概念,PF一般被主机使用,VF可以给容器使用,每个VF都可以看做是一个单独的物理网卡,分配给一个容器,并且配置单独的MAC、VLAN和IP等信息。
使用
我们展示怎么使用,首先要做的就是使能SR-IOV,然后是配置文件的各个配置项。
原版
# vi /etc/modprobe.conf
options ixgbe max_vfs=8,8
配置文件
# cat > /etc/cni/net.d/10-mynet.conf <<EOF
{
"name": "mynet",
"type": "sriov",
"master": "eth1",
"ipam": {
"type": "fixipam",
"subnet": "10.55.206.0/26",
"routes": [
{ "dst": "0.0.0.0/0" }
],
"gateway": "10.55.206.1"
}
}
EOF
- name (string, required): 网络配置名字
- type (string, required): "sriov"
- master (string, required): PF的名字
- ipam (dictionary, required): 使用的IPAM配置
- pfOnly (bool, optional): 跳过VF,只使用PF
- vf (int, optional): VF的index
- vlan (int, optional): VF的VLAN
- mac (string, optional): VF的MAC
Intel版本
除了支持上述的intel网卡,还支持了Mellanox的网卡。
# mst start
Starting MST (Mellanox Software Tools) driver set
Loading MST PCI module - Success
Loading MST PCI configuration module - Success
Create devices
# mst status
MST modules:
------------
MST PCI module loaded
MST PCI configuration module loaded
MST devices:
------------
/dev/mst/mt4115_pciconf0 - PCI configuration cycles access.
...
# mlxconfig -d /dev/mst/mt4115_pciconf0 q set SRIOV_EN=1 NUM_OF_VFS=8
...
Apply new Configuration? ? (y/n) [n] : y
Applying... Done!
-I- Please reboot machine to load new configurations.
# reboot
# ibdev2netdev
mlx5_0 port 1 ==> enp2s0f0 (Up)
mlx5_1 port 1 ==> enp2s0f1 (Up)
# echo 4 > /sys/class/net/enp2s0f0/device/sriov_numvfs
# ibdev2netdev -v
0000:02:00.0 mlx5_0 (MT4115 - MT1523X04353) CX456A - ConnectX-4 QSFP fw 12.23.1020 port 1 (ACTIVE) ==> enp2s0f0 (Up)
0000:02:00.1 mlx5_1 (MT4115 - MT1523X04353) CX456A - ConnectX-4 QSFP fw 12.23.1020 port 1 (ACTIVE) ==> enp2s0f1 (Up)
0000:02:00.5 mlx5_2 (MT4116 - NA) fw 12.23.1020 port 1 (DOWN ) ==> enp2s0f2 (Down)
0000:02:00.6 mlx5_3 (MT4116 - NA) fw 12.23.1020 port 1 (DOWN ) ==> enp2s0f3 (Down)
0000:02:00.7 mlx5_4 (MT4116 - NA) fw 12.23.1020 port 1 (DOWN ) ==> enp2s0f4 (Down)
0000:02:00.2 mlx5_5 (MT4116 - NA) fw 12.23.1020 port 1 (DOWN ) ==> enp2s0f5 (Down)
# lspci | grep Mellanox
02:00.0 Ethernet controller: Mellanox Technologies MT27700 Family [ConnectX-4]
02:00.1 Ethernet controller: Mellanox Technologies MT27700 Family [ConnectX-4]
02:00.2 Ethernet controller: Mellanox Technologies MT27700 Family [ConnectX-4 Virtual Function]
02:00.3 Ethernet controller: Mellanox Technologies MT27700 Family [ConnectX-4 Virtual Function]
02:00.4 Ethernet controller: Mellanox Technologies MT27700 Family [ConnectX-4 Virtual Function]
02:00.5 Ethernet controller: Mellanox Technologies MT27700 Family [ConnectX-4 Virtual Function]
# ip link show
...
enp2s0f2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether c6:6d:7d:dd:2a:d5 brd ff:ff:ff:ff:ff:ff
enp2s0f3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 42:3e:07:68:da:fb brd ff:ff:ff:ff:ff:ff
enp2s0f4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 42:68:f2:aa:c2:27 brd ff:ff:ff:ff:ff:ff
enp2s0f5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
...
echo 0 > /sys/class/net/enp2s0f0/device/sriov_numvfs
echo 8 > /sys/class/net/enp2s0f0/device/sriov_numvfs
配置文件
# cat > /etc/cni/net.d/20-mynet-dpdk.conf <<EOF
{
"cniVersion": "0.3.1",
"name": "sriov-dpdk",
"type": "sriov",
"deviceID": "0000:03:02.0",
"vlan": 1000,
"ipam": {
"type": "host-local",
"subnet": "10.56.217.0/24",
"rangeStart": "10.56.217.171",
"rangeEnd": "10.56.217.181",
"routes": [
{ "dst": "0.0.0.0/0" }
],
"gateway": "10.56.217.1"
}
"min_tx_rate": 100,
"max_tx_rate": 200,
"spoofchk": "off",
"trust": "on"
"link_state": "enable"
}
EOF
- name (string, required): 网络配置名字
- type (string, required): "sriov"
- deviceID (string, required): 网卡VF的pci地址,比如"0000:03:02.3"。
- vlan (int, optional): VF的VLAN
- vlanQoS (int, optional): VF的VLAN QoS(0-7),这个依赖vlan配置,不能为0。
- mac (string, optional): VF的MAC
- ipam (dictionary, required): 使用的IPAM配置
- spoofchk (string, optional): VF的报文欺骗检查开关。
- trust (string, optional): VF的信任设置开关。
- link_state (string, optional): VF的连接状态,支持auto, enable, disable。这个取决于网卡驱动的支持程度,比如i40e支持,igb不支持。
- min_tx_rate (int, optional): 更改VF允许的最小传输带宽(Mbps),将此设置为0将禁用速率限制,min_tx_rate应该小于等于max_tx_rate,是否支持此功能取决于NIC和驱动。
- max_tx_rate (int, optional): 同上。
代码
原版
cmdAdd操作
- 调用LoadConf解析配置以及参数
- 调用ns.GetNS获取当前的namespace
如果是pfOnly不为true的话,调用setupVF寻找一个可用的vf端口
- 如果vfIdx不是0的话,getVFDeviceName会获取vf对应的端口
- 如果vfIdx为0的话,allocFreeVF会寻找一个可用的vf端口
- netlink.LinkByName获取vf端口的句柄
- netlink.LinkSetUp up端口
- netlink.LinkSetNsFd将端口配置到namespace中
- netlink.LinkByName获取pf端口的句柄
- net.ParseMAC解析配置中的mac地址
- netlink.LinkSetVfHardwareAddr将mac地址配置给namespace中的vf端口
- netlink.LinkSetVfVlan给namespace中的vf端口配置vlan
- 在namespace中调用renameLink将vf端口名称修改为namespace中的端口名称
如果pfOnly是true的话,调用setupPF寻找一个可用的pf端口
- netlink.LinkByName获取pf端口的句柄
- netlink.LinkSetUp up端口
- netlink.LinkSetNsFd将端口配置到namespace中
- 在namespace中调用renameLink将vf端口名称修改为namespace中的端口名称
- ipam.ExecAdd获取ip地址
- 在namespace中调用ipam.ConfigureIface将IP配置给端口
cmdDel操作
- 调用LoadConf解析配置以及参数
- 调用ns.GetNS获取当前的namespace
如果是pfOnly不为true的话,调用releaseVF释放vf
- ns.GetCurrentNS获取当前的namespace
- 在容器中做以下所有的操作
- netlink.LinkByName获取容器中的端口句柄
- netlink.LinkSetDown down掉端口
- renameLink更改回原来的名字
- netlink.LinkSetNsFd将端口从namespace中移回宿主机
如果pfOnly是true的话,调用releasePF释放pf
- ns.GetCurrentNS获取当前的namespace
- 在容器中做以下所有的操作
- netlink.LinkByName获取容器中的端口句柄
- netlink.LinkSetDown down掉端口
- renameLink更改回原来的名字
- netlink.LinkSetNsFd将端口从namespace中移回宿主机
- ipam.ExecDel释放IP
Intel版本
cmdAdd操作
调用config.LoadConf解析配置以及参数
- 调用json.Unmarshal解析配置
- 如果配置了DeviceID,则调用getVfInfo获取pf名字以及vfID
- 调用utils.GetVFLinkNames根据给定的pci地址获取端口名字,如果没有找到则调用utils.HasDpdkDriver查看该端口是否有dpdk驱动
- getEnvArgs-->types.LoadArgs解析参数
- 调用ns.GetNS获取当前的namespace
sm.ApplyVFConfig存储vf的配置
- s.nLink.LinkByName获取vf的句柄
- 如果有vlan的配置项,会继续判断vlanqos的配置,如果有则调用s.nLink.LinkSetVfVlanQos配置,没有则只配置vlan,调用s.nLink.LinkSetVfVlan
- 如果有mac配置项,则调用net.ParseMAC解析mac地址,然后调用getVfInfo获取之前的mac,并且保存起来,调用s.nLink.LinkSetVfHardwareAddr将配置的mac地址配置到端口
- 如果配置了速率限制,调用s.nLink.LinkSetVfRate设置速率限制
- 如果配置了spoofchk,则调用s.nLink.LinkSetVfSpoofchk进行配置
- 如果配置了trust,则调用s.nLink.LinkSetVfTrust
- 如果配置了link state,则调用s.nLink.LinkSetVfState
- 如果是dpdk模式,调用utils.SaveNetConf存储配置信息,为了后续的cmdDel使用,直接返回,不做后续操作
sm.SetupVF配置vf,并且转移到namespace中
- s.nLink.LinkByName获取端口句柄
- s.nLink.LinkSetDown设置端口为down
- s.nLink.LinkSetName修改端口名字
- net.ParseMAC解析mac地址,s.nLink.LinkSetHardwareAddr设置mac
- s.nLink.LinkSetNsFd将端口转移到namespace
- 在namespace中调用s.nLink.LinkSetName修改端口名称
- 在namespace中调用s.nLink.LinkSetUp使端口up
- 如果配置了IPAM,则调用ipam.ExecAdd申请IP地址,在namespace中执行ipam.ConfigureIface配置IP地址
- 调用utils.SaveNetConf保存配置,为后续的cmdDel使用。
cmdDel操作
- 调用config.LoadConfFromCache从之前存储的缓存中获取配置
如果不是dpdk模式,配置了IPAM的话,调用ipam.ExecDel释放之前申请的IP,然后获取配置的namespace,如果不存在直接退出,如果存在则调用sm.ReleaseVF释放vf
- 以下操作都是namespace中进行
- s.nLink.LinkByName获取vf的句柄
- s.nLink.LinkSetDown设置端口为down
- s.nLink.LinkSetName修改端口名字
- 如果有mac的配置,则需要调用net.ParseMAC获取之前的有效mac,然后调用s.nLink.LinkSetHardwareAddr设置mac
- s.nLink.LinkSetNsFd将namespace中的端口移出来
sm.ResetVFConfig恢复vf配置
- s.nLink.LinkByName获取vf的句柄
- 只配置了vlan的话调用s.nLink.LinkSetVfVlan将vlan配置为0,如果也配置了vlanqos的话,不调用前面,直接调用s.nLink.LinkSetVfVlanQos,将vlan配置为0,qos也配置为0
- 配置了mac的话,调用net.ParseMAC解析admin mac,然后调用s.nLink.LinkSetVfHardwareAddr将mac恢复
- s.nLink.LinkSetVfSpoofchk将spoofchk设置为on
- s.nLink.LinkSetVfTrust将trust配置为off
- s.nLink.LinkSetVfRate关闭限速
- 如果配置过linkstate的话,调用s.nLink.LinkSetVfState将连接状态设置为auto
cmdCheck
无代码
6 条评论
你的文章内容非常专业,让人佩服。 https://www.4006400989.com/qyvideo/83555.html
你的文章内容非常精彩,让人回味无穷。 http://www.55baobei.com/EBe5M9jAuQ.html
想想你的文章写的特别好www.jiwenlaw.com
不错不错,我喜欢看 https://www.ea55.com/
想想你的文章写的特别好https://www.237fa.com/
博主真是太厉害了!!!