前言
最近在做NFV相关的优化工作。在进行优化过程中需要对优化结果进行实时测试,以来确定优化手段是否有效果。由于公司并没有专业的发包机。而传统的netperf/iperf在10G场景下,64的小包很难发到限速。所以转而寻找其他工具来进行代替。刚好遇到了DPDK-Pktgen这个工具,完美的解决了我遇到的问题。
DPDK-Pktgen的安装
DPDK-Pktgen其实就是DPDK的一个应用,它类似于linux原生的pktgen,通过自己构造数据包,然后发送。而DPDK-Pktgen做的更强大,他可以通过用lua脚本或者json编辑自己的测试过程,同时输出自己关心的数据,比如发送,接收的数据包数量,流量带宽等等。
这里先简单介绍下安装DPDK-Pktgen,DPDK-Pktgen的安装和DPDK的其他应用其实是一样的。首先需要安装DPDK。这个就不在赘述了。
export RTE_SDK=<installDir>/Pktgen-DPDK/dpdk
export RTE_TARGET=x86_64-pktgen-linuxapp-gcc
然后
cd examples/pktgen
make
这样就编译完成了,在目录app/build/pktgen 就是编译出来的程序。
DPDK-Pktgen的使用
DPDK-Pktgen可以自己定义数据包的发送方式,下面就是使用的一个实例
./app/build/pktgen -c f -n 3 --proc-type auto --socket-mem 256,256 -- -T -P -m "[1:3].0, [2:4].1" -f test/set_seq.lua
-c 是指选择的core的掩码,f等于1111也就是选择 1、2 、3、4 core;
--proc-type 选择的auto ,如果是当前系统第一执行的dpdk相关的程序,选择primary模式,如果是第二是secondary 模式;
--file-prefix pg 设置/mnt/huge/内存分配模块的文件名前缀;
-P 使能网络混装模式,
-m "2.0, 3.1" 是指一个矩阵模型,2.0是指,在2号lcore上绑定的端口0 , 3.1是指在lcore3上绑定端口1
-f test/set_seq.lua 导入pktgen的执行配置文件;在执行pktgen时,利用配置产生数据包;
这里对于数据包的发送就是在set_seq.lua中进行描述的。
local seq_table = { -- entries can be in any order
["eth_dst_addr"] = "0011:4455:6677",
["eth_src_addr"] = "0011:1234:5678",
["ip_dst_addr"] = "10.12.0.1",
["ip_src_addr"] = "10.12.0.1/16", -- the 16 is the size of the mask value
["sport"] = 9, -- Standard port numbers
["dport"] = 10, -- Standard port numbers
["ethType"] = "ipv4", -- ipv4|ipv6|vlan
["ipProto"] = "udp", -- udp|tcp|icmp
["vlanid"] = 1, -- 1 - 4095
["pktSize"] = 128 -- 64 - 1518
};
-- seqTable( seq#, portlist, table );
pktgen.seqTable(0, "all", seq_table );
pktgen.set("all", "seqCnt", 1);
可以看到lua文件中就是描述了 要如何发送数据包,包括IP,mac,协议等等。其实就是对pktgen的命令进行了一系列编排。
RFC2544
在我们的工作中,主要是测试虚拟机中的转发性能。测试模型如下:
+-------------------------------+
| +----------------------+ |
| | | |
| | VM | |
| | <--------------> | |
| +--^----------------^--+ |
| +----------------------+ |
| | | OVS | | |
| +----------------------+ |
| | ^ |
| +---+-+ +--+--+ |
| | P0 | | P1 | |
+---+---+-+-----------+--+--+---+
| |
+-------------------------------+
| | TOR | |
+-------------------------------+
| |
| |
+---+---v-+-----------+--v--+---+
| | P0 | | P1 | |
| +-----+ +-----+ |
| |
| 发 包 机 |
| |
| |
+-------------------------------+
这里标准的发包机中都有一个rfc2544的测试套,他就是专门来进行这种转发模型的测试。
DPDK-Pktgen也提供了这个测试方法,在scripts/rfc2544.lua中就定义了这种测试方法。
我们刚好就采用了这一方式来进行测试。
简单描述下rfc2544的测试方式。比如我们测试10G的网络。首先使用64字节的包以5G的带宽进行发送,判断发送的包-接收到的包,如果丢包率超过我们设置的值,则带宽减半,使用2.5G的发送。如果丢包率少于我们设置的值,则使用7.5G进行发送来测试。这样使用2分法,最终得到我们在丢包率允许的情况下,我们的带宽。
在使用中直接使用这个文件会有一些问题,所以还是需要根据实际情况进行修改。
下面把这个文件 简答的解释下
-- RFC-2544 throughput testing.
package.path = package.path ..";?.lua;test/?.lua;app/?.lua;../?.lua"
require "Pktgen";
-- 这里定义了我们要发送的包的大小,这里可以自己随便定义。
local pktSizes = { 64, 128, 256, 512, 1024, 1280, 1518 };
local firstDelay = 3;
local delayTime = 30; -- Time in seconds to wait for tx to stop
local pauseTime = 1;
local sendport = "0";
local recvport = "1";
-- 发包机接收端的IP
local dstip = "192.168.1.1";
-- 发包机发送端的IP
local srcip = "192.168.0.1";
local netmask = "/24";
local pktCnt = 4000000;
-- 虚拟机接收端的mac地址
local mac = "00:00:00:00:00:01"
local foundRate;
pktgen.set_mac(sendport, mac);
pktgen.set_ipaddr(sendport, "dst", dstip);
pktgen.set_ipaddr(sendport, "src", srcip..netmask);
pktgen.set_ipaddr(recvport, "dst", srcip);
pktgen.set_ipaddr(recvport, "src", dstip..netmask);
pktgen.set_proto(sendport..","..recvport, "udp");
--关闭pktgen的实时显示
pktgen.screen("off");
local function doWait(port)
local stat, idx, diff;
-- Try to wait for the total number of packets to be sent.
local idx = 0;
while( idx < (delayTime - firstDelay) ) do
stat = pktgen.portStats(port, "port")[tonumber(port)];
diff = stat.ipackets - pktCnt;
print(idx.." ipackets "..stat.ipackets.." delta "..diff);
idx = idx + 1;
if ( diff == 0 ) then
break;
end
local sending = pktgen.isSending(sendport);
if ( sending[tonumber(sendport)] == "n" ) then
break;
end
pktgen.delay(pauseTime * 1000);
end
end
-- 开始进行测试的函数
local function testRate(size, rate)
local stat, diff;
pktgen.set(sendport, "rate", rate);
pktgen.set(sendport, "size", size);
pktgen.clr();
pktgen.delay(500);
pktgen.start(sendport);
pktgen.delay(firstDelay * 1000);
doWait(recvport);
pktgen.stop(sendport);
pktgen.delay(pauseTime * 1000);
stat = pktgen.portStats(recvport, "port")[tonumber(recvport)];
diff = stat.ipackets - pktCnt;
--printf(" delta %10d", diff);
return diff;
end
local function GetPreciseDecimal(nNum, n)
if type(nNum) ~= "number" then
return nNum;
end
n = n or 0;
n = math.floor(n)
if n < 0 then
n = 0;
end
local nDecimal = 1/(10 ^ n)
if nDecimal == 1 then
nDecimal = nNum;
end
local nLeft = nNum % nDecimal;
return nNum - nLeft;
end
local function midpoint(imin, imax)
return (imin + ((imax - imin) / 2));
end
local function doSearch(size, minRate, maxRate)
local diff, midRate;
if ( maxRate < minRate ) then
return 0.0;
end
-- 查找本次需要发送的速率
midRate = midpoint(minRate, maxRate);
--printf(" Testing Packet size %4d at %3.0f%% rate", size, midRate);
--printf(" (%f, %f, %f)\n", minRate, midRate, maxRate);
-- 对带宽进行测试
diff = testRate(size, midRate);
-- 这里允许配置如果 最大速率和最小速率相差 0.0001 就直接退出。
if (maxRate - minRate < 0.0001) then
return foundRate;
end
if ( diff < 0 ) then
printf("\n");
return doSearch(size, minRate, midRate);
elseif ( diff > 0 ) then
printf("\n");
return doSearch(size, midRate, maxRate);
else
if ( midRate > foundRate ) then
foundRate = midRate;
end
if ( (foundRate == 100.0) or (foundRate == 1.0) ) then
return foundRate;
end
if ( (minRate == midRate) and (midRate == maxRate) ) then
return foundRate;
end
return doSearch(size, midRate, maxRate);
end
end
function main()
local size;
pktgen.clr();
pktgen.set(sendport, "count", pktCnt);
print("\nRFC2544 testing... (Not working Completely) ");
-- 根据配置的包,对不同包大小进行测试,并输出最后结果
for _,size in pairs(pktSizes) do
foundRate = 0.0;
printf(" >>> %d Max Rate %3.0f%%\n", size, doSearch(size, 1.0, 100.0));
end
end
main();
测试方式
启动虚拟机,主要是创建如下网卡。这里mac地址和我们rfc2544中配置要对应起来。
<interface type='vhostuser'>
<mac address='00:00:00:00:00:01'/>
<source type='unix' path='/tmp/vhost1' mode='server'/>
<model type='virtio'/>
<driver queues='1'>
<host mrg_rxbuf='off'/>
</driver>
</interface>
<interface type='vhostuser'>
<mac address='00:00:00:00:00:02'/>
<source type='unix' path='/tmp/vhost2' mode='server'/>
<model type='virtio'/>
<driver queues='1'>
<host mrg_rxbuf='off'/>
</driver>
</interface>
在发包机上执行
app/app/x86_64-native-linuxapp-gcc/pktgen -c 0x1f -n 3 -- -P -m "[1:3].0,[2:4].1" -f scripts/rfc2544.lua
作者简介
肖丁 烽火云计算高级虚拟化设计师,多年从事云计算产品的架构设计、软件开发与技术方案编制等工作。长期专注于内核、虚拟化、云计算、容器、分布式等方向的研究,尤其对KVM和XEN虚拟化等产品有较深研究。
原文来自: 云技术实践
声明:所有来源为“聚合数据”的内容信息,未经本网许可,不得转载!如对内容有异议或投诉,请与我们联系。邮箱:marketing@think-land.com
涉农贷款地址识别,支持对私和对公两种方式。输入地址的行政区划越完整,识别准确度越高。
根据给定的手机号、姓名、身份证、人像图片核验是否一致
通过企业关键词查询企业涉讼详情,如裁判文书、开庭公告、执行公告、失信公告、案件流程等等。
IP反查域名是通过IP查询相关联的域名信息的功能,它提供IP地址历史上绑定过的域名信息。
结合权威身份认证的精准人脸风险查询服务,提升人脸应用及身份认证生态的安全性。人脸风险情报库,覆盖范围广、准确性高,数据权威可靠。