安装启动

直接使用 docker 安装最方便!

1
docker pull onosproject/onos

启动,做端口映射,不需要的可以去掉

1
docker run -t -d -p 8181:8181 -p 8101:8101 -p 6653:6653 -p 6640:6640 --name onos onosproject/onos
  • 8181 - REST API 和 GUI
  • 8101 - ONOS CLI
  • 9876 - 集群内通信
  • 6653 - Openflow 通信,OVS 连接控制器使用此端口(流表相关操作)
  • 6640 - OVSDB,OVS 网桥、端口相关的配置

启用应用,用于控制OVS时,打开下面的应用,可通过UI 界面操作,也可在容器中用命令行方式启用。

1
2
3
4
5
6
7
8
docker exec -it onos bash
cd bin
./onos-app localhost activate org.onosproject.openflow-base
./onos-app localhost activate org.onosproject.ofagent
./onos-app localhost activate org.onosproject.fwd
./onos-app localhost activate org.onosproject.drivers.ovsdb
./onos-app localhost activate org.onosproject.proxyarp
./onos-app localhost activate org.onosproject.lldpprovider

lldpprovider 是用于拓扑发现的,启用该应用后,在 UI/topology 可以看到节点是否有链路直连。

常用页面

  1. UI 页面地址:http://localhost:8181/onos/ui/ 用户名:onos,密码:rocks
  2. RESTFUL 接口文档:http://localhost:8181/onos/v1/docs/
  3. 流表组成说明:https://wiki.onosproject.org/display/ONOS/Flow+Rules
  4. ONOS wiki,也就是官方文档:https://wiki.onosproject.org

连接ONOS CLI

  1. 打开终端并输入以下命令,以连接到ONOS的远程命令行界面:
1
2
phpCopy code
ssh <username>@<onos-ip-address> -p 8101

其中,<username> 是您连接到ONOS的用户名,<onos-ip-address> 是ONOS的IP地址。

  1. 按回车键执行命令,并输入您的密码(如果需要)。
  2. 连接成功后,您将看到ONOS的CLI界面,类似于以下内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
yamlCopy codeWelcome to ONOS
________ ________ ________ ________
|\ __ \|\ __ \|\ __ \|\ ___ \
\ \ \|\ \ \ \|\ \ \ \|\ \ \ \_|\ \
\ \ ____\ \ \\\ \ \ __ \ \ \ \\ \
\ \ \___|\ \ \\\ \ \ \ \ \ \ \_\\ \
\ \__\ \ \_______\ \__\ \__\ \_______\
\|__| \|_______|\|__|\|__|\|_______|

Documentation: wiki.onosproject.org
Tutorials: tutorials.onosproject.org
Mailing lists: lists.onosproject.org

Come help out! Find out how at: contribute.onosproject.org

onos>

现在,您可以在CLI中执行各种ONOS命令以管理和监控ONOS控制器和网络。

清楚所有配置

  1. 打开终端并连接到ONOS的CLI。
  2. 在CLI中输入以下命令以清除缓存:
1
onos> clear storage

按回车键执行命令。

这将清除ONOS的所有缓存,包括网络拓扑、设备、主机、流表等。请注意,在执行此命令之前,您需要确保ONOS控制器已经停止对网络的控制,以避免数据丢失或网络中断。

OVS 连接控制器

  1. 要指定OPENFLOW 协议为 OPENFLOW13,OPENFLOW10仅指定为OPENFLOW13时,连接控制器后将无法使用ofctl查看流表
  2. ovs bridge 连接到控制器后的 deviceIdbridge对应的datapath-id,可以先指定该值,再连接控制器。下发流表时会用到。
1
2
3
4
5
6
ovs-vsctl add-br s1 -- set bridge s1 datapath_type=netdev
ovs-vsctl set bridge s1 other_config:datapath-id=0x0000000000000012
ifconfig s1 192.168.1.12 netmask 255.255.255.0 up

ovs-vsctl set bridge s1 protocols=OpenFlow13,OpenFlow10
ovs-vsctl set-controller s1 tcp:172.17.0.2:6653

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
## 创建容器
sudo docker create --rm -it --name=s1 --privileged -v /dev/hugepages:/dev/hugepages -v /root/run:/root/run ovs-dpdk
sudo docker create --rm -it --name=s2 --privileged -v /dev/hugepages:/dev/hugepages -v /root/run:/root/run ovs-dpdk
sudo docker start s1
sudo docker start s2

