dpvs入门实践1--概念及编译安装

DPVS是一种基于DPDK的高性能四层负载均衡器。它来源于Linux Virtual Server LVS及其修改后的alibaba/LVS. 那LVS是什么呢?Linux Virtual Server是构建在实服务器集群上的高度可伸缩和高可用的服务器,负载平衡器运行在Linux操作系统上。服务器集群的架构对最终用户是完全透明的,用户之间的交互就好像它是一个高性能的虚拟服务器。因此,DPVS使用了LVS里面的核心概念(这些在http://www.linuxvirtualserver.org/zh/index.html官网有详细说明,这里做个摘要):

  • NAT: 通过网络地址转换,调度器重写请求报文的目标地址,根据预设的调度算法,将请求分派给后端的真实服务器;真实服务器的响应报文通过调度器时,报文的源地址被重写,再返回给客户,完成整个负载调度过程。
  • TUN: 采用NAT技术时,由于请求和响应报文都必须经过调度器地址重写,当客户请求越来越多时,调度器的处理能力将成为瓶颈。为了解决这个问题,调度器把请求报 文通过IP隧道转发至真实服务器,而真实服务器将响应直接返回给客户,所以调度器只处理请求报文。由于一般网络服务应答比请求报文大许多,采用 VS/TUN技术后,集群系统的最大吞吐量可以提高10倍。
  • DR: 通过改写请求报文的MAC地址,将请求发送到真实服务器,而真实服务器将响应直接返回给客户。同VS/TUN技术一样,VS/DR技术可极大地 提高集群系统的伸缩性。这种方法没有IP隧道的开销,对集群中的真实服务器也没有必须支持IP隧道协议的要求,但是要求调度器与真实服务器都有一块网卡连 在同一物理网段上。
  • FNAT: IPVS的一种新的报文转发方式,区别于DR/NAT/TUNNEL. 该模式处理原则如下:引入local ip address(即IDC 内部ip地址lip), IPVS转换cip(client ip)--vip to/from lip--rip(remote ip),这里lip和rip都是IDC内部IP地址,因此LVS负载均衡器和真实服务器可以在不同的vlan,真实的服务器只需要能访问到内网即可。

其他概念:

  • 单臂(one arm): 指所有的客户端和服务器都在负载均衡器的同一侧,LB通过相同的逻辑网络接口转发流量。
  • 双臂(two arms): 客户机位于负载平衡器(LB)的一端,服务器位于负载平衡器(RS)的另一端,然后LB在其两个逻辑网络接口之间转发数据包。例如广域网到局域网的负载均衡.

编译安装

虽然github官方上说明不再支持dpdk-stable-20.11.1之前的版本了,但是目前新分支还出与开发阶段,我没有编译通过。所以我用的版本还是dpdk18.11.2 + dpvs1.8. 首先安装dpvs1.8版本在github上的官方介绍一样下载1.8版本的dpvs源代码。

$ git clone https://github.com/iqiyi/dpvs.git
$ cd dpvs

下不来的话可以直接去码云网站https://gitee.com 下载release包。然后进到dpvs目录,再下载dpdk源码:

$ wget https://fast.dpdk.org/rel/dpdk-20.11.1.tar.xz   # download from dpdk.org if link failed.
$ tar xf dpdk-20.11.1.tar.xz

接下来打补丁,在打补丁之前我们先来安装一些工具包防止在后面的编译过程中报错,有的话可以跳过:

yum install  python3 (Python 3.5 or later.)	
pip3 install meson ninja //Meson (version 0.49.2+) and ninja
pip3 install pyelftools 或者yum install pyelftools
yum install -y popt-devel automake libnl3 libnl3-devel openssl openssl-devel numactl kernel-devel libpcap-devel unzip patch numactl-devel

另外,注意安装gcc前要安装和内核版本匹配的kernel-devel, 查看 ls /usr/src/kernels/, 并且 ldd --version 查看glibc版本要求 glibc >= 2.7(拜托2.17 大于 2.7)

编译dpdk

在编译dpvs之前要先编译DPDK:

cd dpvs-1.8/
cp patch/dpdk-stable-18.11.2/*.patch dpdk-stable-18.11.2/
cd dpdk-stable-18.11.2/
patch -p1 < 000
...
make config T=x86_64-native-linuxapp-gcc
make
export RTE_SDK=$PWD
export RTE_TARGET=build

echo 8192 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
echo 8192 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
// 如果很多个numa节点,可以用如下命令:
for i in {0..7};do echo 8192 > /sys/devices/system/node/node$i/hugepages/hugepages-2048kB/nr_hugepages;done

mkdir /mnt/huge
mount -t hugetlbfs nodev /mnt/huge
grep Huge /proc/meminfo
 # 需要开机自动挂载的话可以在
 $ echo "nodev /mnt/huge hugetlbfs defaults 0 0" >> /etc/fstab

modprobe uio
cd dpdk-stable-18.11.2
insmod build/kmod/igb_uio.ko
insmod build/kmod/rte_kni.ko carrier=on
./usertools/dpdk-devbind.py --status
// 172.18.8.129: eno4 100.200.0.129  30:fd:65:32:e8:c3  0000:1a:00.3
// 172.18.8.129: eno1                30:fd:65:32:e8:c0  0000:1a:00.0
ifconfig eno4 down
./usertools/dpdk-devbind.py -b igb_uio 0000:1a:00.3
./usertools/dpdk-devbind.py --status

./usertools/dpdk-devbind.py -u 0000:1a:00.0
./usertools/dpdk-devbind.py -b i40e 0000:1a:00.0

学习地址:Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家(免费订阅,永久学习)

【文章福利】需要更多DPDK/SPDK学习资料加群793599096(资料包括C/C++,Linux,golang技术,内核,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,大厂面试题 等)可以自行添加学习交流群点击这里噢~

编译dpvs

编译dpvs比较简单,只需要配置export PKG_CONFIG_PATH=/opt/sj/dpvs-1.8/dpdk-stable-18.11.2/dpdklib/lib64/pkgconfig/libdpdk.pc 然后到dpvs目录下编译即可

cd ..
make // 报 inline 函数未定义的错误,需要在 src/Makefile CFLAGS 参数最后-mcmodel=medium之前加上 -fgnu89-inline
make install

运行DPVS

拷贝./conf/下合适的配置文件到 /etc/dpvs.conf
总结一下,我遇到过的问题:

  1. 运行./bin/dpvs 如果报段错误退出则需要调整配置文件中的pktpool_size,我猜测是因为这个值太大了导致内存不足。可以把这个值改小一些,并且屏蔽一些cpu,减少消耗。我这样操作之后能跑起来了。
  2. 我遇到另外一个coredump退出的情况,使用1中的方法不生效。于是我打开src/Makefile中的DEBUG开关,用gdb跑dpvs,因为不知道断点在哪里只能run,得到的信息如下,基本没用
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff440d700 (LWP 47658)]
0x00000000006162f9 in conn_term_lcore ()
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7.x86_64 libgcc-4.8.5-16.el7.x86_64 li.0.2k-24.el7_9.x86_64 zlib-1.2.7-19.el7_9.x86_64

于是,我又打开了/etc/dpvs.conf中的log_level为DEBUG,再次启动程序得到有效信息如下所示:

EAL: rte_mem_virt2phy(): cannot open /proc/self/pagemap: Too many open files

应该是系统允许最大打开文件数太小所致,用ulimit -a查看果然只有1024,用ulimit -n 1048576改成较大的数量,再次启动DPVS进程这次可以了。
3. 报错“DPVS_MAX_SOCKET is smaller than system numa nodes!”,查看源码发现是numa节点数小于系统常量DPVS_MAX_SOCKET,再次查找这个DPVS_MAX_SOCKET,发现它是在src/config.mk文件中定义并被编译到源码里,因此需要修改成numa节点数(numactl --hardware查看numa节点数)并再次编译。

猜你喜欢

转载自blog.csdn.net/lingshengxiyou/article/details/130175032
今日推荐