
SRIOV 与 DPDK
SRIOV 基本介绍
PCI 简介
简单来讲:物理主机网卡资源直接挂载到虚拟机使用,不需要经过hypervisor的模拟和过滤,虚拟机发的命令直接送到物理设备。
PCIE 简介
由于PCI只支持一种规格的卡槽,而PCIE支持不同类型大小规格的卡曹,可以看作PCI的升级版。功能都一样的。
SR-IOV 简介
我们知道一台主机上肯定可以创建出不止一台虚拟机,但是PCIE硬件物理网卡设备只有一台所以根本不够分。所以SR-IOV就诞生了,主要作用于把物理网卡分成网卡池,这样就够用了。
SR-IOV 使用 physical functions (PF) 和 virtual functions (VF) 为 SR-IOV 设备管理全局功能。
PF:包含SR-IOV功能的完整PCIe设备,PF作为普通的PCIe设备被发现、管理和配置。PF通过分配VF来配置和管理SR-IOV功能。禁用SR-IOV后,主机将在一个物理网卡上创建一个PF。
VF:是轻量级PCIe功能(I/O 处理)的PCIe设备,每个VF都是通过PF来生成管理的,VF的具体数量限制受限于PCIe设备自身配置及驱动程序的支持,启用SR-IOV后,主机将在一个物理NIC上创建单个PF和多个VF。VF的数量取决于配置和驱动程序支持。
每个SR-IOV设备都可有一个PF(Physical Functions),并且每个PF最多可有64,000个与其关联的 VF(Virtual Function)。PF 可以通过寄存器创建VF,这些寄存器设计有专用于此目的的属性。一旦在PF中启用了 SR-IOV,就可以通过PF的总线、设备和功能编号(路由 ID)访问各个VF的PCI配置空间。
每个VF都具有一个PCI内存空间,用于映射其寄存器集。VF设备驱动程序对寄存器集进行操作以启用其功能,并且显示为实际存在的PCI设备。创建 VF
后,可以直接将其指定给虚拟机或各个应用程序。此功能使得虚拟功能可以共享物理设备,并在没有CPU和虚拟机管理程序软件开销的情况下执行 I/O。
DPDK简介
从前面的分析得知目前网络IO的实现的方式中,内核是导致性能瓶颈的原因所在,要解决性能问题就需要绕过内核,直接在用户态收发包。
1、内核bypass:通过UIO(Userspace I/O)旁路数据包,实现用户态数据包收发,减少上下文切换以及内存拷贝。
2、使用多核编程代替多线程编程:设置 CPU 的亲和性,将线程和 CPU 核进行一比一绑定,减少彼此之间调度切换。
3、使用大页内存代替普通的内存:减少 cache-miss。
4、采用无锁技术:解决资源竞争问题。
预先准备
前提
首先需要确保VT-D
在BIOS层中的启动。
根据您使用的NIC,全局和/或每个NIC启用SRIOV功能,例如,应在BIOS级别为每个NIC禁用Intel x710。
升级内核引导行以启用intel_iomu=on
和iommu=pt
grubby --update-kernel=ALL --args="iommu=pt intel_iommu=on"
reboot
巨页(Hugepage)的支持
大多数网络应用程序使用巨大的页面,因此您可能需要启用该功能。请编辑/etc/default/grub
并添加Hugepage.
GRUB_CMDLINE_LINUX="nofb nomodeset vga=normal iommu=pt intel_iommu=on default_hugepagesz=1G hugepagesz=1G hugepages=16"
#Rebuild grub.cfg
grub2-mkconfig -o /boot/grub2/grub.cfg && reboot
配置创建与安装
安装SRIOV的yaml文件。
git clone https://github.com/k8snetworkplumbingwg/sriov-cni.git
cd sriov-cni
kubectl apply -f images/k8s-v1.16/sriov-cni-daemonset.yaml
创建SRIOV配置文件。
vim sriovdp-config.yaml
pfNames
表示物理网卡的名字,em1#0-6
表示em1物理网卡分出0-6个VF。drivers
表示设备注册的驱动程序名称。
apiVersion: v1
kind: ConfigMap
metadata:
name: sriovdp-config
namespace: kube-system
data:
config.json: |
{
"resourceList": [{
"resourceName": "intel_sriov_kernel0",
"selectors": {
"pfNames": ["em1#0-6"],
"drivers": ["igbvf"]
}
}
]
}
kubectl apply -f sriovdp-config.yaml
git clone https://github.com/k8snetworkplumbingwg/sriov-network-device-plugin.git
cd sriov-network-device-plugin
kubectl apply -f images/k8s-v1.16/sriov-cni-daemonset.yaml
创建网络连接定义SR-IOV类型。
请复制粘贴以下定义更新子网的值并将其应用于我们的群集:
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: sriov-kernelnet0
annotations:
k8s.v1.cni.cncf.io/resourceName: intel.com/intel_sriov_kernel0
spec:
config: '{
"type": "sriov",
"cniVersion": "0.3.1",
"name": "sriov-kernelnet0",
"spoofchk": "off",
"type": "sriov",
"vlan": 80,
"ipam": {
"type": "whereabouts",
"range": "192.168.80.0/24",
"range_start": "192.168.80.20",
"range_end": "192.168.80.50",
"gateway": "192.168.80.1"
}
}'
主密钥值是对工作节点中的 *_second nic*_
的引用。
kubectl apply -f networkattachdefinition-sriov.yaml
网络连接定义验证SR-IOV类型
让我们通过列出和描述新的网络连接定义来验证我们的工作
kubectl get net-attach-def
使用SR-IOV接口创建Pod(内核驱动程序)
vim pod0-case3.yaml
$ cat pod0-case3.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod0-case-03-sriov-kernel
annotations:
k8s.v1.cni.cncf.io/networks: sriov-kernelnet0
spec:
containers:
- name: pod0-case-03
image: docker.io/centos/tools:latest
command:
- /sbin/init
resources:
requests:
intel.com/intel_sriov_kernel0: '1'
limits:
intel.com/intel_sriov_kernel0: '1'
kubectl apply -f pod0-case3.yaml
kubectl exec pod0-case-03 -- ethtool -i net2
kubectl exec pod0-case-03 -- ethtool -i net1
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739


默认昵称
mac地址会更改但vxlan解析后mac地址除了源mac地址改为cni0的地址外目的mac是c3 pod的mac. 这里的源地址是被改为flannel.1的mac地址吧 ,你这里写的是cni0的地址