APRESIA Technical Blog

CORD Trellis Underlay FabricをOVS on GNS3で構築してみた

trellis_v2.md

はじめに

ONF (Open Networking Foundation)におけるCORD (Central Office Re-architected as a Datacenter) プロジェクト内のSDNベースのLeaf-Spineファブリックの制御を担当するTrellisについて、GNS3仮想環境上で実際に動かしてみた。
スイッチはOVS、スイッチ制御のインタフェースとしてはOpenFlowを用いる。

ONFの公式チュートリアル等で実施されているMninetでの仮想試験環境とは違い、GNS3仮想環境上に試験ネットワークを構築することで、より物理環境に近い試験を実施することが可能になる。これによりパケットキャプチャや疑似障害を容易に実施可能になり今後の調査に役立つ。

今回は、基本的なLeaf-Spine構成での通信確認、およびECMPによる負荷分散の様子を可視化するところまで実施する。

環境全体像

以下の環境を構築する。

  • ONOSクラスタの構築はScenario Test Coordinator (STC)を利用する
  • ONOSサーバー2台でクラスタ構成にする
  • 各サーバー間はローカルネットワーク(192.168.200.0/24)でそれぞれ接続する
  • 各種ソフトウェアのインストールのために、各サーバーはens160経由でインターネットに接続しているが、ここでは明記しない(GNS3サーバーに関してはNAT出口となるため明記してある)

各サーバーの事前準備

管理サーバー

  • Ubuntu 16.04 LTSのインストール (手順省略)

  • Proxyの設定
    HTTP Proxyの設定が不要な場合は本手順では不要

    export http_proxy=http://proxy.server:port/ export https_proxy=http://proxy.server:port/
  • JDK1.8のインストール

    sudo -E apt-get install openjdk-8-jdk
  • bazel(ビルドツール)のインストール

    echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add - sudo -E apt-get update && sudo -E apt-get install bazel
  • その他必要なツールのインストール

    sudo -E apt-get install python python-pip zip

ONOSサーバー

クラスタ構成にするので、本手順は2台分必要。

  • Ubuntu 16.04 LTSのインストール (手順省略)

  • Proxyの設定
    HTTP Proxyの設定が不要な場合は本手順では不要

    export http_proxy=http://proxy.server:port/ export https_proxy=http://proxy.server:port/
  • JDK1.8のインストール

    sudo -E apt-get install openjdk-8-jdk
  • sdnユーザーの作成
    STCでは、sdnユーザーでアクセスするため、事前にsdnユーザーを作成する必要がある。

    sudo adduser sdn ## password等適宜設定
  • sudoerの設定

    sudo visudo

    ファイル編集画面になるので、以下を最後に追記

    sdn ALL=(ALL) NOPASSWD:ALL

ONOS STCのセットアップ

以下の作業は特別な記載がない限り管理サーバーから実施するものとする。STCではローカルでビルドしたONOSをインストールするため、事前にソースコードからビルドをする必要がある。

  • ONOSソースコードの取得

    cd ~ git clone https://gerrit.onosproject.org/onos cd onos git checkout onos-1.15 #最新のリリースブランチに移動する(例示の1.15は執筆時点(2018/11/14)での最新)
  • ONOSのビルド

    bazel build onos
  • 便利スクリプトの実行PATHを読み込む

    source ./tools/dev/bash_profile
    • 管理サーバーログイン時にスクリプトが実行可能とするために、以下を設定しておくと良い
      cat << EOF >> ~/.bashrc export ONOS_ROOT=~/onos source \$ONOS_ROOT/tools/dev/bash_profile EOF
  • STC環境ファイルの編集
    $ONOS_ROOT/tools/test/cells/localファイルを実環境にあわせて編集する。
    ここでは、ONOSサーバーのIPがそれぞれ192.168.200.137, 192.168.200.138であった場合についての例を示す。

    export ONOS_NIC=192.168.200.* export OC1="192.168.200.137" export OC2="192.168.200.138" export OCC1="192.168.200.137" export OCC2="192.168.200.138" export ONOS_APPS="drivers,openflow,segmentrouting,netcfghostprovider,routeradvertisement,mcast"
  • 設定の反映と確認
    cellコマンドで設定を反映させる。設定内容が正しいことも同時に確認する。

    cell local
  • ssh鍵の登録
    Remoteサーバーへのアクセスのため、SSH鍵を作成し、サーバーへ公開鍵登録を行う。

    ssh-keygen -t rsa # passphraseは指定しない onos-push-keys $OC1 # sdnユーザーのパスワードを聞かれるので、先に設定したものを指定 onos-push-keys $OC2
  • STC構築

    stc setup
  • 確認
    ブラウザでhttp://<onos-server>:8181/onos/ui へアクセスしてONOSのGUIが開くことを確認する。 (username: onos, password: rocks)


ネットワーク構築

GNS3設定

  • OVS 2.5.0以上が必要なため、Dockerイメージを作成する。
    ※執筆時点ではGNS3のOVSバージョンは2.4なため自分で作成する必要がある。

    以下作業はGNS3サーバー上で実施すること。

    • gns3のDockerイメージのソースコード取得

      git clone https://github.com/GNS3/gns3-registry.git
    • open vswitchのDockerファイルを編集

      cd gns3-registry/docker/openvswitch vim Dockerfile

      ベースのイメージをalpine:3.4に変更

      --- a/docker/openvswitch/Dockerfile +++ b/docker/openvswitch/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.3 +FROM alpine:3.4 RUN apk add --update openvswitch nano && rm -rf /var/cache/apk/*
    • ビルド

      docker build -t gns3/openvswitch:2.5 .
  • Dockerイメージのテンプレート化

    • GNS3クライアント上でCtrl + Shift + Pにてメニューを開き、Docker Containersを選択し、Newをクリック

    OVS docker

    • Existing imageより、先ほど作成したイメージを選択し、Next

    OVS docker

    • nameは任意、Network adaptersは16とし、後はデフォルトのままで作成する
    • 作成したDockerを選択し、Editを選択し、CategoryをSwitchとSymbolをMultilayer switchにそれぞれ変更する

    OVS docker

    • GNS3から作成したOVSをデプロイ可能なことを確認する

    OVS docker

OVSの設定

  • OVSの配置および結線を行う

    • Leaf-Spineは順番にeth0から接続
    • 管理用/コントローラー接続用のインタフェースはeth15とする

    GNS3 OVS

  • 管理用のインタフェースのIPを設定(すべてのOVSに設定)
    ※DHCPサーバーがある場合は、DHCPで良い

    mgmt interface

  • OVSの基本設定
    以下となるようにOVSの設定を行う。また、併せて管理ポートをBridgeから外しておく。

    Switch name datapath-id mac address
    Spine01 S226 0000000000000226 00:00:00:00:02:26
    Spine02 S227 0000000000000227 00:00:00:00:02:27
    Leaf01 S204 0000000000000204 00:00:00:00:02:04
    Leaf02 S205 0000000000000205 00:00:00:00:02:05
    Spine01の設定例は下記となるが、Spine02, Leaf01, Leaf02に対しても設定を行う必要がある。
    ovs-vsctl del-port br0 eth15 ovs-vsctl set bridge br0 other-config:datapath-id=0000000000000226 ovs-vsctl set bridge br0 other-config:hwaddr=00:00:00:00:02:26
  • コントローラー接続
    各OVSをコントローラー2台と接続する

    ovs-vsctl set-controller br0 tcp:192.168.200.137:6653 tcp:192.168.200.138:6653

ホスト接続

ホストを以下のように接続する。IPアドレスとGWの設定も実施する。(GWアドレスに注意)

GNS3 Hosts

  • 現時点ではホスト間で通信ができないことを確認しておく
/ # ping 10.0.3.1 -c 1 PING 10.0.3.1 (10.0.3.1): 56 data bytes --- 10.0.3.1 ping statistics --- 1 packets transmitted, 0 packets received, 100% packet loss / #

ONOS設定

ネットワーク設定をインポート

管理サーバーより、ONOSにネットワーク設定ファイルを流し込む。この設定により、ONOSより各OVSにフロー設定が投入される。クラスターを構成しているため、設定ファイル流し込みは1つのコントローラーで実施すればよい。

onos-netcfg $OC1 trellis.json

今回の設定例では、以下のような設定ファイル(trellis.json)を用意した。

{ "ports" : { "of:0000000000000204/3" : { "interfaces" : [ { "ips" : [ "10.0.2.254/24" ], "vlan-untagged": 20 } ] }, "of:0000000000000204/4" : { "interfaces" : [ { "ips" : [ "10.0.2.254/24" ], "vlan-untagged": 20 } ] }, "of:0000000000000205/3" : { "interfaces" : [ { "ips" : [ "10.0.3.254/24" ], "vlan-untagged": 30 } ] }, "of:0000000000000205/4" : { "interfaces" : [ { "ips" : [ "10.0.3.254/24" ], "vlan-untagged": 30 } ] } }, "devices" : { "of:0000000000000204" : { "segmentrouting" : { "name" : "s204", "ipv4NodeSid" : 204, "ipv4Loopback" : "192.168.0.204", "routerMac" : "00:00:00:00:02:04", "isEdgeRouter" : true, "adjacencySids" : [] }, "basic" : { "name": "s204", "driver" : "ofdpa-ovs" } }, "of:0000000000000205" : { "segmentrouting" : { "name" : "s205", "ipv4NodeSid" : 205, "ipv4Loopback" : "192.168.0.205", "routerMac" : "00:00:00:00:02:05", "isEdgeRouter" : true, "adjacencySids" : [] }, "basic" : { "name": "s205", "driver" : "ofdpa-ovs" } }, "of:0000000000000226" : { "segmentrouting" : { "name" : "s226", "ipv4NodeSid" : 226, "ipv4Loopback" : "192.168.0.226", "routerMac" : "00:00:00:00:02:26", "isEdgeRouter" : false, "adjacencySids" : [] }, "basic" : { "name": "s226", "driver" : "ofdpa-ovs" } }, "of:0000000000000227" : { "segmentrouting" : { "name" : "s227", "ipv4NodeSid" : 227, "ipv4Loopback" : "192.168.0.227", "routerMac" : "00:00:00:00:02:27", "isEdgeRouter" : false, "adjacencySids" : [] }, "basic" : { "name": "s227", "driver" : "ofdpa-ovs" } } } }

通信確認

ホスト間でお互いにPingを実行し通信可能なことを確認する。
※最初はフロー登録されていない可能性があるため同時に双方向でPingを実行するのが良い。

/ # ping 10.0.3.1 -c 3 PING 10.0.3.1 (10.0.3.1): 56 data bytes 64 bytes from 10.0.3.1: seq=0 ttl=63 time=7.918 ms 64 bytes from 10.0.3.1: seq=1 ttl=63 time=19.777 ms 64 bytes from 10.0.3.1: seq=2 ttl=63 time=13.366 ms --- 10.0.3.1 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 7.918/13.687/19.777 ms

ECMPの確認

負荷試験ツールであるTsungを使用してホスト間通信を実施し、ONOS上でトラフィック流量が可視化する。
ファブリック内のトラフィックが均等に分散されていることが確認できる。

Tsung



まとめ

GNS3を用いて、Trellisファブリックの基本構成での通信確認および、ECMPによる負荷分散をONOS上で可視化した。


従来型のスイッチによる自律的な制御とは異なり、すべてコントローラーにより制御することでスイッチへの負担軽減や設定の簡素化が可能となる。


今回は、基本的な動作のみを確認したが、今後は以下のようなことを試していきたい。



  • 疑似障害を起こした場合の挙動調査
  • パケットキャプチャによる解析
  • その他ONOSアプリケーションの動作確認
  • 実機での動作確認および性能調査

参考

・Trellis
 https://wiki.opencord.org/display/CORD/Trellis%3A+CORD+Network+Infrastructure
・ONOS Developer Guide
 https://wiki.onosproject.org/display/ONOS/Developer+Guide
・Trellisファブリック設定例
 https://github.com/opennetworkinglab/routing
・Tsung
 http://tsung.erlang-projects.org/


ホワイトボックスに興味ある方はこちら