動的プラグインは、ノードの健全性を確認するために、サポートされているトランスポート ノード(ESXi ホストなど)に作成できるカスタマイズされたプラグインです。
動的プラグインはランタイムにインストールできます。次の機能を実行します。
- 影響を受けるトランスポート ノードをシステム ログに記録します。
run_command()
機能を使用して、コマンドまたは CLI を実行します。- 既存のメトリックを読み取ります。
- wavefront にデータをエクスポートします(VMware Cloud 環境のみ)。
NSX の管理に関する専門知識があれば、動的プラグインを作成できます。VMware のサポートは、動的プラグインを作成することもできます。
セキュリティ管理
プラグインを作成したら、プラグインのコード レビューを実行する VMware のエンジニアリング チームに送信する必要があります。レビューの完了後、エンジニアリング チームは、検証のために GIT リポジトリにプラグイン、レビュー テスト結果、およびコード変更を送信します。動的プラグインが検証に合格すると、コミットされ、GIT リポジトリで製品ビルドがトリガされ、すべての動的プラグインを公開する新しいビルドが作成されます。次の GIT リポジトリの詳細が使用されます。
- GitLab: https://gitlab.eng.vmware.com/core-build/nsbu-sha-plugin
- 製品:nsx-sha-plugins
- Gitreview のサポート:VMware チームが実施
必要なプラグインは、ビルドの公開ファイルから取得できます。署名済みのプラグインを管理プレーンにアップロードすると、管理プレーンはパブリック キーで署名を検証し、このプラグインが有効であることを確認します。管理プレーンがプラグインを検証すると、管理プレーンと中央制御プレーン (CCP) 間、CCP とホスト間のセキュアなチャネルを介してプラグインのファイルを宛先のホストにプッシュします。
システムの健全性エージェント (SHA) インスタンスを再起動すると、プラグイン ファイルが管理プレーンから再度取得されます。すべてのファイルはセキュアなチャネルを介して公開されているため、一時ファイルは使用されません。これにより、ハッカーによってスクリプトが改ざんされるリスクを回避できます。
また、有害なコードによるリスクを回避するため、SHA はスクリプトの実行前に RestrictedPython を使用して、プラグインの Python スクリプトをチェックします。
バージョン管理
プラグインで使用されているコマンドまたはツールが NSX の新しいバージョンでサポートされていない場合があります。このため、動的プラグインでは、サポートされている NSX のバージョンを manifest.yml ファイルに定義する必要があります。サポートされているバージョンをすべて定義するため、バージョンは正規表現で記述する必要があります。ホスト側の SHA が動的プラグインのバージョンをチェックし、正規表現で一致したバージョンだけを実行します。
-
サポートされるバージョンとして、メジャー リリースの NSX バージョンを定義します。
同じメジャー リリースのマイナー リリース間では、コマンドとツールはほとんど変わらないため、次のように、すべてのマイナー リリースのバージョンを定義することをおすすめします。
次はその例です。
version: ^2\.5\.[0-9.]+ <== The custom plugin supporting all NSX 2.5 releases
- 新しいメジャー リリースが公開されると、VMware のエンジニアリング チームは送信されたすべての動的プラグインを確認する必要があります。
- 関連するコマンドまたはツールが変更された場合、プラグインの作成者はスクリプトを更新する必要があります。
動的プラグインのインストール
プラグインをインストールするトランスポート ノードまたは Edge ノードには、30 MB 以上のメモリ領域が必要です。また、インストールできるプラグインは最大 10 個までです。プラグインの数が 10 個を超えると、プラグインのインストールは失敗します。
- GIT リポジトリに動的プラグイン ファイルを作成します。プラグイン ファイルの詳細については、「動的プラグイン ファイル」を参照してください。
- GIT リポジトリで製品のビルドをトリガし、動的プラグイン ファイルの ZIP パッケージを生成して、パッケージをダウンロードします。
- POST メソッドを含む次の API を使用して、動的プラグインを作成します。
https://<manager_ip>/api/v1/systemhealth/plugins
- POST メソッドを含む次の API を使用して、管理プレーンにプラグインの ZIP パッケージをアップロードします。管理プレーンで、アップロードしたファイルが展開され、必要な検証が行われます。
/systemhealth/plugins/<plugin-id>/files/<file-name>/data
注: プラグインの ZIP ファイルの最大サイズは 500K です。 - POST メソッドを含む次の API を使用して、必要なトランスポート ノードをメンバーとするノード グループを作成します。
/<manager_ip>/api/v1/ns-groups
- 次の API を使用して新しいサービス構成を作成し、プラグイン プロファイルをノード グループに適用します。サービス構成フレームワークがプラグイン コンテンツをノード グループに送信します。
https://<manager_ip>/api/v1/service-configs
API の詳細については、『NSX API ガイド』を参照してください。
プラグインの状態の取得
動的プラグインを実行すると、既存のメッセージ チャネルを介して状態情報が管理プレーンに自動的にアップロードされます。管理プレーンは、プラグインの状態情報を集約してデータベースに格納します。各ノードのすべてのプラグインの状態を取得するには、GET メソッドを含む次の API を使用します。
https://<manager_ip>/api/v1/systemhealth/plugins/status/<transport_node_id>
要求の例:
GET https://<manager_ip>/api/v1/systemhealth/plugins/status/a257b981-1a1c-4b95-b16c-8646
{ "result_count":1, "results": [ { "id": "72e1bd4b-6df6-42d0-9c59-a1c31312c9f1", "name": "health-check-compute", "status": "NORMAL", "detail": "" } ] }
動的プラグインのアンインストール
プラグインをアンインストールするには、次の API を使用してサービス構成を削除します。
https://<manager_ip>/api/v1/service-configs/<service_config_id>
プラグインの管理に使用するその他の API
次の表に、動的プラグインの管理を行う API を示します。API の詳細については、『NSX API ガイド』を参照してください。
タスク | メソッド | API |
---|---|---|
プラグインを削除する | DELETE | /systemhealth/plugins/<plugin-id> |
システムの健全性プロファイルを作成する | POST | /systemhealth/profiles |
プラグインの状態を監視する |
GET | /systemhealth/plugins/status/<node-id> |
プラグインを有効にする | プラグインを有効にするには、次の 2 段階のプロセスがあります。
|
|
プラグインの間隔を変更する | POST | プラグインの間隔を変更するには、次の 2 段階のプロセスがあります。
|
動的プラグイン ファイル
動的プラグインは、次のファイルで構成されています。
- インストール仕様ファイル。
インストール仕様ファイル ( manifest.yml) には、システムの健全性エージェントに関する次の情報が含まれています。
- プラグインの構造
- 制約(ある場合)
- プラグインをインストールして使用する方法
- 健全性チェック スクリプトのセキュリティ制限。たとえば、スクリプトの権限や、スクリプトからアクセス可能なファイル。
次の表に、 manifest.yml ファイルに指定されているフィールドを示します。名前 説明 必須かどうか 例 classes プラグイン スクリプトで必要なクラスを指定します。 クラスは、次の形式で指定する必要があります。'<module_name>.<class_name>'
オプション classes: ['datetime.datetime','datetime.date']
modules プラグイン スクリプトで必要なモジュールを指定します。 オプション modules: ['random', 'math'] plugin 次のようにプラグイン構造を指定します。
config: 構成ファイル名
script: スクリプト ファイル名
必須 plugin:
config: plugin.cfg.yml
script: plugin.py
バージョン このプラグインをインストールできる NSX バージョンを指定します。 必須 version: '^3\.1\.[0-9.]+'
node_type このプラグインをインストールできる NSX ノード タイプを指定します。使用可能なノード タイプは次のとおりです。
- nsx-esx
- nsx-bms
- nsx-edge
必須 node_type: ['nsx-esx']
metrics プラグイン スクリプトで使用可能なメトリックを指定します。 オプション metrics: ['nsx.host.host-metrics']
precondition プラグインの前提条件を指定します。使用可能な前提条件は、wavefront です。
注: このフィールドは、VMware Cloud 環境にのみ適用されます。オプション precondition: ['wavefront']
次の組み込みモジュールは使用しないでください。-
os
-
subprocess
-
sys
-
multiprocessing
-
importlib
次の表に、各モジュールの組み込み機能の代わりに使用する必要があるインターフェイスを示します。これらのインターフェイスはシステムから提供されます。これらは、 manifest.yml にファイルにモジュール/クラスを指定せず、直接使用することもできます。manifest.yml ファイルのサンプル。モジュール 組み込み機能 代替インターフェイス datetime datetime.date.strftime(self, fmt) datetime_date_strftime(dt, fmt)
:param dt: date instance
:param fmt: format string
datetime datetime.date.today() datetime_date_today() sys sys.getrecursionlimit() sys_getrecursionlimit() sys sys.getrefcount(object) sys_getrefcount(object) sys sys.getsizeof(object, default) sys_getsizeof(object, default) sys sys.maxsize sys_maxsize sys sys.path sys_path # specify classes needed in plugin script classes: ['datetime.datetime','datetime.date'] # specify modules needed in plugin script modules: ['random', 'math'] # plugin structure plugin: config: plugin.cfg.yml script: plugin.py # specify nsx versions on which this plugin can be installed version: '^3\.1\.[0-9.]+' # specify nsx node type where this plugin can be installed node_type: ['nsx-esx'] # specify metrics which can be consumed in plugin script metrics: ['nsx.host.host-metrics'] # specify precondition for plugin precondition: ['wavefront']
- デフォルトのプロファイル ファイル
デフォルトのプロファイル ファイル(plugin.cfg.yml)は、健全性チェック スクリプトの実行頻度などのプラグインの動作を構成するために使用されます。デフォルトの構成を変更するには、特定の動的プラグイン用に SHA プロファイルを作成し、管理プレーンから CCP、CCP から NestDB のチャネルを使用して、NS グループ経由でトランスポート ノードに適用します。
次の表に、 plugin.cfg.yml ファイルに指定されているフィールドを示します。名前 説明 必須かどうか 例 CHECK_INTERVAL プラグイン スクリプトのデフォルトの実行間隔 (秒単位) を指定します。 必須 CHECK_INTERVAL: 20 ENABLE プラグインをデフォルトで有効にするかどうかを指定します。 必須 ENABLE: true plugin.cfg.yml ファイルのサンプル。# Required field - default interval (unit: second) between plugin script executions. CHECK_INTERVAL: 20 # Required field - whether plugin is enabled by default ENABLE: true # Plugin user can add other fields as below if needed to control plugin script logic. EXPORT_DATA: true
- 健全性チェック スクリプト
健全性チェック スクリプト ファイル(plugin.py)には、トランスポート ノードの健全性の状態を確認する Python スクリプトが含まれています。
次の表に、使用可能なシステム定義の変数と機能、 plugin.py ファイルで読み取り可能なデータを示します。変数/データ/機能 説明 タイプ 例 logger Syslog にログ情報を書き込みます。既存のシステム定義変数(logger)は、プラグイン スクリプトで直接使用できます。 次のサンプル出力のように、出力ログでは、プラグイン名と ID がプレフィックスとして追加されます。
2020-10-28T10:47:43Z nsx-sha: NSX 2101378 - [nsx@6876 comp="nsx-esx" subcomp="nsx-sha" username="root" level="INFO"] [name:hl-esx-002-04][id:a3eb14f1-d185-4bc7-bfaa-6cf888bbeb22] dynamic plugin - not export data
変数 logger.info("this is a demo log")
data_store システム提供のデータを取得するために使用される既存のシステム定義のディクショナリ。たとえば、プロファイル、メトリック、host_id などです。
変数 profile = data_store['profile']
profile プロファイル データは、data_store から読み取られるデフォルトのプロファイル (plugin.cfg.ym) または有効な SHA プロファイル(Manager API を介してユーザーが適用)で解析されたディクショナリです。次の形式になっています。
{'ENABLE': True, 'CHECK_INTERVAL': 20, 'EXPORT_DATA': True}
データ profile = data_store['profile']
metric メトリックは、data_store から読み取られる value と timestamp のディクショナリです。次の形式になっています。
data_store['metrics'][<metric_name>]
説明:
最初のキーは metrics にする必要があります。
2 つ目のキーは既存のメトリック名です。
データ metric = data_store['metrics']['nsx.host.host-metrics']
metric is: {
‘value’:XXX, <== the collected data of the metric
‘timestamp’: XXX <== timestamp of the data collected
}
注:現時点では、メトリックが実行中のプラグインと非同期で収集されるため、プラグインの最初の実行時にメトリックが返されない場合があります。そのため、プラグインの最初の実行でメトリックが収集されていないことがあります。
host_id host_id は、data_store から読み込まれたクラス uuid.UUID のインスタンスです。 データ host_id = data_store['host_id']
run_command この機能は、コマンドをリスト形式で実行します。次の形式になっています。 run_command(cmd, timeout=4)
説明:
- cmd:実行されるコマンド。この例のようにリスト形式にする必要があります。
- timeout:コマンドの結果を待機するタイムアウト。デフォルトのタイムアウトは 4s です。20s よりも大きい値は設定できません。
この関数は、コマンドの実行結果を返します。
関数 cmd = ['nsxdp-cli', 'ipfix', 'settings', 'granular', 'get', '--dvs-alias', 'nsxvswitch', '--dvport=dafa09ca-33ed-4e04-ae3d-1c53305d5fe6']
res = run_command(cmd)
Exportdata この関数は データを wavefront にエクスポートします。現在、動的プラグインでサポートされているのは、wavefront へのエクスポートのみです。 注: この関数は、VMware Cloud 環境にのみ適用されます。Exportdata: ExportData(data={}, exports=[], source=host_uuid)
説明:
data:エクスポートするデータ。データは、例のようにディクショナリ形式にする必要があります。
exports:エクスポートの宛先リスト。HL では、宛先の wavefront のみがサポートされます。これは必須です。
source:エクスポートするソース文字列。これは、宛先が wavefront の場合にのみ有効です。これはオプションです。デフォルト値は NSX host_uuid です。
この関数は値を返しません。
関数 Exportdata(data={'esx.plugin.stats': {'stats': {'gc-esx-001': data}}}, exports=['wavefront'])
plugin.py ファイルのサンプル。def report_test_data(edge_service_status): if edge_service_status == 'running': data = 2 else: data = 3 # examples on how to report data to wavefront. Exportdata(data={'esx.plugin.stats': {'stats': {'esx-dynamic-plugin-001': data}}}, exports=['wavefront']) def run(): # examples on how to write log. logger.debug("this is a debug message!") logger.info("this is a demo message!") # examples on how to use specified module in manifest. Take 'random' as an example. s_res = random.randint(1,10) logger.warn("random.randint(1,10)=%s", s_res) # examples on how to use specified class in manifest. Take 'datetime' and 'date' as an example. logger.info('date.ctime(datetime.now()):{}'.format(date.ctime(datetime.now()))) # examples on how to run cmd via interface run_command cmd = ['nsxdp-cli', 'ipfix', 'settings', 'granular', 'get', '--dvs-alias', 'nsxvswitch', '--dvport=dafa09ca-33ed-4e04-ae3d-1c53305d5fe6'] c_res = run_command(cmd) logger.error("run_command(cmd) res:%s", c_res) # examples on how to read existing metrics from data_store m_res = data_store['metrics']['nsx.host.host-metrics'] # examples on how to read effective profile from data_store profile = data_store['profile'] logger.error("data_store['metrics']['nsx.host.host-metrics']:%s, profile:%s", m_res, profile) # examples on how to read host_id from data_store host_id = data_store['host_id'] logger.info('host_id:{}'.format(host_id)) if profile['EXPORT_DATA']: report_test_data('running') logger.info("dynamic plugin - exported data to wavefront") else: logger.info("dynamic plugin - not export data ") # examples on how to use substitute interfaces for sys. logger.info("sys_path:{}".format(sys_path)) logger.info("sys_getsizeof(1):{}".format(sys_getsizeof(1))) logger.info("sys_getrefcount(cmd):{}".format(sys_getrefcount(cmd))) logger.info("sys_maxsize:{}".format(sys_maxsize)) logger.info("sys_getrecursionlimit():{}".format(sys_getrecursionlimit())) # examples on how to use substitute interfaces for datetime. today = datetime_date_today() logger.info("datetime today:{}".format(today)) logger.info("datetime_date_strftime now:{}".format(datetime_date_strftime(datetime.now(), '%H:%M'))) logger.info('date.ctime(today):{}'.format(date.ctime(today))) run()