OpenDaylightでクラスタを組んでみよう

2016年9月16日(金)
安座間 勇二(あざま ゆうじ)

前回までは、OpenDaylight(以下ODL)の構築と基本動作確認を行ってきました。OpenStackとの連携もできているので、使ってみようかなと思う方もおられるかと思います。実際に、システム構成を考えるときにSPOF(単一障害点)を作らないように設計するのは基本かと思いますが、OpenStackはHA構成が組めるのに、ODLがSPOFになってしまっては元も子もありません。そこで今回は、ODLのクラスタを構築してみます。

OpenDaylightのデータストアとクラスタ

ODLのクラスタはMD-SAL Clustering機能として実装されています。ODLの分散データストアを理解するためにはデータストアがどのような構造になっているのかを理解している必要があります。

データストア

OpenDaylightはMD-SALという抽象化レイヤー内に独自のデータストアを持っています。ODLを利用する各アプリケーションはこのデータストアにアクセスすることで必要な情報を保存したり、取り出したりできます。データストアの実体はLevelDB(Key-Value Storage)かSnapshotとなりますが、論理的には以下の図のようなデータツリー構造をしています。

Data tree

シャード

クラスタを構成した際、データストアに保存されたデータはクラスタ内の多数のノードへシャード単位でレプリケーションされます。シャードとはデータストアのあるひとまとめにしたサブツリーを指します。シャード毎にどのノードへレプリケーションするかを設定できます。

Shard

Raft

ODLのクラスタではRaftというコンセンサスアルゴリズムを採用しています。Raftでは各ノードは以下の3つの状態のいずれかを持っています。

  • Leader
    • Leaderはクラスタ内で1ノードのみ選出され、ODLアプリケーションやFollowerからの全ての要求に応答し、Followerへの要求も行います。
  • Follower
    • FollowerはLeaderかCandidateのノードからの要求に応答します。自ら要求を行うことはありません。
  • Candidate
    • Candidateはノードの起動時やLeaderがダウンした時に、新しいLeaderを選出する状態を示しています。

Raftではクラスタ内の過半数以上のノードが稼働していれば全体のフォールトトレラント性が保たれる仕組みになっています。もし、何らかの障害により過半数以上のノードがダウンした場合、Leaderを選出できずクラスタはSuspend状態となります。Raftでは全てのノードがリクエストを受けることができます。Followerが要求を受けるとその要求はLeaderに転送されます。したがって、OpenStackからのリクエストがLeaderではないノードに届いても問題はありません。実際に、今回解説する構成ではHAProxyを使ってロードバランシングしていますので、Followerにもリクエストが飛ぶことになります。

環境・バージョンについて

クラスタの物理構成

env

今回は3ノードのODLクラスタを構築してみます。これまでと同様にOpenStackと連携させた環境を構築します。OpenStack用の1ノードとODLクラスタ用の3ノードの全てでUbuntuを使用します。ODLへのリクエストをODLクラスタへ分散するためにOpenStackのノードにHAProxyも使用します。それぞれのパッケージで使用するバージョンは以下の表の通りです。

パッケージ バージョン
Ubuntu 14.04 LTS
OpenDaylight Beryllium SR2
OpenStack Mitaka
HAProxy 1.4.24

シャードの構成

今回の構成では以下の図のように、Inventoryサブツリー配下のシャードとnetwork-topologyサブツリー配下のシャード、それら以外のサブツリーであるdefault、toasterのシャードを全てのノードにレプリケーションする設定を行います。

Data Tree

構築してみよう

全ノード共通の設定

それでは早速構築を始めていきます。先に、全ノードで共通の設定を実施しておきます。

構築を簡単にするために、ファイアーウォールは無効化しておきます。

~$ sudo ufw disable

続いて、ODLの構築に入ります。

ODLの構築

JDKのインストール

ODLはJava言語によって実装されています。そのためJavaの実行環境が必要になりますのでJDK(Java Development Kit)をインストールします。今回インストールするBeryllium SR2ではJDK 8が必要です。

~$ sudo add-apt-repository ppa:openjdk-r/ppa
~$ sudo apt-get update
~$ sudo apt-get install openjdk-8-jre

OpenDaylightのダウンロード

ODLのパッケージをNexusリポジトリからダウンロードして展開します。

~$ wget https://nexus.opendaylight.org/content/repositories/opendaylight.release/org/opendaylight/integration/distribution-karaf/0.4.2-Beryllium-SR2/distribution-karaf-0.4.2-Beryllium-SR2.tar.gz
~$ tar zxvf distribution-karaf-0.4.2-Beryllium-SR2.tar.gz
~$ cd distribution-karaf-0.4.2-Beryllium-SR2/

OpenDaylightの起動

ODLを以下のstartスクリプトを実行して起動します。

~/distribution-karaf-0.4.2-Beryllium-SR2$ ./bin/start  # OpenDaylightを起動する

必要な機能のインストール

ODLのコンソールにログインして、必要な機能をインストールしていきます。インストールするのは、OpenStack連携に必要な「odl-ovsdb-openstack」とMD-SALのクラスタリングに必要な「odl-mdsal-clustering」になります。

~/distribution-karaf-0.4.2-Beryllium-SR2$ ./bin/client -u karaf  # OpenDaylight Karaf Shellにログイン
  :
opendaylight-user@root>feature:install odl-ovsdb-openstack
opendaylight-user@root>feature:install odl-mdsal-clustering
opendaylight-user@root>logout

ここで、一度ODLを停止します。

~/distribution-karaf-0.4.2-Beryllium-SR2$ ./bin/stop  # OpenDaylightを停止する

ここまでの手順を3台のODLノード全てで実施してください。

クラスタリングの設定

続いて、クラスタリングに必要な設定をしていきます。ODLクラスタリングではakka.confとmodule-shards.confの2つのファイルを設定する必要があります。今回使用する設定ファイルは全てGitHubからダウンロードできます。

まずはODL Controller 1のノードで設定を行います。以下のディレクトリに移動し、akka.confをダウンロードします。

~/distribution-karaf-0.4.2-Beryllium-SR2$ cd configuration/initial
~/distribution-karaf-0.4.2-Beryllium-SR2/configuration/initial$ wget -O akka.conf https://raw.githubusercontent.com/YujiAzama/opendaylight-openstack-integration/master/clustering/akka.conf.member-1

ODL Controller 2と3のakka.confは以下のURLからダウンロードして使用してください。

ダウンロードしたファイルを開き、hostnameやseed-nodesのIPアドレスをお使いの環境に合わせて編集してください。rolesにはクラスタ内でのメンバー識別子が指定されています。それぞれのメンバーはクラスタ内での識別子を持っている必要があり、そのクラスタ内で一意でなければなりません。ここでは以下のように値を設定しています。

ノード メンバー識別子
ODL Controller 1 member-1
ODL Controller 2 member-2
ODL Controller 3 member-3
odl-cluster-data {
  akka {
    remote {
      netty.tcp {
        hostname = "192.168.0.11"  # 自ノードのIPアドレスへ変更する
        port = 2550
      }
    }

    cluster {
      seed-nodes = ["akka.tcp://opendaylight-cluster-data@192.168.0.11:2550",  # member-1のIPアドレスを指定する
                    "akka.tcp://opendaylight-cluster-data@192.168.0.12:2550",  # member-2のIPアドレスを指定する
                    "akka.tcp://opendaylight-cluster-data@192.168.0.13:2550"]  # member-3のIPアドレスを指定する

      roles = [
        "member-1"  # クラスタ内でのメンバー識別子を指定する
      ]

    }
  :  # 省略
}

odl-cluster-rpc {  
  :  # 省略
    remote {
      log-remote-lifecycle-events = off
      netty.tcp {
        hostname = "192.168.0.11"  # 自ノードのIPアドレスへ変更する
        port = 2551
        maximum-frame-size = 419430400
        send-buffer-size = 52428800
        receive-buffer-size = 52428800
      }
    }

    cluster {
      seed-nodes = ["akka.tcp://odl-cluster-rpc@192.168.0.11:2551",  # member-1のIPアドレスを指定する
                    "akka.tcp://odl-cluster-rpc@192.168.0.12:2551",  # member-2のIPアドレスを指定する
                    "akka.tcp://odl-cluster-rpc@192.168.0.13:2551"]  # member-3のIPアドレスを指定する
      auto-down-unreachable-after = 300s
    }
  }
}

