Ein dynamisches Plug-in ist ein benutzerdefiniertes Plug-in, das Sie für jeden unterstützten Transportknoten (z. B. ESXi-Host) erstellen können, um den Systemstatus des Knotens zu überprüfen.
Ein dynamisches Plug-in kann zur Laufzeit installiert werden. Es führt die folgenden Funktionen aus:
- Ein Systemprotokoll für den betroffenen Transportknoten schreiben.
- Einen Befehl oder einen CLI-Befehl über die
run_command()
-Funktion ausführen. - Vorhandene Metriken lesen.
- Daten in Wavefront exportieren (nur in einer VMware Cloud-Umgebung).
Sie können ein dynamisches Plug-in erstellen, wenn Sie über Kenntnisse in der Verwaltung von NSX verfügen. Der VMware-Support kann auch ein dynamisches Plug-in erstellen.
Sicherheitsverwaltung
Nachdem Sie das Plug-in erstellt haben, müssen Sie es an das VMware Engineering-Team übermitteln, das eine Codeprüfung des Plug-ins durchführt. Nach Abschluss der Überprüfung übermittelt das Engineering-Team das Plug-in, das Testergebnis und Codeänderungen in einem GIT-Repository zur Validierung. Wenn das dynamische Plug-in die Validierung besteht, wird es committed und ein Produkt-Build wird im GIT-Repository ausgelöst, um eine neue Version für die Veröffentlichung aller dynamischen Plug-ins zu erstellen. Die folgenden Git-Repository-Details werden verwendet:
- GitLab: https://gitlab.eng.vmware.com/core-build/nsbu-sha-plugin
- Produkt: nsx-sha-plugins
- Gitreview-Unterstützung: Wird von VMware-Team ausgeführt
Sie können das erforderliche Plug-in aus den veröffentlichten Dateien des Build abrufen. Wenn Sie ein signiertes Plug-in auf die Management Plane hochladen, verwendet die Management Plane einen öffentlichen Schlüssel, um die Signatur zu überprüfen und zu bestätigen, dass dieses Plug-in gültig ist. Nach der Validierung des Plug-ins durch die Management Plane werden die Dateien des Plug-ins über die gesicherten Kanäle zwischen der Management Plane und der zentralen Control Plane (CCP) und zwischen CCP und Hosts an die Zielhosts übertragen.
Wenn Sie die Instanz des Systemintegritäts-Agents (SHA) neu starten, werden die Plug-ins erneut von der Management Plane abgerufen. Da alle Dateien über gesicherte Kanäle veröffentlicht werden und keine temporären Dateien verwendet werden, besteht kein Risiko, dass Hacker die Skripte verändern könnten.
Um Risiken durch schädlichen Code zu verhindern, verwendet SHA außerdem RestrictedPython, um das Python-Skript des Plug-ins vor der Ausführung des Skripts zu überprüfen.
Versionsverwaltung
Ein Plug-in basiert unter Umständen auf einem Befehl oder einem Tool, das in späteren Versionen von NSX nicht mehr unterstützt wird. Daher muss jedes dynamische Plug-in die unterstützte NSX-Version in der Datei manifest.yml definieren. Bei der Version sollte es sich um eine REGEX-Zeichenfolge für alle unterstützten Versionen handeln. Der SHA auf der Hostseite prüft die Version dynamischer Plug-ins und führt nur die mit der REGEX übereinstimmenden aus.
-
Definieren Sie die unterstützte NSX-Version einer Hauptversion.
In Anbetracht der Tatsache, dass die meisten Befehle und Tools bei Nebenversionen derselben Hauptversion nicht geändert werden, wird die folgende Methode empfohlen, um die Version für alle Nebenversionen zu definieren.
Beispiel:
version: ^2\.5\.[0-9.]+ <== The custom plugin supporting all NSX 2.5 releases
- Wenn eine neue Hauptversion veröffentlicht wird, muss das Engineering-Team von VMware alle übermittelten dynamischen Plug-Ins überprüfen.
- Der Verfasser des Plug-ins muss das Skript aktualisieren, wenn sich die zugehörigen Befehle oder Tools ändern.
Installieren eines dynamischen Plug-ins
Der Transportknoten bzw. der Edge-Knoten, auf dem das Plug-in installiert ist, muss über mindestens 30 MB Speicherplatz verfügen. Beachten Sie außerdem, dass nur bis zu 10 Plug-ins installiert werden können. Sobald die Anzahl der Plug-ins 10 erreicht hat, schlägt die weitere Installation eines Plug-ins fehl.
- Erstellen Sie die Dateien für das dynamische Plug-in im GIT-Repository. Weitere Informationen zu den Plug-in-Dateien finden Sie im Abschnitt Dateien für dynamische Plug-ins.
- Lösen Sie den Produkt-Build im GIT-Repository aus, um das komprimierte Paket der Dateien für das dynamische Plug-in zu generieren und das Paket herunterzuladen.
- Erstellen Sie das dynamische Plug-in mithilfe der folgenden API mit der POST-Methode.
https://<manager_ip>/api/v1/systemhealth/plugins
- Laden Sie das komprimierte Plug-in-Paket mit der folgenden API mit der POST-Methode auf die Management Plane hoch. Die Management Plane extrahiert die hochgeladene Datei und führt die erforderliche Validierung durch.
/systemhealth/plugins/<plugin-id>/files/<file-name>/data
Hinweis: Die maximale Größe der komprimierten Plug-in-Datei beträgt 500 K. - Erstellen Sie eine Knotengruppe mit den erforderlichen Transportknoten als Mitglieder, indem Sie die folgende API mit der POST-Methode verwenden.
/<manager_ip>/api/v1/ns-groups
- Wenden Sie das Plug-in-Profil auf die Knotengruppe an, indem Sie eine neue Dienstkonfiguration mithilfe der folgenden API erstellen. Das Dienstkonfigurations-Framework sendet den Plug-in-Inhalt an die Knotengruppe.
https://<manager_ip>/api/v1/service-configs
Weitere Informationen zu APIs finden Sie im NSX-API-Handbuch.
Abrufen des Plug-in-Status
Sobald das dynamische Plug-in ausgeführt wird, wird der Status automatisch über den vorhandenen Nachrichtenkanal auf die Management Plane hochgeladen. Die Management Plane aggregiert die Statusinformationen des Plug-ins und speichert Sie in der Datenbank. Um den Status aller Plug-ins auf jedem Knoten abzurufen, verwenden Sie die folgende API mit der GET-Methode.
https://<manager_ip>/api/v1/systemhealth/plugins/status/<transport_node_id>
Anforderungsbeispiel:
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": "" } ] }
Deinstallieren eines dynamischen Plug-ins
Um ein Plug-in zu deinstallieren, entfernen Sie die Dienstkonfiguration mithilfe der folgenden API.
https://<manager_ip>/api/v1/service-configs/<service_config_id>
Andere APIs für die Verwaltung der Plug-ins
In der folgenden Tabelle sind die APIs für die Verwaltung von dynamischen Plug-ins aufgelistet. Weitere Informationen zu APIs finden Sie im NSX-API-Handbuch.
Aufgabe | Methode | API |
---|---|---|
Löschen eines Plug-ins | LÖSCHEN | /systemhealth/plugins/<plugin-id> |
Erstellen eines Systemzustandprofils | POST | /systemhealth/profiles |
Einsehen des Plug-in-Status |
GET | /systemhealth/plugins/status/<node-id> |
Aktivieren des Plug-ins | Die Aktivierung eines Plug-ins ist ein zweistufiger Prozess:
|
|
Ändern des Plug-in-Intervalls | POST | Die Änderung des Plug-in-Intervalls ist ein zweistufiger Prozess:
|
Dateien für dynamische Plug-ins
Ein dynamisches Plug-in besteht aus den folgenden Dateien:
- Datei mit den Installationsspezifikationen
Die Datei mit den Installationsspezifikationen manifest.yml enthält die folgenden Informationen für den System Health Agent:
- Plug-in-Struktur
- Einschränkungen, falls vorhanden
- Installieren und Verwenden des Plug-ins
- Sicherheitseinschränkungen für das Skript für die Integritätsprüfung. Zum Beispiel Berechtigungen, die das Skript hat, und Dateien, auf die das Skript zugreifen kann.
In der folgenden Tabelle sind Felder aufgelistet, die in einer manifest.yml-Datei angegeben sind.Name Beschreibung Erforderlich/Optional Beispiel classes Gibt Klassen an, die im Skript des Plug-ins benötigt werden. Die Klassen müssen im folgenden Format angegeben werden. '<module_name>.<class_name>'
Optional classes: ['datetime.datetime','datetime.date']
modules Gibt Module an, die im Skript des Plug-ins benötigt werden. Optional Module: ['random', 'math'] plugin Gibt die Plug-in-Struktur wie folgt an:
Konfiguration: Name der Konfigurationsdatei
Skript: Name der Skriptdatei
Erforderlich plugin:
config: plugin.cfg.yml
script: plugin.py
version Gibt die NSX-Versionen an, auf denen dieses Plug-in installiert werden kann. Erforderlich version: '^3\.1\.[0-9.]+'
node_type Gibt die NSX-Knotentypen an, auf denen dieses Plug-in installiert werden kann. Die verfügbaren Knotentypen sind:
- nsx-esx
- nsx-bms
- nsx-edge
Erforderlich node_type: ['nsx-esx']
metrics Gibt Metriken an, die im Skript des Plug-ins verbraucht werden können. Optional metrics: ['nsx.host.host-metrics']
precondition Gibt die Vorbedingung für das Plug-in an. Die verfügbare Vorbedingung ist Wavefront.
Hinweis: Dieses Feld bezieht sich nur auf eine VMware Cloud-Umgebung.Optional precondition: ['wavefront']
Verwenden Sie nicht die folgenden integrierten Module:-
os
-
subprocess
-
sys
-
multiprocessing
-
importlib
In der folgenden Tabelle sind die Schnittstellen aufgelistet, die Sie anstelle der integrierten Funktionen der jeweiligen Module verwenden müssen. Diese Schnittstellen werden vom System bereitgestellt. Sie können sie direkt verwenden, ohne deren Modul/Klasse in der Datei manifest.yml-Datei anzugeben.Beispiel einer manifest.yml-Datei.Modul Integrierte Funktion Ersatzschnittstelle 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']
- Standardprofildatei
Die Standardprofildatei plugin.cfg.yml wird verwendet, um das Plug-in-Verhalten zu konfigurieren, wie z. B. die Ausführungshäufigkeit des Skripts für die Integritätsprüfung. Um die Standardkonfigurationen zu ändern, können Sie ein SHA-Profil für ein bestimmtes dynamisches Plug-in erstellen und es auf den Transportknoten über die NS-Gruppe anwenden, indem Sie den Kanal von der Management Plane zu CCP zu NestDB verwenden.
In der folgenden Tabelle sind Felder aufgelistet, die in einer plugin.cfg.yml-Datei angegeben sind.Name Beschreibung Erforderlich/Optional Beispiel CHECK_INTERVAL Gibt das Standardintervall für die Ausführung des Plug-in-Skripts in Sekunden an. Erforderlich CHECK_INTERVAL: 20 AKTIVIEREN Gibt an, ob das Plug-in standardmäßig aktiviert ist. Erforderlich ENABLE: true Beispiel einer plugin.cfg.yml-Datei.# 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
- Skript für die Integritätsprüfung
Die Datei mit dem Skript für die Integritätsprüfung plugin.py enthält ein Python-Skript zur Überprüfung des Integritätsstatus eines Transportknotens.
In der folgenden Tabelle sind die systemdefinierten Variablen und Funktionen, die verwendet werden können, und Daten, die in einer plugin.py-Datei gelesen werden können, aufgelistet.Variable/Daten/Funktion Beschreibung Typ Beispiel logger Schreibt Protokollinformationen in syslog. Die vorhandene systemdefinierte Variable „logger“ kann direkt im Skript des Plug-ins verwendet werden. Das Ausgabeprotokoll wird mit dem Namen und der ID des Plug-ins wie in der folgenden Beispielausgabe dargestellt.
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
Variable logger.info("this is a demo log")
data_store Das vorhandene systemdefinierte Wörterbuch, das zum Abrufen von vom System bereitgestellten Daten verwendet wird. Beispielsweise „profile“, „metric“, und „host_id“.
Variable profile = data_store['profile']
profile Bei „profile“ handelt es sich um ein aus dem Standardprofil (plugin.cfg.yml) oder dem effektiven SHA-Profil (vom Benutzer über die Manager-API angewendet) analysiertes Wörterbuch, das aus „data_store“ gelesen wird. Es weist folgendes Format auf:
{'ENABLE': True, 'CHECK_INTERVAL': 20, 'EXPORT_DATA': True}
Daten profile = data_store['profile']
metric Bei „metric“ handelt es sich um ein Wörterbuch mit 'value' und 'timestamp', das aus „data_store“ gelesen wird. Es weist folgendes Format auf:
data_store['metrics'][<metric_name>]
Dabei gilt Folgendes:
Der erste Schlüssel muss 'metrics' lauten.
Der zweite Schlüssel ist der Name einer vorhandenen Metrik.
Daten 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
}
Hinweis: Bei der ersten Ausführung des Plug-ins wird möglicherweise keine Metrik zurückgegeben, da derzeit eine Metrik asynchron mit dem ausgeführten Plug-in erfasst wird, sodass die Metrik bei der ersten Ausführung des Plug-ins unter Umständen nicht erfasst wurde.
host_id „host_id“ ist eine Instanz der Klassen-uuid.UUID, die von „data_store“ gelesen wird. Daten host_id = data_store['host_id']
run_command Diese Funktion führt Befehle in einem Listenformat aus. Sie weist folgendes Format auf. run_command(cmd, timeout=4)
Dabei gilt Folgendes:
- cmd: Befehle, die ausgeführt werden sollen. Muss im Listenformat wie im Beispiel angegeben werden.
- timeout: Zeitüberschreitung beim Warten auf das Befehlsergebnis. Die standardmäßige Zeitüberschreitung beträgt 4 s. Die Zeitüberschreitung darf nicht auf mehr als 20 s festgelegt werden.
Diese Funktion gibt das Ergebnis der Befehlsausführung zurück.
Funktion cmd = ['nsxdp-cli', 'ipfix', 'settings', 'granular', 'get', '--dvs-alias', 'nsxvswitch', '--dvport=dafa09ca-33ed-4e04-ae3d-1c53305d5fe6']
res = run_command(cmd)
Exportdata Mit dieser Funktion werden Daten in Wavefront exportiert. Derzeit unterstützt ein dynamisches Plug-in nur den Export in Wavefront. Hinweis: Dieses Funktion bezieht sich nur auf eine VMware Cloud-Umgebung.Exportdata: ExportData(data={}, exports=[], source=host_uuid)
Dabei gilt Folgendes:
data: Daten, die exportiert werden sollen; die Daten müssen im Wörterbuchformat wie im Beispiel angegeben werden.
exports: Zielliste für den Export. In HL wird nur Wavefront im Ziel unterstützt. Dies ist erforderlich.
source: Quellzeichenfolge für den Export. Dies ist nur für das Wavefront-Ziel nützlich. Dies ist optional, der Standardwert ist die „host_uuid“ von NSX.
Die Funktion gibt keinen Wert zurück.
Funktion Exportdata(data={'esx.plugin.stats': {'stats': {'gc-esx-001': data}}}, exports=['wavefront'])
Beispiel einer plugin.py-Datei.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()