Extensible Telemetry Guide
拡張可能テレメトリの概要
Apstraのデバイスドライバーとテレメトリコレクターをインストールして、 IBAプローブで使用できる追加のテレメトリを収集します。デバイスドライバーにより、ApstraはNOSに接続し、テレメトリを収集できます。Apstraには、EOS、NX-OS、Ubuntu、CentOSのドライバが同梱されています。ここに記載されていないオペレーティング システムのドライバを追加するには、 Juniper Support にお問い合わせください。
テレメトリ コレクターは、拡張テレメトリの収集に役立つ Python モジュールです。以下のセクションでは、テレメトリコレクターを作成し、新しいコレクターでApstraを拡張するためのパイプラインについて説明します。コレクターを開発するには、Python に精通している必要があります。
開発環境の設定
テレメトリ コレクター( aos_developer_sdk リポジトリに格納)へのアクセスについては、 Juniper Support にお問い合わせください。開発した新しいコレクターをリポジトリに投稿します。
システム環境を損ならないように、仮想環境を使用して(開発とテストのために)必要な Python パッケージを分離することをお勧めします。https://support.juniper.net/support/downloads/?p=apstra/ から、 aos_developer_sdk.run の基本開発環境 をダウンロードできます。環境を読み込むには、以下を実行します。
aos_developer_sdk$ bash aos_development_sdk.run 4d8bbfb90ba8: Loading layer [==================================================>] 217.6kB/217.6kB 7d54ea05a373: Loading layer [==================================================>] 4.096kB/4.096kB e2e40f457231: Loading layer [==================================================>] 1.771MB/1.771MB Loaded image: aos-developer-sdk:2.3.1-129 ================================================================================ Loaded AOS Developer SDK Environment Container Image aos-developer-sdk:2.3.1-129. Container can be run by docker run -it \ -v <path to aos developer_sdk cloned repo>:/aos_developer_sdk \ --name <container name> \ aos-developer-sdk:2.3.1-129 ================================================================================
このコマンドは、aos_developer_sdk Docker イメージを読 み込 みます。イメージの読み込みが完了すると、環境を開始するコマンドが印刷されます。コマンドの指定に応じてコンテナ環境を起動します。依存関係をインストールするには、以下を実行します。
root@f2ece48bb2f1:/# cd /aos_developer_sdk/ root@f2ece48bb2f1:/aos_developer_sdk# make setup_env ...
コレクターの開発とテスト用に環境がセットアップされました。デバイス ドライバーや REST クライアントなどの Apstra SDK パッケージも、環境にインストールされます。
コレクターの開発
テレメトリ コレクターを開発するには、次の 順序で指定します。
書き込みコレクター
コレクターは、 aos.sdk.system_agent.base_telemetry_collector から派生する必要があるクラスです。BaseTelemetryCollectorコレクターの 収集 メソッドをロジックで上書きし、以下の操作を行います。
デバイスからデータを収集
コレクター内のデバイス ドライバー インスタンスには、デバイスに対してコマンドを実行するメソッドが用意されています。たとえば、ほとんどのApstraデバイスドライバはメソッドを get_json
提供し、 get_text
コマンドを実行して出力を返します。
aos_developer_sdk環境のデバイスドライバーは事前にインストールされています。データを収集するために利用可能な方法を調めることができます。例えば:
>>> from aos.sdk.driver.eos import Device >>> device = Device('172.20.180.10', 'admin', 'admin') >>> device.open() >>> pprint.pprint(device.get_json('show version')) {u'architecture': u'i386', u'bootupTimestamp': 1548302664.0, u'hardwareRevision': u'', u'internalBuildId': u'68f3ae78-65cb-4ed3-8675-0ff2219bf118', u'internalVersion': u'4.20.10M-10040268.42010M', u'isIntlVersion': False, u'memFree': 3003648, u'memTotal': 4011060, u'modelName': u'vEOS', u'serialNumber': u'', u'systemMacAddress': u'52:54:00:ce:87:37', u'uptime': 62620.55, u'version': u'4.20.10M'} >>> dir(device) ['AOS_VERSION_FILE', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'close', 'device_info', 'driver', 'execute', 'get_aos_server_ip', 'get_aos_version_related_info', 'get_device_aos_version', 'get_device_aos_version_number', 'get_device_info', 'get_json', 'get_text', 'ip_address', 'onbox', 'open', 'open_options', 'password', 'probe', 'set_device_info', 'upload_file', 'username']
データを解析
収集されたデータは、Apstraフレームワークと上記で識別されたサービススキーマに従って解析し、再フォーマットする必要があります。一般ストレージ スキーマを持つコレクターは、次の構造に従います。
{ "items": [ { "identity": <key goes here>, "value": <value goes here>, }, { "identity": <key goes here>, "value": <value goes here>, }, ... ] }
IBAベースのスキーマを持つコレクターは、以下の構造に従います。
[ { "key": <key goes here>, "value": <value goes here>, }, { "key": <key goes here>, "value": <value goes here>, }, ... ]
上記の構造では、転記されたデータには複数の項目があります。各項目にはキーと値があります。たとえば、インターフェイス固有の情報を投稿するには、フレームワークに投稿する各インターフェイスにアイデンティティ/キー値のペアが存在します。
サードパーティパッケージを使用してデバイスから取得したデータを解析する場合は、パス内のPythonパッケージとバージョンをリストします。
<aos_developer_sdk>/aosstdcollectors/requirements_<NOS>.txt
.依存関係によってインストールされたパッケージは、Apstraソフトウェアが使用するパッケージと競合しません。Apstraにインストールされたパッケージは、開発環境で /etc/aos/python_dependency.txt
利用できます。
フレームワークへのデータの投稿
データを収集し、必要なスキーマに従って解析する場合は、データをフレームワークに投稿します。コレクターで post_data
利用可能なメソッドを使用できます。1 つの引数を受け入れ、それはフレームワークに投稿する必要があるデータです。
リポジトリ内のフォルダ aos_developer_sdk/aosstdcollectors/aosstdcollectors
には、各NOSのフォルダが含まれています。NOSと一致するフォルダにコレクターを追加します。CumulusはApstraバージョン4.1.0ではサポートされていませんが、この例は具体的な目的で使用されています。たとえば、Cumulus のコレクターを作成するには、コレクターを 、 に aos_developer_sdk/aosstdcollectors/aosstdcollectors/cumulus
追加し、サービス名の後にファイルの名前を付けます。例えば、サービス名が 、 の場合は interface_in_out_bytes
、ファイル interface_in_out_bytes.py
の名前を指定します。
コレクター クラスの定義に加えて、コレクター ファイルで関数 collector_plugin
を定義します。この関数は、1 つの引数を取得し、実装されているコレクター クラスを返します。
たとえば、一般的なストレージスキーマベースのコレクターは次のようになります。
""" Service Name: interface_in_out_bytes Schema: Key: String, represents interface name. Value: Json String with two possible keys: rx: integer value, represents received bytes. tx: integer value, represents transmitted bytes. DOS: eos Data collected using command: 'show interfaces' Type of Collector: BaseTelemetryCollector Storage Schema Path: aos.sdk.telemetry.schemas.generic Application Schema: { 'type': 'object', 'properties': { 'identity': { 'type': 'string', }, 'value': { 'type': 'object', 'properties': { 'rx': { 'type': 'number', }, 'tx': { 'type': 'number', } }, 'required': ['rx', 'tx'], } } } """ import json from aos.sdk.system_agent.base_telemetry_collector import BaseTelemetryCollector # Inheriting from BaseTelemetryCollector class InterfaceRxTxCollector(BaseTelemetryCollector): # Overriding collect method def collect(self): # Obtaining the command output using the device instance. collected_data = self.device.get_json('show interfaces') # Data is in the format # "interfaces": { # "<interface_name>": { # .... # "interfaceCounters": { # .... # "inOctets": int # "outOctets": int # .... # } # } # ... # } # Parse the data as per the schema and structure required. parsed_data = json.dumps({ 'items': [ { 'identity': intf_name, 'value': json.dumps({ 'rx': intf_stats['interfaceCounters'].get('inOctets'), 'tx': intf_stats['interfaceCounters'].get('outOctets'), }) } for intf_name, intf_stats in collected_data['interfaces'].iteritems() if 'interfaceCounters' in intf_stats ] }) # Post the data to the framework self.post_data(parsed_data) # Define collector_plugin class to return the Collector def collector_plugin(_device): return InterfaceRxTxCollector
IBAストレージスキーマベースのコレクターは次のようになります。
""" Service Name: iba_bgp Schema: Key: JSON String, specifies local IP and peer IP. Value: String. ‘1’ if state is established ‘2’ otherwise DOS: eos Data collected using command: 'show ip bgp summary vrf all' Storage Schema Path: aos.sdk.telemetry.schemas.iba_string_data Application Schema: { 'type': 'object', 'properties': { key: { 'type': 'object', 'properties': { 'local_ip': { 'type': 'string', }, 'peer_ip': { 'type': 'string', } }, 'required': ['local_ip', 'peer_ip'], }, 'value': { 'type': 'string', } } } """ from aos.sdk.system_agent.base_telemetry_collector import IBATelemetryCollector def parse_text_output(collected): result = [ {'key': {'local_ip': str(vrf_info['routerId']), 'peer_ip': str(peer_ip)}, 'value': str( 1 if session_info['peerState'] == 'Established' else 2)} for vrf_info in collected['vrfs'].itervalues() for peer_ip, session_info in vrf_info['peers'].iteritems()] return result # Inheriting from BaseTelemetryCollector class IbaBgpCollector(BaseTelemetryCollector): # Overriding collect method def collect(self): # Obtaining the command output using the device instance. collected_data = self.device.get_json('show ip bgp summary vrf all') # Parse the data as per the schema and structure required and # post to framework. self.post_data(parse_text_output(collected_data)) # Define collector_plugin class to return the Collector def collector_plugin(device): return IbaBgpCollector
単体テスト コレクター
リポジトリ内のフォルダー aos_developer_sdk/aosstdcollectors/test
には、NOS に基づくフォルダーが含まれています。NOS に一致するフォルダーにテストを追加します。たとえば、Cumulus のコレクターへのテストが に aos_developer_sdk/aosstdcollectors/test/cumulus
追加されます。ユニットテストの名前をプレフィックス test_
にすることをお勧めします。
既存のインフラストラクチャでは、デバイス ドライバコマンドの応答を模擬して使用する Pytest 固定具 collector_factory
を実装しています。テスト開発の一般的なフローは次のとおりです。
- コレクターファクトリを使用して、コレクターインスタンスと模擬Apstraフレームワークを取得します。コレクター ファクトリは、入力として記述したコレクター クラスを受け取ります。
- デバイスの応答を模擬します。
- 収集メソッドを呼び出す。
- 模擬的なApstraフレームワークに投稿されたデータを検証します。
例えば、テストは次のようになります。
import json from aosstdcollectors.eos.interface_in_out_bytes import InterfaceRxTxCollector # Test method with prefix 'test_' def test_sanity(collector_factory): # Using collector factory to retrieve the collector instance and mocked # Apstra framework. collector, mock_framework = collector_factory(InterfaceRxTxCollector) command_response = { 'interfaces': { 'Ethernet1': { 'interfaceCounters': { 'inOctets': 10, 'outOctets': 20, } }, 'Ethernet2': { 'interfaceCounters': { 'inOctets': 30, 'outOctets': 40, } } } } # Set the device get_json method to retrieve the command response. collector.device.get_json.side_effect = lambda _: command_response # Invoke the collect method collector.collect() expected_data = [ { 'identity': 'Ethernet1', 'value': json.dumps({ 'rx': 10, 'tx': 20, }), }, { 'identity': 'Ethernet2', 'value': json.dumps({ 'rx': 30, 'tx': 40, }) } ] # validate the data posted by the collector data_posted_by_collector = json.loads(mock_framework.post_data.call_args[0][0]) assert sorted(expected_data) == sorted(data_posted_by_collector["items"])
テストを実行するには、以下を実行します。
root@1df9bf89aeaf:/aos_developer_sdk# make test root@1df9bf89aeaf:/aos_developer_sdk# make test
このコマンドは、リポジトリ内のすべてのテストを実行します。
パッケージ コレクター
すべてのコレクターは NOS に基づいてパッケージ化されます。すべてのパッケージを生成するには、 で aos_develop_sdk
を実行します。ビルドパッケージ aos_developer_sdk/dist
を見つけることができます.パッケージのビルドは大きく分類できます。
パッケージ | の説明 |
---|---|
内蔵コレクター パッケージ | これらのパッケージには、プレフィックス aosstdcollectors_builtin_があります。Apstraは、リファレンスデザインに従ってデバイスからテレメトリを収集するために、セクションに記載されているサービスを <deviceblah> 必要とします。組み込みコレクター パッケージには、これらのサービスのコレクターが含まれています。パッケージは NOS 単位で生成されます。 |
カスタム コレクター パッケージ | これらのパッケージの名前にはプレフィックス aosstdcollectors_custom_ が含まれています。パッケージは NOS 単位で生成されます。 aosstdcollectors_custom_<NOS>-0.1.0-py2-none-any.whl というパッケージには、開発されたコレクターが含まれています。 |
Apstra SDKデバイスドライバパッケージ | これらのパッケージにはプレフィックス apstra_devicedriver_があります。これらのパッケージは、NOS 単位で生成されます。パッケージは、Apstraではデフォルトでは利用できないNOS用に生成されます。 |
パッケージのアップロード
Apstraソフトウェアに内蔵コレクターパッケージとデバイスオペレーティングシステム(NOS)用のApstra SDKデバイスドライバが提供されていない場合は、Apstraサーバーにアップロードする必要があります。
オフボックス ソリューションを使用していて NOS が EOS でない場合は、組み込みのコレクター パッケージをアップロードする必要があります。
コレクターを含むパッケージをアップロードし、デバイスシステムエージェントまたはシステムエージェントプロファイルに割り当てます。
テレメトリ コレクターの使用
テレメトリサービスレジストリの設定
レジストリは、そのアプリケーションスキーマとストレージスキーマパスにサービスをマッピングします。REST エンドポイント /api/telemetry-service-registry
でテレメトリ サービス レジストリを管理できます。特定のサービスのレジストリ エントリを追加せずにサービスのコレクターを有効にすることはできません。サービスのレジストリ エントリは、サービスの使用中に変更できません。
実行 make
すると、すべてのアプリケーション スキーマが dist フォルダー内の tar ファイル (json_schemas.tgz) に一緒にパッケージ化されます。apstra-cliでは、.tgzファイル内のすべてのスキーマをインポートするオプションがあります。
開始コレクター
サービスを開始するには、次の 3 つの引数を使用して POST API /api/systems/<system_id>/services
を使用します。
引数 | |
---|---|
Input_data | コレクターへの入力として提供されるデータ。デフォルトは「なし」です。 |
間隔 | サービスを実行する間隔。デフォルトは120秒です。 |
名前 | サービスの名前。 |
また、apstra-cliユーティリティを使用してコレクターを管理することもできます。
コレクターの削除
サービスを削除するには、DELETE API を使用します /api/systems/<system_id>/services/<service_name>
。
収集されたデータの取得
収集されたデータを取得するには、GET API を使用します /api/systems/<system_id>/services/<service_name>/data
。最後の反復で収集されたデータのみが保存されます。Apstraの再起動後もデータは持続しません。
実行中のコレクター サービスの一覧表示
デバイスで有効になっているサービスのリストを取得するには、GET API を使用します /api/systems/<system_id>/services
。