• EOSへの直接アクセスを可能とするSDK – EOS SDK (後編)

 
 
Print Friendly, PDF & Email

本記事では、アリスタが提供するEOSアプリケーション開発の為のSDKである、EOS SDKを扱います。前編の概要に続き、この後編ではより具体的な実践例を扱います。

 

EOS SDKが必要となる場面

ネットワーク機器の初期構築、運用中に定期的に実行するコマンドオペレーション、あるいは新規テナント用ネットワーク・プロビジョニングなど、即応性の必要がなく、他のネットワーク上のイベントとの連動性が低い場面においては、Ansibleなどに代表されるDevOpsツールや、eAPIのようなRestful APIによるプログラミングが適しています。

一方で、任意のネットワーク上のイベントに素早く反応して設定を変更する、などが必要となる場面では、EOS SDKが活躍する典型例といえます。以下にいくつかそのようなユースケースを示します。

  • MPLSのラベルをみて動的に経路を制御するカスタムエージェントを作成
    • EOS SDKを用いて、インタフェースのUp/Downに反応するような作り込みをし、ProcMgrによりデーモン管理する
  • LAGのメンバーの1/3がダウンしたらQOSポリシーを調整
    • EOS SDKを利用してLAGの状態に対して適宜反応して、QOSを変更するアプリケーションを開発する

その他にも、標準化されたばかりのプロトコルをEOSがサポートする前にSDKで実装して、競争力の高い顧客サービスを展開したい、などの場面において、そのような新規プロトコルを競合他社に先んじてEOSのカスタムエージェントとして運用する、などの使い方も不可能ではありません。

 

EOS SDKの実践的なユースケース

それでは、より実践的なユースケースでEOS SDKを活用してみます。シナリオは以下の通りです。

  1. 2台のEOSデバイスR1とR2のVLAN112にてVRRPを組んでおり、通常時はR1がマスターでR2がバックアップ
  2. R1は、常に自身のルーティングテーブルに192.168.0.0/24のプレフィックスが存在するかをモニターする
  3. 同プレフィックスが消失した場合、つまりR1から192.168.0.0/24への疎通が無くなった場合、自身のVRRP Priorityを90に下げて、マスター・ロールをR2へ遷移させる
  4. 同プレフィックスが復活した場合には、つまりR1から192.168.0.0/24への疎通が可能となった場合には、再びVRRP Priorityを100に上げて、VRRPを通常運用に戻す

通常時 (上記1と上記4の状態)

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2017-12-15-22-41-35

 切替時  (上記3の状態)

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2017-12-15-22-41-48

EOSの vrrp track機能で、指定インターフェイスのダウンを契機にVRRPの操作を行うのは可能ですが、このシナリオは、ルーティングテーブルにおける特定プレフィックスの変化をトリガーとするのが主な違いになります。

 

ルーティングテーブルの変化に即応するアプリケーション例

以下に今回のユースケースに沿ってPythonで記述したアプリケーションであるVrrpTrack.py を示します。

arista@arista:~/EOS-SDK$ cat VrrpTrack.py
#!/usr/bin/env python
import eossdk
import sys
from jsonrpclib import Server

class VrrpTrackAgent(eossdk.AgentHandler, eossdk.FibHandler):
    def __init__(self, agentMgr, fibMgr):
        eossdk.AgentHandler.__init__(self, agentMgr)
        eossdk.FibHandler.__init__(self, fibMgr)
        self.tracer = eossdk.Tracer("VrrpRouteAgent")
        self.agentMgr_ = agentMgr
        self.fibMgr_ = fibMgr
        self.prefix = "0.0.0.0/0"
        self.tracer.trace0("VrrpRouteAgent constructed")

    def on_initialized(self):
        p = self.agentMgr_.agent_option("prefix")
        if p:
            self.on_agent_option("prefix", p)

    def on_agent_option(self, optionName, value):
        if optionName == "prefix":
            if value:
                self.tracer.trace1("tracking %s " % value)
                self.prefix=value

    def manage_vrrp(self, priority):
        self.switch = Server( "unix:/var/run/command-api.sock" )
        self.response = self.switch.runCmds( 1, [ 'show vrrp all'  ] )
        self.virtualRouters=self.response[0]["virtualRouters"]
        for i in self.virtualRouters:
            rc = self.switch.runCmds(1, [ 'enable',
                                          'configure',
                                          'interface %s' % (i['interface']),
                                          'vrrp %s priority %s' % (i['groupId'],priority) ] )
            self.tracer.trace9("Changed VRRP priority for %s" % (i['interface']))

    def on_route_del(self, key):
        deleted_prefix=key.prefix().to_string()
        if(deleted_prefix == self.prefix):
            self.tracer.trace9("Tracked route %s deleted " % self.prefix)
            self.manage_vrrp(90)

    def on_route_set(self, route):
        set_prefix=route.route_key().prefix().to_string()
        if(set_prefix == self.prefix):
            self.tracer.trace9("Tracked route %s added " % self.prefix)
            self.manage_vrrp(100)

if __name__ == "__main__":
    sdk_  = eossdk.Sdk()
    _ = VrrpTrackAgent(sdk_.get_agent_mgr(), sdk_.get_fib_mgr(1))
    sdk_.main_loop(sys.argv)

前回の解説で触れたHandlersオブジェクトを使って、optionで指定する特定のプレフィックスに対する状態変化に即応するようなイベントループを仕掛けているのが肝になります。続くコールバックの on_route_set と on_route_del によって、VRRP Priorityを操作するリアクションを実行します。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2017-12-17-8-56-17

VrrpTrackの動作確認

指定したプレフィックスである192.168.0.0/24の変化に即応して、適宜VRRPが切り替わる様子を、ステップ毎にR1上でのshowコマンドにて示します。

-- Normal Case (R1 is VRRP Master)

R1# show ip route 192.168.0.0/24 
VRF: default 
  Codes: C - connected, S - static, K - kernel, 
  O - OSPF, IA - OSPF inter area, E1 - OSPF external type 1, 
  E2 - OSPF external type 2, N1 - OSPF NSSA external type 1, 
  N2 - OSPF NSSA external type2, B I - iBGP, B E - eBGP, 
  R - RIP, I L1 - IS-IS level 1, I L2 - IS-IS level 2, 
  O3 - OSPFv3, A B - BGP Aggregate, A O - OSPF Summary, 
  NG - Nexthop Group Static Route, V - VXLAN Control Service, 
  DH - Dhcp client installed default route 

S 192.168.0.0/24 [1/0] via 192.0.2.254, Management1 

R1# show vrrp brief
Interface Vrf Id Ver Pri Time State VrIps 
Vlan112 default 1 2 100 3600 Master 198.51.100.112

-- Switchover Case (R1 is VRRP Backup)

R1# configure
R1(config)# no ip route 192.168.0.0/24
R1(config)#show ip route 192.168.0.0/24
VRF: default 
  Codes: C - connected, S - static, K - kernel, 
  O - OSPF, IA - OSPF inter area, E1 - OSPF external type 1, 
  E2 - OSPF external type 2, N1 - OSPF NSSA external type 1, 
  N2 - OSPF NSSA external type2, B I - iBGP, B E - eBGP, 
  R - RIP, I L1 - IS-IS level 1, I L2 - IS-IS level 2, 
  O3 - OSPFv3, A B - BGP Aggregate, A O - OSPF Summary, 
  NG - Nexthop Group Static Route, V - VXLAN Control Service, 
  DH - Dhcp client installed default route 

Gateway of last resort: 
S 0.0.0.0/0 [1/0] via 192.0.2.254, Management1

R1(config)# show vrrp brief 
Interface Vrf Id Ver Pri Time State VrIps 
Vlan112 default 1 2 90 3640 Backup 198.51.100.112 


-- Switchback Case (R1 is VRRP Master)

R1(config)#ip route 192.168.0.0/24 192.0.2.254 
R1# show ip route 192.168.0.0/24 
VRF: default 
  Codes: C - connected, S - static, K - kernel, 
  O - OSPF, IA - OSPF inter area, E1 - OSPF external type 1, 
  E2 - OSPF external type 2, N1 - OSPF NSSA external type 1, 
  N2 - OSPF NSSA external type2, B I - iBGP, B E - eBGP, 
  R - RIP, I L1 - IS-IS level 1, I L2 - IS-IS level 2, 
  O3 - OSPFv3, A B - BGP Aggregate, A O - OSPF Summary, 
  NG - Nexthop Group Static Route, V - VXLAN Control Service, 
  DH - Dhcp client installed default route 

S 192.168.0.0/24 [1/0] via 192.0.2.254, Management1 

R1(config)#show vrrp brief 
Interface Vrf Id Ver Pri Time State VrIps 
Vlan112 default 1 2 100 3600 Master 198.51.100.112 

 

フローで見るeAPIとEOS SDK

最後に、eAPIとEOS SDKのそれぞれの実現方法の違いを明確にする為に、今回のシナリオをフローで見てみます。

 eAPIで実装した場合のフロー

eapi

リモートノードあるいはローカルノード(EOSデバイスそのもの)で、ポーリングベースで上記フローを一定間隔で繰り返すことになります。例えば、Linuxのcronなどの仕組みで数分間隔で実行する、などです。その為、VRRPの切り替えスピードはポーリング実行間隔に依存します。間隔を短くすれば、切り替えは早くなるものの、システム観点での負荷が上がりますし、間隔を長くすれば、今度は切り替えが遅くなってしまう可能性が高まりますので、高可用性が求められるネットワークでは、このあたりのバランスを取るのが難しいかもしれません。

EOS SDKで実装した場合のフロー

sdk

ローカルノードでEOSのネイティブ アプリケーションの一つとして起動した後、SysDBにサブスクライブし、SysDB側からの通知(パブリッシュ)待ちのループに入ります。イベントドリブン型ですので、ポーリングが不要な分、状態変化が無い場合はシステム負荷を抑えることができますし、状態が変化した場合、つまりプレフィックスに変更があった場合には、直ちにVRRPの切り替えを行うブロック(”Prefix変更”ブロック以降)が実行されますので、即座にVRRPを切り替えることで高可用性を実現可能です。

 

まとめ

二回に渡ってEOS SDKを扱いましたが、日々のネットワーク運用の中で「ポーリングベースのアプリケーションでは期待する性能が実現できないシナリオがある」などのお悩みを抱えていらっしゃる方は、今回ご紹介したEOS SDKを活用しての実現が可能かを検討してみるのも一つの手かもしれません。

EOS SDKのGithubサイトには豊富なサンプルが揃っていますので、それらを参考に様々なカスタムEOSエージェントをお試し頂けると思いますので、ぜひトライしてみてください。

なお「〜のようなロジックのカスタムエージェントを実現したいけど、手間がかかるのでコーディングからサポートして欲しい」あるいは「〜を実現するであろうアプリケーションをEOS SDK(あるいはeAPI)で書いたけど、しっかりしたコードレビューとテストを実施して欲しい」などのご要望があればお気軽にご相談下さい。アリスタネットワークスは、そのような場面を専門のチームでサポートするEOSコンサルティング サービスを提供しておりますので、ぜひご活用下さい。

 

Appendix: VrrpTrackの配備

VRRPの設定については省略していますので、こちらを参照の上適宜設定をお願いします。なお、以下の配備例のVRRP Priorityですが、R1はデフォルトの100を、R2は95を使用しています。

(1) 前項のVrrpTrack.pyをEOSデバイスへコピーします。

R1> enable
R1# copy <url-or-path-to-the-VrrpTrack.py> flash:

(2) リアクションの実行に用いるeAPIを有効にします。なお、以前にご紹介したhttp/https経由のeAPIでも設定投入は可能ですが、ローカルからeAPIを実行する際にはUNIXのソケットを使う方法がより安全で高速に動作しますので、今回はこちらを使います。

R1# configure
R1(config)# management api http-commands
R1(config-mgmt-api-http-cmds)# protocol unix-socket 
R1(config-mgmt-api-http-cmds)# no shutdown

(3) コピーしたPythonスクリプトをデーモンとして設定します。

R1(config)# daemon VrrpTrack
R1(config-daemon-VrrpTrack)# exec /mnt/flash/VrrpTrack.py
R1(config-daemon-VrrpTrack)# option prefix value 192.168.0.0/24
R1(config-daemon-VrrpTrack)# no shutdown

(4) デーモンとしての設定が完了すれば、show daemon コマンドにて、アプリケーションの稼働状況を確認できます。

R1(config-daemon-VrrpTrack)# show daemon 
Agent: VrrpTrack (running) 
Configuration: 
Option Value 
------------ -------------- 
prefix 192.168.0.0/24 

No status data stored. 
R1(config-daemon-VrrpTrack)#
Follow

Get every new post on this blog delivered to your Inbox.

Join other followers: