最近由于科研的需要,安装了这个SDN的P4环境,不得不说这个过程真的是异常多的bug,装了一周才装好,总结这一周以来的错误,下面告诉大家如何一次性的安装好。(特别提醒,希望你是直接看到这篇文章后来安装的,因为在自己安装的过程中如果出现版本错误而没有把配置好的环境删除干净的话,安装过程基本就卒了啊!)
所以推荐安装前满足以下条件之一:
话不多说,直接进入安装整体把。安装过程大家可能会参考各种网上的文档,这里强烈建议大家安装官网github给的安装流程https://github.com/p4lang/tutorials/blob/master/vm/user-bootstrap.sh,然后结合SDNLAB的一篇命令改进后的优秀文章P4编程理论与实践(2)—快速上手一起来看,保证整个过程尽量只有Ctrl+C和Ctrl+V的操作。
这里我使用的版本是:
希望大家版本尽量和我保持一致,接下来就开始进入正题。我们一共主要需要安装5个组件:
在搭建之前为了不破坏原环境的整洁性,我们还是在home目录下创建一个P4的工作目录,并且加入环境变量:
mkdir ~/P4
cd ~/P4
echo "P4_HOME=$(pwd)" >> ~/.bashrc
source ~/.bashrc
先安装一些依赖项:(依赖项的安装很重要,不然等会会出各种问题)
sudo apt-get update
sudo apt-get install automake cmake libjudy-dev libpcap-dev libboost-dev libboost-test-dev libboost-program-options-dev libboost-system-dev libboost-filesystem-dev libboost-thread-dev libevent-dev libtool flex bison pkg-config g++ libssl-dev -y
sudo apt-get install cmake g++ git automake libtool libgc-dev bison flex libfl-dev libgmp-dev libboost-dev libboost-iostreams-dev libboost-graph-dev llvm pkg-config python python-scapy python-ipaddr python-ply tcpdump curl -y
sudo apt-get install libreadline6 libreadline6-dev python-pip -y
sudo pip install psutil
sudo pip install crcmod
接下来就是结合上面的两篇文章开始搭建了
在我写这篇文章时,P4的官网github的安装流程给的Bmv2,PI,P4C,PROTOBUF,GRPC版本如下:
# 打印脚本命令.
set -x
# 在有错误输出时停止.
set -e
# 设置相关路径和版本变量
P4_HOME=$HOME/P4
BMV2_COMMIT="884e01b531c6fd078cc2438a40258ecae011a65b" # Apr 24, 2019
PI_COMMIT="19de33e83bae7b737a3f8a1c9507c6e84173d96f" # Apr 24, 2019
P4C_COMMIT="61409c890c58d14ec7d6790f263eb44f393e542a" # Apr 24, 2019
PROTOBUF_COMMIT="v3.2.0"
GRPC_COMMIT="v1.3.2"
#获得cpu核数,与某些软件的编译选项相关
NUM_CORES=`grep -c ^processor /proc/cpuinfo`
大家自己安装的时候一定要时刻关注版本的变化,要按照官网github给的版本安装才尽量不会出现问题(朋友们,我就是因为设置的版本路径是旧版的,在P4环境搭建后无法运行最新版的tutorials中的basic实例 )
首先是Mininet的安装:mininet的功能是构建一个虚拟的网络拓扑。 它通过linux内核的一些特性(net命名空间),在一个主机上划分出多个虚拟网络空间,各个网络空间之间相互隔离,有自己的端口, ip等等。mininet让一个或者多个vhost(虚拟主机), 软件交换机(如ovs, bmv2)等 以进程的状态分别绑定在这些网络空间之中,共同构成一个进程级别的虚拟网络拓扑。需要注意的是这些进程级别的主机和交换机他们只是网络上的隔离,而文件系统则是共享主机的文件系统。
命令行如下:
cd $P4_HOME
# 安装Mininet
git clone git://github.com/mininet/mininet mininet
cd mininet
sudo ./util/install.sh -nwv
cd ..
很easy就可以实现这一步。
这个组件是重点安装的对象,一定要仔细,它一旦安装错误就会导致后面组件安装各种报错。
安装Protobuf
git clone https://github.com/google/protobuf.git
cd protobuf
git checkout ${PROTOBUF_COMMIT}
export CFLAGS="-Os"
export CXXFLAGS="-Os"
export LDFLAGS="-Wl,-s"
./autogen.sh
./configure --prefix=/usr
make -j${NUM_CORES}
make check -j${NUM_CORES}
sudo make install
sudo ldconfig
unset CFLAGS CXXFLAGS LDFLAGS
# force install python module
cd python
sudo python setup.py install
cd ../..
要注意这里的git checkout ,一定要checkout,不然它会默认下载最新版的protobuf,在最后运行实例的时候会报如下的错:No module named protobuf.internal,这就是版本的问题(我在下载的时候为3.9.0,但是python2.7目前只支持最高3.8.0的),由于P4的测试都是基于3.2.0版本的,所以建议大家还是安装老版本的。
make check -j这条命令也很重要,它会检测安装的protobuf是否通过所有的测试,如果没有100% 通过务必要找到原因再继续往下安装。
gRPC使客户端和服务器应用程序能够透明地进行通信,并简化了连接系统的构建。关于它的解释自己在命令行中找到github网址去查看吧:
git clone https://github.com/grpc/grpc.git
cd grpc
git checkout ${GRPC_COMMIT}
git submodule update --init --recursive
export LDFLAGS="-Wl,-s"
make -j${NUM_CORES}
sudo make install
sudo ldconfig
unset LDFLAGS
cd ..
# Install gRPC Python Package
sudo pip install grpcio
这里一般会比较顺利,除了下载速度。
这一步没有完全安装bmv2,一切都是按照github上的指示来操作的,先安装BMv2的依赖,下面PI编译时会用到。behavioral-model又叫bmv2交换机模块,安装命令如下:
# 安装BMv2的依赖,下面PI编译时会用到。
git clone https://github.com/p4lang/behavioral-model.git
cd behavioral-model
git checkout ${BMV2_COMMIT}
# From bmv2's install_deps.sh, we can skip apt-get install.
# Nanomsg is required by p4runtime, p4runtime is needed by BMv2...
tmpdir=`mktemp -d -p .`
cd ${tmpdir}
bash ../travis/install-thrift.sh
bash ../travis/install-nanomsg.sh
sudo ldconfig
bash ../travis/install-nnpy.sh
cd ..
sudo rm -rf $tmpdir
cd ..
这里在运行install-thrift.sh和nanomsg.sh文件时会出现一些问题:无法连接到下载thrift源码包的网址,http://archive.apache.org/dist/thrift/0.9.2/thrift-0.9.2.tar.gz, 这里给大家提供下载的链接链接:https://pan.baidu.com/s/1t5YUm79PtoLkzFt91UDTgw
提取码:55sl
对应的,将install-thrift.sh文件中的这两行注释掉:
#wget http://archive.apache.org/dist/thrift/0.9.2/thrift-0.9.2.tar.gz
#tar -xzvf thrift-0.9.2.tar.gz
然后插入如下一行代码,也就是thrift-0.9.2的绝对路径,也就是behavioral-model下的thrift-0.9.2目录的位置,修改后保存文件。参考P4使用Ubuntu中安装教程这篇文章中的图来给大家一个直观的感受:
nanomsg.sh文件的修改方式和thrift文件一样,nnpy文件不需要修改可以直接用。至此,依赖项已完成。
PI是P4 runtime的实现,用于Control Plane对数据平面的控制。
# PI/P4Runtime
git clone https://github.com/p4lang/PI.git
cd PI
git checkout ${PI_COMMIT}
git submodule update --init --recursive
./autogen.sh
./configure --with-proto
make -j${NUM_CORES}
sudo make install
sudo ldconfig
cd ..
刚刚只是安装了bmv2的依赖,现在开始才是正式安装:
# 安装Bmv2
cd behavioral-model
./autogen.sh
./configure --enable-debugger --with-pi
make -j${NUM_CORES}
make check -j${NUM_CORES}
sudo make install
sudo ldconfig
# Simple_switch_grpc target
cd targets/simple_switch_grpc
./autogen.sh
./configure --with-thrift
make -j${NUM_CORES}
sudo make install
sudo ldconfig
cd ..
cd ..
cd ..
这里多了个Simple_switch_grpc的安装,它是支持P4 Runtime的SimpleSwitch版本,这个东西的安装很关键,否则最后的示例也是无法运行的,不过只要你前面安装的都没有问题,这里也不会有啥问题,如果除了问题,推荐github上的Simple_switch_grpc来看是否依赖项出了问题。至此,你已经无限接近最后的成功了,就差最后一个组件了!
这个组件非常关键,它是p4语言的编译器,而且对于它一定要注意版本的问题,因为目前github上p4lang官网的人还在一直维护更新,所以语法经常有变化,如果你不下载最新的版本,那么很有可能最后实例测试的时候就会因为语法问题而game over,所以每一步的git checkout的版本很关键。
# 安装P4C
git clone https://github.com/p4lang/p4c
cd p4c
git checkout ${P4C_COMMIT}
git submodule update --init --recursive
mkdir -p build
cd build
cmake ..
make -j${NUM_CORES}
make check -j${NUM_CORES}
sudo make install
sudo ldconfig
cd ..
cd ..
这里在安装cmake的时候会报一个错误:(如果一切顺利当然就不用管下面的了)
-- Found LLVM 3.8.0
-- Added 14 tests to 'ebpf-bcc' (0 xfails)
-- Added 14 tests to 'ebpf' (0 xfails)
-- Added 5 tests to 'p4' (0 xfails)
-- Added 533 tests to 'p4' (5 xfails)
-- Added 5 tests to 'err' (0 xfails)
-- Added 160 tests to 'err' (0 xfails)
-- Added 207 tests to 'p14_to_16' (0 xfails)
-- CTest parallel: -j 4
-- Configuring incomplete, errors occurred!
See also "/home/ilya/p4/p4c/build/CMakeFiles/CMakeOutput.log".
See also "/home/ilya/p4/p4c/build/CMakeFiles/CMakeError.log".
若出现以上类似错误,参考github中的issue,具体的命令为:
cmake .. -DENABLE_EBPF=OFF
就可以顺利通过,这里如果make check -j没有全部通过也没关系,也可以顺利安装。当然你也可以检查去p4c的github上看看还有啥依赖项遗落了。至此,如果你全部安装成功了,那么恭喜你,下面就是你的验收了!!
没啥好说的。
# 最后获得p4 tutorials
git clone https://github.com/p4lang/tutorials
至此安装完成之后,现在P4目录下面应该是这个样子:
P4
├── behavioral-model ## BMv2 软件交换机
├── grpc ## 作为BMv2的依赖
├── mininet ## mininet 网络仿真
├── p4c ## p4c 编译器
├── PI ## PI P4 runtime库
├── protobuf ## 作为依赖
└── tutorials #### 教程目录,以及以后主要的学习,实验
我们主要的工作目录时tutorials,其余的都是被使用的工具组件。细看tutorials:
tutorials/
├── exercises # 存放各种练习
├── utils # 工具脚本目录
└── vm # 用于vagrant构建虚拟机的目录,可以无视
其中utils里面存放了一些用于调用各个组件(mininet, bmv2, PI, p4c)的脚本,有了这些脚本,我们可以专注于p4代码的开发,控制面的编写,以及拓扑的构建,而不需要费神去了解bmv2的启动命令,p4c的调用选项等等。具体如何使用,也是非常的简单,我们进入一个具体的例子查看:
# 我们切换进入 exercises/basic 这个例子
basic
├── basic.p4 # 要编写的p4代码
├── build # 生成文件的目录
├── logs # 日志文件, 在调试的时候真的非常重要!
├── Makefile ### 通过Makefile 来调用utils下的脚本!
├── pcaps # 生成的pcap包,可以使用wireshark等工具来分析
├── README.md # 详细的指导
├── receive.py ## 利用scapy写的抓取和分析数据包的工具
├── s1-runtime.json #
├── s2-runtime.json # 在运行同时加载入交换机的控制面代码,这里有争议,稍后再谈
├── s3-runtime.json #
├── send.py ## 利用scapy写的构建和发送数据包的工具
├── solution # 这里有这个例子的示例代码(答案)
└── topology.json # 描述拓扑的json文件
可以看到,通过Makefile,我们可以调用utils下的脚本,让我们的p4代码跑起来,具体的操作步骤参看github网址https://github.com/p4lang/tutorials/tree/master/exercises/basic::
#
#This will:
#compile basic.p4, and
#start a Mininet instance with three switches (s1, s2, s3) configured in a triangle, each connected to one host (h1, h2, and h3).
#The hosts are assigned IPs of 10.0.1.1, 10.0.2.2, and 10.0.3.3.
#
make run
#you should now see a Mininet command prompt. Open two terminals for h1 and h2, respectively:
mininet> xterm h1 h2
#Each host includes a small Python-based messaging client and server. In h2's xterm, start the server:
./receive.py
#In h1's xterm, send a message to h2:
./send.py 10.0.2.2 "P4 is cool"
#Type exit to leave each xterm and the Mininet command line. Then, to stop mininet:
make stop
#And to delete all pcaps, build files, and logs:
make clean
那么恭喜你成功运行!!
建议大家遇到问题在官网github中各自的组件安装的issue里面去查找解决问题的方法!此外就是不要放弃,即使反复的失败也不要灰心,这玩意就是这么麻烦!