次に、module-shards.confをダウンロードします。

~/distribution-karaf-0.4.2-Beryllium-SR2/configuration/initial$ wget -O module-shards.conf https://raw.githubusercontent.com/YujiAzama/opendaylight-openstack-integration/master/clustering/module-shards.conf

module-shards.confではクラスタのメンバー(ODLのノード)とレプリカの設定をします。レプリカのリストの順番に優先順位が設定されます。

module-shards = [
    {
        name = "default"
        shards = [
            {
                name="default"
                replicas = [
                    "member-1",
                    "member-2",
                    "member-3"
                ]
            }
        ]
    },
    {
        name = "topology"
        shards = [
            {
                name="topology"
                replicas = [
                    "member-1",
                    "member-2",
                    "member-3"
                ]
            }
        ]
    },
    {
        name = "inventory"
        shards = [
            {
                name="inventory"
                replicas = [
                    "member-1",
                    "member-2",
                    "member-3"
                ]
            }
        ]
    },
    {
        name = "toaster"
        shards = [
            {
                name="toaster"
                replicas = [
                    "member-1",
                    "member-2",
                    "member-3"
                ]
            }
        ]
    }
]

ODL Controller 2とODL Controller 3も同様に設定をします。最後に、全てのODLを起動してください。

~/distribution-karaf-0.4.2-Beryllium-SR2/configuration/initial$ cd ~/distribution-karaf-0.4.2-Beryllium-SR2
~/distribution-karaf-0.4.2-Beryllium-SR2$ ./bin/start  # OpenDaylightを起動する

以上で、ODLの設定は完了です。

HAProxyの設定

今回はODLがクラスタ構成となっていますので、Neutron ML2ドライバからのリクエストをクラスタの各メンバーへ分散するためにHAProxyを使用してみます。OpenStackのノードでインストールと設定を行っていきます。

~$ sudo apt-get install haproxy

以下の設定ファイルを開いてください。

~$ sudo vim /etc/default/haproxy

ENABLEDが0になっていれば1に変更してください。

ENABLED=1

続いて、設定ファイルをダウンロードします。

~$ sudo wget -O /etc/haproxy/haproxy.cfg https://raw.githubusercontent.com/YujiAzama/opendaylight-openstack-integration/master/clustering/haproxy.cfg

ダウンロードしたhaproxy.cfgを開きbackend_serversに指定されているクラスタのメンバーのIPアドレスへ変更してください。HAProxyの設定は非常に単純で、8181番ポートから入ってきたhttpパケットをバックエンドのODLへラウンドロビンで分散するように設定しています。

global
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy
    user haproxy
    group haproxy
    daemon

defaults
    log global
    mode    http
    option  httplog
    option  dontlognull
        contimeout 5000
        clitimeout 50000
        srvtimeout 50000
    errorfile 400 /etc/haproxy/errors/400.http
    errorfile 403 /etc/haproxy/errors/403.http
    errorfile 408 /etc/haproxy/errors/408.http
    errorfile 500 /etc/haproxy/errors/500.http
    errorfile 502 /etc/haproxy/errors/502.http
    errorfile 503 /etc/haproxy/errors/503.http
    errorfile 504 /etc/haproxy/errors/504.http

frontend http-in
        bind *:8181
        default_backend backend_servers
        option          forwardfor

backend backend_servers
        balance roundrobin
        server odl1 192.168.0.11:8181 check  # member-1のIPアドレスへ変更
        server odl2 192.168.0.12:8181 check  # member-2のIPアドレスへ変更
        server odl3 192.168.0.13:8181 check  # member-3のIPアドレスへ変更

最後にHAProxyを再起動します。

~$ sudo service haproxy restart

以上で、HAProxyの設定は完了です。

コントローラノードの構築

続いて、OpenStackの構築を行います。DevStackをダウンロードしてきます。

~$ sudo apt-get install git
~$ git clone https://github.com/openstack-dev/devstack.git --branch stable/mitaka

以下のURLからlocal.confのサンプルをダウンロードしてください。

~$ cd devstack/
~/devstack$ wget https://raw.githubusercontent.com/YujiAzama/opendaylight-openstack-integration/master/clustering/local.conf

ダウンロードしたlocal.confを開くと以下の様になっています。まず、お使いの環境に合わせてHOST_IPをコントローラノードのIPアドレスに変更してください。

~/devstack$ vim local.conf
  :
# IP Details
HOST_IP=192.168.0.10
SERVICE_HOST=$HOST_IP
  :
# Neutron
  :
BRANCH_NAME=stable/beryllium
enable_plugin networking-odl http://git.openstack.org/openstack/networking-odl ${BRANCH_NAME}

# OpenDaylight Details
ODL_MODE=externalodl
ODL_PORT=8181
ODL_OVS_MANAGERS=192.168.0.11,192.168.0.12,192.168.0.13

[[post-config|/etc/neutron/plugins/ml2/ml2_conf.ini]]
[ml2_odl]
password=admin
username=admin
url="http://127.0.0.1:${ODL_PORT}/controller/nb/v2/neutron"

ODL_OVS_MANAGERSには、OpenStackの各OVSが接続する先のODLのIPアドレスを指定します。今回は3台のODLがいるので、3台分のIPアドレスを指定します。本来、ml2_conf.iniのml2_odlセクションにはODLコントローラのIPアドレスをurlとして指定しますが、今回のODLはクラスタ構成なので、HAProxyが動作しているローカルホストを指定しています。

後は、stack.shスクリプトを実行するだけです。以下の様なメッセージが出力されれば終了です。

~/devstack$ ./stack.sh
  :
This is your host IP address: 192.168.0.10
This is your host IPv6 address: ::1
Horizon is now available at http://192.168.0.10/dashboard
Keystone is serving at http://192.168.0.10:5000/
The default users are: admin and demo
The password: password
2016-07-22 06:47:58.133 | stack.sh completed in 1130 seconds.

以上で全ての構築は完了です。

動作確認

レプリケーションされているか

機能的には第2回、第3回で構築した環境と変わりません。ここでは、ODLのデータストアが全てのメンバーにレプリケーションできているか確認してみましょう。

ODLにデータを登録するためにOpenStackからネットワークとインスタンスを作成します。コントローラノードで以下のコマンドを実行します。

~/devstack$ source openrc demo demo   # 認証用の環境変数を設定(demoユーザー、demoテナント)
~/devstack$ neutron net-create net01  # ネットワークを作成
Created a new network:                                            
+-------------------------+--------------------------------------+
| Field                   | Value                                |
+-------------------------+--------------------------------------+
| admin_state_up          | True                                 |
| availability_zone_hints |                                      |
| availability_zones      |                                      |
| created_at              | 2016-07-26T07:43:08                  |
| description             |                                      |
| id                      | b94883ed-34ad-4a09-ac58-e459b6b77582 |
| ipv4_address_scope      |                                      |
| ipv6_address_scope      |                                      |
| mtu                     | 1450                                 |
| name                    | net01                                |
| port_security_enabled   | True                                 |
| router:external         | False                                |
| shared                  | False                                |
| status                  | ACTIVE                               |
| subnets                 |                                      |
| tags                    |                                      |
| tenant_id               | aaa0ecf59218482d9e55b75a50f22a5c     |
| updated_at              | 2016-07-26T07:43:08                  |
+-------------------------+--------------------------------------+

net01というネットワークが作成され、ODLのデータストアに情報が書き込まれました。さっそくデータストアの情報を確認してみましょう。第4回で紹介したRESTCONFを使ってアクセスします。まずはmember-1にアクセスしてneutronの情報を取得します。以下のようなデータが取得できます。

~$ curl -u admin:admin http://192.168.0.11:8181/restconf/config/neutron:neutron/ | python -m json.tool
{
    "neutron": {
        "networks": {
            "network": [
                {
                    "admin-state-up": true,
                    "name": "net01",
                    "neutron-L3-ext:external": false,
                    "neutron-provider-ext:network-type": "neutron-networks:network-type-vxlan",
                    "neutron-provider-ext:segmentation-id": "1048",
                    "shared": false,
                    "status": "ACTIVE",
                    "tenant-id": "aaa0ecf5-9218-482d-9e55-b75a50f22a5c",
                    "uuid": "b94883ed-34ad-4a09-ac58-e459b6b77582"
                }
            ]
        },
    :
    }
}

データ量が多いので一部省略していますが、先ほど作成したネットワークの情報が取得できます。member-2とmember-3に対しても同様にRESTCONFでアクセスしてみてください。同じデータが取得できていればレプリケーションできており、クラスタが正常に動作しています。

障害時の動作

それではクラスタの状態を確認してみます。Javaアプリケーションの統計情報を取得したりモニタリングや管理などを行う時に欠かせないJMXですが、ODLではJMXの情報をREST APIで提供するためのJolokiaを利用できます。まず、Jolokiaをインストールします。

~/distribution-karaf-0.4.2-Beryllium-SR2$ ./bin/client -u karaf
client: JAVA_HOME not set; results may vary
Logging in as karaf
387 [sshd-SshClient[ed17bee]-nio2-thread-2] WARN org.apache.sshd.client.keyverifier.AcceptAllServerKeyVerifier - Server at [/0.0.0.0:8101, DSA, 75:e8:b1:02:c3:ac:e8:6d:f8:8e:fb:99:a8:b2:1a:8e] presented unverified {} key: {}

    ________                       ________                .__  .__       .__     __
    \_____  \ ______   ____   ____ \______ \ _____  ___.__.|  | |__| ____ |  |___/  |
     /   |   \\____ \_/ __ \ /    \ |    |  \\__  \<   |  ||  | |  |/ ___\|  |  \   __\
    /    |    \  |_> >  ___/|   |  \|    `   \/ __ \\___  ||  |_|  / /_/  >   Y  \  |
    \_______  /   __/ \___  >___|  /_______  (____  / ____||____/__\___  /|___|  /__|
            \/|__|        \/     \/        \/     \/\/            /_____/      \/


Hit '<tab>' for a list of available commands
and '[cmd] --help' for help on a specific command.
Hit '<ctrl-d>' or type 'system:shutdown' or 'logout' to shutdown OpenDaylight.

opendaylight-user@root>bundle:install -s mvn:org.jolokia/jolokia-osgi/1.3.1
Bundle ID: 286
opendaylight-user@root>logout

Jolokiaのインストールを全てのmemberに対して行います。

まずmember-1の状態を取得してみます。

$ curl -s http://192.168.0.11:8181/jolokia/read/org.opendaylight.controller:Category=Shards,name=member-1-shard-inventory-config,type=DistributedConfigDatastore | python -m json.tool
{
    "request": {
        "mbean": "org.opendaylight.controller:Category=Shards,name=member-1-shard-inventory-config,type=DistributedConfigDatastore",
        "type": "read"
    },
    "status": 200,
    "timestamp": 1465515563,
    "value": {
        "AbortTransactionsCount": 0,
        "CommitIndex": 13,
        "CommittedTransactionsCount": 0,
        "CurrentTerm": 5,
        "FailedReadTransactionsCount": 0,
        "FailedTransactionsCount": 0,
        "FollowerInfo": [
            {
                "active": true,
                "id": "member-2-shard-inventory-config",
                "matchIndex": 13,
                "nextIndex": 14,
                "timeSinceLastActivity": "00:00:00.012"
            },
            {
                "active": true,
                "id": "member-3-shard-inventory-config",
                "matchIndex": 13,
                "nextIndex": 14,
                "timeSinceLastActivity": "00:00:00.015"
            }
        ],
        "FollowerInitialSyncStatus": true,
        "InMemoryJournalDataSize": 1338,
        "InMemoryJournalLogSize": 1,
        "LastApplied": 13,
        "LastCommittedTransactionTime": "1970-01-01 09:00:00.000",
        "LastIndex": 13,
        "LastLeadershipChangeTime": "2016-06-10 08:37:53.140",
        "LastLogIndex": 13,
        "LastLogTerm": 4,
        "LastTerm": 4,
        "Leader": "member-1-shard-inventory-config",
        "LeadershipChangeCount": 3,
        "PeerAddresses": "member-2-shard-inventory-config: akka.tcp://opendaylight-cluster-data@192.168.0.12:2550/user/shardmanager-config/member-2-shard-inventory-config, member-3-shard-inventory-config: akka.tcp://opendaylight-cluster-data@192.168.0.13:2550/user/shardmanager-config/member-3-shard-inventory-config",
        "PendingTxCommitQueueSize": 0,
        "RaftState": "Leader",
        "ReadOnlyTransactionCount": 0,
        "ReadWriteTransactionCount": 0,
        "ReplicatedToAllIndex": 12,
        "ShardName": "member-1-shard-inventory-config",
        "SnapshotCaptureInitiated": false,
        "SnapshotIndex": 12,
        "SnapshotTerm": 4,
        "StatRetrievalError": null,
        "StatRetrievalTime": "1.676 ms",
        "TxCohortCacheSize": 0,
        "VotedFor": "member-1-shard-inventory-config",
        "WriteOnlyTransactionCount": 0
    }
}

取得した結果、"RaftState": "Leader" となっていることが確認できます。続いて、member-2とmember-3でも確認してみてください。"RaftState": "Follower"となっていることが確認できます。

member-1を落としてみる

クラスタが正常に動作していることを確認するために、Leaderとなっているmember-1を停止してmember-2にLeaderが切り替わることを確認します。

~/distribution-karaf-0.4.2-Beryllium-SR2$ ./bin/stop

これでmember-1からのレスポンスは返ってこなくなります。この時のmember-2の状態を確認してみます。

$ curl -s http://192.168.0.12:8181/jolokia/read/org.opendaylight.controller:Category=Shards,name=member-2-shard-inventory-config,type=DistributedConfigDatastore | python -m json.tool
{
    "request": {
        "mbean": "org.opendaylight.controller:Category=Shards,name=member-2-shard-inventory-config,type=DistributedConfigDatastore",
        "type": "read"
    },
    "status": 200,
    "timestamp": 1465449951,
    "value": {
        "AbortTransactionsCount": 0,
        "CommitIndex": 13,
        "CommittedTransactionsCount": 0,
        "CurrentTerm": 7,
        "FailedReadTransactionsCount": 0,
        "FailedTransactionsCount": 0,
        "FollowerInfo": [
            {
                "active": false,
                "id": "member-1-shard-inventory-config",
                "matchIndex": -1,
                "nextIndex": 13,
                "timeSinceLastActivity": "00:00:00.000"
            },
            {
                "active": false,
                "id": "member-3-shard-inventory-config",
                "matchIndex": -1,
                "nextIndex": 13,
                "timeSinceLastActivity": "00:00:00.000"
            }
        ],
        "FollowerInitialSyncStatus": true,
        "InMemoryJournalDataSize": 1338,
        "InMemoryJournalLogSize": 1,
        "LastApplied": 13,
        "LastCommittedTransactionTime": "1970-01-01 09:00:00.000",
        "LastIndex": 13,
        "LastLeadershipChangeTime": "2016-06-09 14:25:51.866",
        "LastLogIndex": 13,
        "LastLogTerm": 4,
        "LastTerm": 4,
        "Leader": "member-2-shard-inventory-config",
        "LeadershipChangeCount": 4,
        "PeerAddresses": "member-1-shard-inventory-config: akka.tcp://opendaylight-cluster-data@192.168.0.11:2550/user/shardmanager-config/member-1-shard-inventory-config, member-3-shard-inventory-config: akka.tcp://opendaylight-cluster-data@192.168.0.13:2550/user/shardmanager-config/member-3-shard-inventory-config",
        "PendingTxCommitQueueSize": 0,
        "RaftState": "Leader",
        "ReadOnlyTransactionCount": 1,
        "ReadWriteTransactionCount": 0,
        "ReplicatedToAllIndex": -1,
        "ShardName": "member-2-shard-inventory-config",
        "SnapshotCaptureInitiated": false,
        "SnapshotIndex": 12,
        "SnapshotTerm": 4,
        "StatRetrievalError": null,
        "StatRetrievalTime": "19.88 ms",
        "TxCohortCacheSize": 0,
        "VotedFor": "member-2-shard-inventory-config",
        "WriteOnlyTransactionCount": 0
    }
}

member-1が停止したことによってLeaderがmember-2に切り替わりました。この状態でもOpenStackのネットワークが作れるか確認します。

~/devstack$ neutron net-create net02
Created a new network:                                            
+-------------------------+--------------------------------------+
| Field                   | Value                                |
+-------------------------+--------------------------------------+
| admin_state_up          | True                                 |
| availability_zone_hints |                                      |
| availability_zones      |                                      |
| created_at              | 2016-07-26T08:01:35                  |
| description             |                                      |
| id                      | f9867311-98c3-4618-be98-6ce75ff8aa23 |
| ipv4_address_scope      |                                      |
| ipv6_address_scope      |                                      |
| mtu                     | 1450                                 |
| name                    | net02                                |
| port_security_enabled   | True                                 |
| router:external         | False                                |
| shared                  | False                                |
| status                  | ACTIVE                               |
| subnets                 |                                      |
| tags                    |                                      |
| tenant_id               | aaa0ecf59218482d9e55b75a50f22a5c     |
| updated_at              | 2016-07-26T08:01:35                  |
+-------------------------+--------------------------------------+

作成できました。member-1を起動してnet02がレプリケーションされることを確認しましょう。

~/distribution-karaf-0.4.2-Beryllium-SR2$ ./bin/start
~$ curl -u admin:admin http://192.168.0.11:8181/restconf/config/neutron:neutron/
{
    "neutron": {
        "networks": {
            "network": [
                {
                    "admin-state-up": true,
                    "name": "net01",
                    "neutron-L3-ext:external": false,
                    "neutron-provider-ext:network-type": "neutron-networks:network-type-vxlan",
                    "neutron-provider-ext:segmentation-id": "1048",
                    "shared": false,
                    "status": "ACTIVE",
                    "tenant-id": "aaa0ecf5-9218-482d-9e55-b75a50f22a5c",
                    "uuid": "b94883ed-34ad-4a09-ac58-e459b6b77582"
                },
                {
                    "admin-state-up": true,
                    "name": "net02",
                    "neutron-L3-ext:external": false,
                    "neutron-provider-ext:network-type": "neutron-networks:network-type-vxlan",
                    "neutron-provider-ext:segmentation-id": "1069",
                    "shared": false,
                    "status": "ACTIVE",
                    "tenant-id": "aaa0ecf5-9218-482d-9e55-b75a50f22a5c",
                    "uuid": "f9867311-98c3-4618-be98-6ce75ff8aa23"
                }
            ]
        },
    :
    }
}

再起動したmember-1にも正しくレプリケーションされていることが確認できました。以上で、動作確認は終了です。

今回は、第2回と第3回で解説したOpenStack連携や第4回で解説したRESTCONFなどを取り入れてOpenDaylightのクラスタリングを解説しました。これらのように、OpenDaylightはクライアントアプリケーションにとって汎用性が高く、HAも考慮されている設計になってきています。

著者
安座間 勇二(あざま ゆうじ)
NECソリューションイノベータ株式会社
1991年、沖縄県生まれ。2014年の入社以来、ソフトウェアエンジニアとしてOpenStackでのSFC(Service Function Chaining)やOpenDaylightを使ったSDN/NFVを中心とした開発や検証などに携わる。OpenStack Neutronを中心にコントリビューションしており、OpenStack Summit Tokyo 2015においてSFCのR&Dについて発表。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています