https://medium.com/@john.lin/%E9%80%8F%E9%81%8E-ovs-bridge-%E5%8F%8A-docker-%E8%A6%AA%E6%89%8B%E6%89%93%E9%80%A0-sdn-%E5%AF%A6%E9%A9%97%E7%B6%B2%E8%B7%AF-%E4%B8%89-%E7%84%A1%E5%A4%96%E9%83%A8%E7%B6%B2%E8%B7%AF-2f60a27e0f45
Fig1. Original Network Stack
Fig2. Network Stack with OVS Bridge
Fig3. Network Stack with OVS Bridge and Containers
透過 OVS Bridge 及 Docker 親手打造 SDN 實驗網路 (三) (無外部網路)
操作概要(四步驟)
在詳細進入每個操作步驟之前,會先把全面性的概要操作方法列出來,才不會有種見樹不見林的感覺。
- 建立 OVS Bridge 名稱 ovsbr0
- 直接對 OVS Bridge 設定一個 Static IP address ,並啟動
- 產生兩個 Containers 來當 Hosts
- 透過 ovs-docker/pipework 工具將 Containers attach 上 OVS Bridges
在這邊會做了幾張圖,比較好瞭解 OVS 每道指令在 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 #Create OVS bridge
我們加入了一個名稱 ovsbr0 的 bridge 可以透過 ifconfig [interface name] 來確認,並且透過 ovs-vsctl show 來看 bridge 的資訊
root@ubuntu-xenial:~# ifconfig ovsbr0 ovsbr0 Link encap:Ethernet HWaddr be:86:d5:cd: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.0 B)
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上,但是尚未將它啟動。
再來設定 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
當然,要開幾個 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-ports ovsbr0 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 的網路環境,對外網路連線會留到下一篇做介紹。
留言
張貼留言