## 添加 veth-peer,连接两容器
sudo ip link add p1_2 type veth peer name p2_1 > /dev/null
sudo ip link set dev p1_2 name p1_2 netns $(sudo docker inspect -f '{{.State.Pid}}' s1) up
sudo ip link set dev p2_1 name p2_1 netns $(sudo docker inspect -f '{{.State.Pid}}' s2) up
docker exec -it s1 tc qdisc add dev p1_2 root netem delay 1
docker exec -it s2 tc qdisc add dev p2_1 root netem delay 1

############################### s1 中启动OVS ##################################
ovs-ctl --no-ovs-vswitchd start --system-id=1001
ovs-vsctl --no-wait set Open_vSwitch . other_config:pmd-cpu-mask=0x4
ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-socket-mem="1024"
ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true
ovs-ctl --no-ovsdb-server --db-sock="$DB_SOCK" start

ovs-vsctl add-br s1 -- set bridge s1 datapath_type=netdev
ovs-vsctl set bridge s1 other_config:datapath-id=0x0000000000000012
ovs-vsctl add-port s1 p1_2 -- set Interface p1_2 ofport_request=12
ifconfig s1 192.168.1.12 netmask 255.255.255.0 up

ovs-vsctl set bridge s1 protocols=OpenFlow13,OpenFlow10
ovs-vsctl set-controller s1 tcp:172.17.0.2:6653

############################### s2 中启动OVS ##################################
ovs-ctl --no-ovs-vswitchd start --system-id=1002
ovs-vsctl --no-wait set Open_vSwitch . other_config:pmd-cpu-mask=0x40
ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-socket-mem="1024"
ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true
ovs-ctl --no-ovsdb-server --db-sock="$DB_SOCK" start

ovs-vsctl add-br s2 -- set bridge s2 datapath_type=netdev
ovs-vsctl set bridge s1 other_config:datapath-id=0x0000000000000021
ovs-vsctl add-port s2 p2_1 -- set Interface p2_1 ofport_request=21
ifconfig s2 192.168.1.21 netmask 255.255.255.0 up

ovs-vsctl set bridge s2 protocols=OpenFlow13,OpenFlow10
ovs-vsctl set-controller s2 tcp:172.17.0.2:6653

下发流表

下发的ARP流表只能匹配MAC地址,但一般不需要手动下发。网络拓扑比较小时,也可以通过arp -s {ip} {mac}手动配置。

限制:匹配的以太类型不为IP时,无法匹配目的IP或源IP!即ARP和MPLS类型的,只能和MAC地址一起作为匹配域。实际上这才是正确的,比如MPLS类型的数据包,OVS解析时,并不会解析三层的协议。MPLS是一种隧道协议,并不关心也不会记录下一层的协议类型,因此无法解析。ovs-ofctl并不会提示这种既匹配MPLS标签又匹配IP这种“逻辑”错误。

源码编译

https://gerrit.onosproject.org/plugins/gitiles/onos

https://bazel.build/install/ubuntu

编译 ONOS 镜像

onos仓库中已有写好了的Dockerfile,将整个项目clone到本地后,即可直接编译镜像。该Dockerfile不是从网上下载源码,而是从当前目录COPY,所以修改源码后直接编译就行。

但是 ONOS 编译过程需要从github或一些外网地址下载相关编译工具,导致编译缓慢或者直接失败。需要配置代理使用:

1
docker build --network=host --build-arg http_proxy=http://127.0.0.1:8889 --build-arg https_proxy=http://127.0.0.1:8889  -t onos .

上面的方式在某些情况下已经够用了,但可能卡在onos-gui-npm-install,需要进一步处理。

  • 一种方式是修改 Dockerfile,增加 --action_env 指定代理。
1
2
3
4
5
RUN cat WORKSPACE-docker >> WORKSPACE && bazelisk build onos \
+ --action_env=https_proxy=http://127.0.0.1:8889 \
--jobs ${JOBS} \
--verbose_failures \
--java_runtime_version=dockerjdk_11
  • 另一种方式是修改web/gui/BUILD
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cd onos/web/gui
sudo vi BUILD
#修改 onos-gui-npm-install
在$$NPM $$NPM_ARGS install后面加上
--registry https://registry.npm.taobao.org

#修改 onos-gui-npm-build
在$$ROOT/$$NPM $$NPM_ARGS run build --no-cache后加上
--registry https://registry.npm.taobao.org

cd onos/web/gui2-fw-lib
sudo vi BUILD
#修改 onos-gui2-fw-npm-install
在npm $$NPM_ARGS install后面加上
--registry https://registry.npm.taobao.org

也可以尝试两种方法都用。此外,也可以先将bazelisk build onos之前的编译为一个镜像(免去安装编译工具的步骤),启动容器,再慢慢编译,通过docker commit将完成编译的容器保存为镜像,再参考Dockerfile进行二阶段的编译过程(此法最可靠)。

参考资料