操作概要(四步骤)
在详细进入每个操作步骤之前,会先把全面性的概要操作方法列出来,才不会有种见树不见林的感觉。
-
建立 OVS Bridge 名称 ovsbr0
-
直接对 OVS Bridge 设定一个 Static IP address ,并启动
-
产生两个 Containers 来当 Hosts
-
透过 ovs-docker/pipework 工具将 Containers attach 上 OVS Bridges
在这边会做了几张图,比较好了解 OVS 每道指令在 network stack 上发生什么作用。
Fig1. Original Network Stack
在 vagrant ssh 登入到 VM 之后,我们的 VM 上目前的 Network Stack 如图一所示,可以看到 IP Stack 直接连上 interface enp0s3。此时我们还没透过 OVS 建置任何一个 Bridge。
在透过 OVS 的指令来加入 Bridge之前,我们必须要先拿到 root 的权限,方便做 OVS 指令的操作
$ [host] vagrant ssh
$ [guest] sudo -i
$ [guest] ovs-vsctl add-br ovsbr0 #CreateOVS bridge
我们加入了一个名称 ovsbr0 的 bridge 可以透过 ifconfig [interface name] 来确认,并且透过 ovs-vsctl show 来看 bridge 的资讯
root@ubuntu-xenial:~# ifconfig ovsbr0
ovsbr0 Link encap:Ethernet HWaddr be:86:d5💿f9:4b
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:0 (0.0 B) TX bytes:0 (0.0B)
root@ubuntu-xenial:~# ovs-vsctl show
0a19b4a7-0279-452f-9916-b73655d5b122
Bridge"ovsbr0"
Port "ovsbr0"
Interface "ovsbr0"
type: internal
ovs_version: "2.5.2"
此时我们的 network stack 变成如图二所示,串接在 IP Stack上,但是尚未将它启动。
Fig2. Network Stack with OVS Bridge
再来设定 OVS bridge (ovsbr0) 的 IP address ,并将这个 interface 启动(注意我们刚刚只有创建一个 ovsbr0 并没有指派给他IP 也没有将它启动)。
透过 ip 指令指派 IP 和启动 ovsbr0
$ ip addr add dev ovsbr0 10.0.2.100/24 #Configure IP address
$ ip link set dev ovsbr0 up #ovsbr0 interface up
接着要启动两个 containers 来模拟 hosts,这里有两个工具可以利用,一个是由开发者@jpetazzo 所开发的 pipework 另外一个是 OVS 官方对 docker 网路操作所释出的工具 ovs-docker 两套各有好处,这边两边都会记录,选一套操作即可。
ovs-docker [option1]
首先我们先启动两个 containers 这里用 busybox 的 image 当范例因为只是要验证网路的互通性,busybox 的 image 可以事先用 docker pull busybox 拉下来,或是直接跑 containers 它(docker) 找不到 local image 会自动去 DockerHub pull
$ docker pull busybox
$ docker run --name=container1--cap-add=NET_ADMIN --net='none' -itd busybox /bin/sh
$ docker run --name=container2--cap-add=NET_ADMIN --net='none' -itd busybox /bin/sh
几个 options 稍微介绍一下,如果不了解可以去看 docker 官方指南
• --name=container1: 指定docker 名称
• --cap-add=NET_ADMIN: 给予 network 最高权限
• --net=’none’: 停掉所有 default 的 networking (我们不用docke0的bridge)
• -itd busybox /bin/sh: 启动 busybox 的 shell 并放入背景 (detach)
透过 ovs-docker 将 container attach 上 OVS bridge, container1 容器内给一个 interface eth0 指派 IP 10.0.2.30/24 ,又或者你可以不要给指派 IP 进去容器内后再用 DHCP (busybox: udhcpc, ubuntu: dhclient)去要 IP (因为我们是用 virtualbox 所以 enp0s3 外面会有一个 gateway 在发 IP)
$ ovs-docker add-port ovsbr0 eth0 container1--ipaddress=10.0.2.30/24
$ ovs-docker add-port ovsbr0 eth0 container2--ipaddress=10.0.2.40/24
Pipework [option2]
pipwork 更加简洁,指令只要两行就可以把网路串好且 docker 开好,原则上跟上面类似 $() 内会启动 container 并且吐出 container ID 喂给 pipework
$ pipework ovsbr0 -i eth0 $(docker run--cap-add=NET_ADMIN --net='none' -itd busybox /bin/sh) 10.0.2.10/24
$ pipework ovsbr0 -i eth0 $(docker run --cap-add=NET_ADMIN--net='none' -itd busybox /bin/sh) 10.0.2.20/24
Fig3. Network Stack with OVS Bridge and Containers
当然,要开几个 Containers 就一直 copy 指令改 IP 下去,反正docker 号称 Lightweight 但还是要注意 VM 一开始所配的 RAM 跟 CPU (可以从 Vagrantfile 里做修改)
大功告成,不管用的是 Option1 还是 Option2 我们的 Network Stack 都是变成图三这个样子,我们先来看一下 OVS 在 bridge 及 port 的资讯
root@ubuntu-xenial:~# ovs-vsctl show
80dfbd0a-f6b7-47d0-89a4-ca7906a86a92
Bridge"ovsbr0"
Port "43ad433deb9684_l"
Interface "43ad433deb9684_l"
Port "ovsbr0"
Interface "ovsbr0"
type: internal
Port "veth0pl6094"
Interface "veth0pl6094"
ovs_version: "2.5.2"
我分别用了 pipework 及 ovs-docker 连上了 OVS bridge 在 list ports 可以发现他们命名的方式不同分别是 veth0pl6094 及 43ad433deb9684_l
root@ubuntu-xenial:~# ovs-vsctl list-portsovsbr0
43ad433deb9684_l
veth0pl6094
验证一下其结果透过 docker attach 指令进入任一个 container 试着 ping 另外一个 container 通了就代表 bridge 两个 containers 成功!
$ docker attach
$ ping 10.0.2.20 #ping container2
$ ping 10.0.2.100 #ping ovs
记得要离开 container 的时候先按下 Ctrl+P 然后再按 Ctrl+Q 离开(detach)容器,这样容器才不会停止。或者用 tmux 开两个 sessions 每个 session 分别放不同的 container 透过 tmux detach 的方式暂时离开切换 session
接下来你可以将 SDN Controller 接上 OVS 开始控制网路流量 (可以将 SDN Controller 放到第三个容器内跟 OVS bridge 做 OpenFlow Protocol 的连线),但是你可能会发现到 Container 内网路没办法对外连线,不过如果实验不需要外部网路,大概这样就可以开始一个 SDN 的网路环境,对外网路连线会留到下一篇做介绍。
- END -