
Sie möchten erfahren, wie Sie einen IoT-Betrieb in der Cloud aufbauen, der vollständig verwaltet, automatisch skalierend und serverlos läuft?
In dieser dreiteiligen Reihe IoT auf GCP begleiten wir einen vollständigen IoT-Workflow: von der Geräteregistrierung über das Streaming und die langfristige Speicherung der Daten bis hin zu deren Analyse und Visualisierung.
Best Practices für IoT im Produktionsmaßstab
Nach Teil eins wissen Sie, wie Sie Millionen von IoT-Geräten sicher registrieren, die Telemetriedaten in Ihre Google-Cloud-Umgebung streamen.
Dies ist der erste Teil einer dreiteiligen Reihe:
- Wie Sie solche Datenströme mit hohem Durchsatz korrekt speichern und visualisieren, zeigen wir in Teil zwei.
- Den Aufbau eines funktionsfähigen Machine-Learning-Modells auf Basis von IoT-Daten behandeln wir in Teil drei.
Über die gesamte Reihe hinweg nutzen wir GCP als Cloud-Anbieter und Raspberry-Pi-Geräte mit angeschlossenen Temperatursensoren als Beispiel-IoT-Geräte.
Überblick
Der Beitrag gliedert sich in folgende Abschnitte:
- Software- und Hardware-Setup des Raspberry Pi
- Geräteregistrierung und Bereitstellung der Anmeldedaten in der Praxis
- Test der Geräteanbindung und Streaming der Temperaturdaten
- Einschränkungen der Google Cloud IoT-Funktionalität
- Speicherung der Streaming-Daten (Teil zwei)
- Visualisierung der Streaming-Daten (Teil zwei)
- Aufbau eines wirksamen Machine-Learning-Modells mit IoT-Daten (Teil drei)
Um diesem Artikel folgen zu können, brauchen Sie lediglich Erfahrung mit Bash und Python sowie Grundkenntnisse in der Bedienung der Google Cloud Console.
Software und Hardware des Raspberry Pi einrichten
Bringen Sie zunächst mehrere Raspberry-Pi-Geräte ans Laufen – ich verwende Pi-3-Geräte. Ich empfehle den Raspbian OS Imager, um die OS-Installation auf microSD-Karten zu automatisieren.
Python-Pakete installieren
Sobald Sie auf dem Desktop angekommen sind und Ihr Gerät aktualisiert haben, installieren Sie mit folgendem Befehl das spezifische SDK für Google Cloud IoT:
pip3 install -U pyjwt paho-mqttBevor wir weitermachen, ist es wichtig zu verstehen, warum wir paho-mqtt installieren und nicht das allgemeine Python-SDK google-api-python-client für Google Cloud. Das gängigere Python-SDK sowie die GCP-CLI gcloud setzen auf HTTP. Dieses Protokoll eignet sich, um die meisten Aktionen schnell auszuführen. HTTP ist allerdings nicht das richtige Protokoll, um Nachrichten über langlebige Verbindungen mit häufig unterbrochener Konnektivität zu senden, bei denen die Daten überwiegend vom verbundenen Gerät weg fließen.
MQTT ist ein im IoT verwendetes Protokoll – über Pakete wie paho-mqtt verfügbar – und genau dafür gemacht, dass ein Gerät trotz schwieriger Konnektivität häufig Nachrichten publizieren und seltener empfangen kann.
Digitalen Temperatursensor anschließen
Da auf Ihrem Raspberry Pi nun die nötigen Python-Pakete installiert sind, schließen Sie als Nächstes einen digitalen Temperatursensor an. Wenn Sie dem Artikel folgen möchten, empfehle ich diesen DS18B20-Sensor.
Außerdem benötigen Sie Folgendes, um den Sensor mit Ihrem Raspberry Pi zu verbinden:
- Mini-Breadboards
- Breadboard-Jumperkabel
- Sortiment-Set mit Widerständen (wir benötigen einen 4,7-kOhm-Widerstand)
Falls Sie auf die Lieferung warten müssen, können Sie ohne Weiteres im Artikel weiterlesen – ein Skript zum Streamen simulierter Temperaturen wird ebenfalls bereitgestellt.
Wenn Ihnen die Teile vorliegen, führen Sie die ersten fünf Minuten dieses Tutorials durch den Anschluss des Sensors an den Raspberry Pi und die Prüfung, ob Temperaturwerte ankommen.
Ergänzend zum Vorgehen im Tutorial empfehle ich, Folgendes in /etc/modules einzutragen, damit die onewire-Module beim Booten geladen werden und Sie nicht nach jedem Neustart modprobe ausführen müssen:
w1-gpiow1-thermIoT-Geräte registrieren
Im Folgenden sehen Sie ein vollständiges, funktionierendes Beispiel, wie Sie Ihre IoT Registry mit sicher registrierten Geräten einrichten, von denen aus wir Temperaturdaten an die Google Cloud IoT-Plattform streamen.
Eine Registry für Ihre Geräte anlegen
In der Google Cloud Console:
- Legen Sie ein neues Projekt an (z. B. "IoTTempStreaming").
- Öffnen Sie den Dienst IoT Core, um die IoT-API zu aktivieren.
- Klicken Sie auf "Create registry", um eine Registry für Ihre IoT-Geräte zu erstellen.
IoT-Geräte können Nachrichten nur dann an IoT Core in GCP senden, wenn sie als Gerät mit gültigen Anmeldedaten in der IoT Registry validiert sind. Das Anlegen der Registry ist also ein essenzieller erster Schritt.
Eine brandneue IoT Core-Umgebung wartet darauf, mit Nachrichten gefüllt zu werden
Ein Pub/Sub-Topic erstellen
Nachrichten an IoT Core – samt kritischer Metadaten wie der eindeutigen deviceId eines Geräts – werden im Hintergrund an ein "Topic" in Pub/Sub weitergeleitet, dem vollständig verwalteten, automatisch skalierenden und serverlosen Message-Queue-System von Google Cloud.
Daher legen wir Pub/Sub-Topics gleich im IoT-Registry-Dialog mit an, damit unsere Telemetriedaten am Ende für die Weiterverarbeitung in Pub/Sub eintreffen.
So legen Sie aus dem IoT-Registry-Dialog heraus ein Pub/Sub-Topic an:
- Vergeben Sie als Registry-ID "RaspberryPiDevices" in der Region us-central1.
- Erstellen Sie ein Pub/Sub-Topic namens "sensordata", in dem IoT-Telemetrienachrichten standardmäßig eintreffen.
- Erstellen Sie unter "Additional topics" ein weiteres Pub/Sub-Topic namens "temperature". Dorthin gelangen Nachrichten, die in einem ebenfalls "temperature" benannten Unterordner des IoT-Topics veröffentlicht werden.
So ist sichergestellt, dass nur die in genau diesem IoT-Unterordner veröffentlichten Temperaturnachrichten im Pub/Sub-Topic "temperature" landen, während alle anderen (unerwarteten) Telemetrieereignisse im Standard-Topic "sensordata" auflaufen.
Außerdem empfehle ich, die erweiterten Optionen aufzuklappen und ausschließlich MQTT zuzulassen, indem Sie HTTP deaktivieren:
IoT Core-Registry-Setup für das Streaming von Temperatursensordaten
Nach dem Anlegen sollte Ihre Registry so aussehen:
Ein erfolgreich eingerichtetes IoT Core-Registry-Setup
Ein registriertes Gerät anlegen
Da wir nun eine Geräte-Registry haben, legen wir ein registriertes Gerät an.
Dazu benötigen wir (1) ein Public-Private-Key-Paar, das mit dem Gerät verknüpft wird, und (2) das Google-Stammzertifikat.
Im Folgenden die Befehle, mit denen Sie auf einem Raspberry Pi Elliptic-Curve-Schlüssel erzeugen und das Google-Stammzertifikat herunterladen (basierend auf der entsprechenden Google Cloud-Dokumentation). EC-Schlüssel sind kompakter als klassische RSA-Schlüssel und helfen IoT-Geräten, auch in Gebieten mit schwacher Konnektivität einen optimalen Durchsatz zu halten:
$ mkdir -p /home/pi/GCP/iot_keys/$ cd /home/pi/GCP/iot_keys/$ wget$ openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem$ openssl ec -in ec_private.pem -pubout -out ec_public.pem$ cat ec_public.pem$ cd ../Nachdem Sie diese Befehle ausgeführt haben:
- Kopieren Sie den im Terminal angezeigten Public Key.
- Wechseln Sie in die IoT Registry und navigieren Sie zu Devices.
- Klicken Sie auf Add Device.
- Vergeben Sie einen Namen (z. B. "device1") und fügen Sie Ihren öffentlichen ES256-Schlüssel unter Authentication ein, wie unten gezeigt.
- Klicken Sie auf Create.
IoT-Geräteregistrierung mit Abfrage eines Elliptic-Curve-Schlüssels
Sobald das Gerät erstellt ist, sind die mit diesem in IoT Core registrierten Gerät verknüpften Anmeldedaten auf dem Raspberry Pi einsatzbereit.
Notieren Sie sich die Numeric ID des Geräts, die Project ID und die Registry ID.
Mit diesen Werten sowie den Schlüsseln und dem Google-Stammzertifikat auf dem Gerät erstellen wir nun eine Konfigurationsdatei namens gcp_iot_config.txt. In ihr werden Authentifizierung und IoT-Endpunkt-Details für ein bestimmtes Gerät hinterlegt. Etwas weiter unten im Artikel folgt ein Python-Skript, das mithilfe dieser Konfigurationsdatei Temperaturwerte streamt:
$ pwd/home/pi/GCP/$ cat gcp_iot_config.txt[SETTINGS]KEY_PATH = /home/pi/GCP/iot_keys/PRIVATE_KEY = ec_private.pemGOOGLE_ROOT_CERT = roots.pemREGISTRY_ID = <REGISTRY_ID>DEVICE_ID = <DEVICE_NUMERIC_ID>REGION = us-central1PROJECT_ID = <PROJECT_ID>Et voilà! Ihr Gerät ist jetzt bereit, Telemetriedaten sicher über die IoT Core-Authentifizierungsplattform von GCP an ein Pub/Sub-Topic zu streamen. Wiederholen Sie das Verfahren, um für jedes weitere Gerät eindeutige Anmeldedaten zu erzeugen und es zu registrieren.
Geräteanbindung testen
Testen wir die Geräteanbindung mit dem folgenden Skript namens "publish_temps.py". Es streamt – je nachdem, ob Sie Zeile 107 oder 108 auskommentiert haben – reale oder simulierte Temperaturwerte.
(Das Skript ist eine Anpassung zweier Beispielskripte von Google Cloud: #1 und #2.)
$ pwd/home/pi/GCP/$ ./publish_temps.pyhttps://gist.github.com/doit-mattporter/7e548158a5dc03b3674282cda19ef663
Hier passiert einiges – ich empfehle dringend, den Code durchzugehen, um nachzuvollziehen, wie er die Verbindung sicher aufbaut und Daten streamt.
Beim Ausführen des Skripts sollten Sie eine Ausgabe ähnlich der folgenden sehen:
Reale Temperaturwerte, die per MQTT an GCP IoT Core gestreamt werden
Wenn Sie das Skript per crontab beim Reboot starten lassen (mit vorgeschalteten 30 Sekunden Sleep, damit die onewire-Module beim Booten geladen werden können), nimmt Ihr IoT-Gerät das Streaming auch nach einem (un)erwarteten Neustart automatisch wieder auf:
$ crontab -e@reboot sleep 30 && /home/pi/GCP/publish_temps.py -c /home/pi/GCP/gcp_iot_config.txt >> /home/pi/GCP/publish_temps.log 2>&1Wiederholen Sie Onboarding und Streaming für alle Raspberry-Pi-Geräte, die Sie bei sich zu Hause platzieren. Sie sind auf dem besten Weg, mit IoT-Daten im großen Maßstab zu arbeiten!
Datenfluss überprüfen
Verifizieren wir kurz, dass die Nachrichten in Google Cloud ankommen, indem wir die Telemetriedaten in Pub/Sub einsehen.
- Legen Sie eine Pub/Sub-Subscription auf das Topic "temperature" an.
- Wechseln Sie zur Subscription.
- Klicken Sie auf View Messages und wählen Sie den Radiobutton Pull.
Sie sollten die Nachrichten in dem Moment sehen, in dem sie eintreffen – inklusive Temperatur- und Zeitstempelinformationen im Nachrichtenkörper sowie der Attribut-Metadaten, die eindeutig kennzeichnen, von welchem Gerät die Werte stammen. Diese Attribut-Metadaten sind nicht nur für Analytics und Endnutzer-Dashboards wertvoll, sondern auch, um missbräuchlich genutzte oder kompromittierte Geräte zu identifizieren und zu sperren.
Anlegen einer Pub/Sub-Subscription zum Einsehen eingehender Temperatur-Telemetrienachrichten
Die folgende Abbildung zeigt, wie eine Subscription auf das Topic "temperature" aussieht:
Nachrichten einer Pub/Sub-Subscription auf das Pub/Sub-Topic "temperature" einsehen
Sobald Sie auf "PULL" klicken, sollten die Nachrichten samt Attributen erscheinen:
Temperaturdaten erreichen ein Pub/Sub-Topic und treffen in einer Pub/Sub-Subscription ein: Nachrichtenkörper
Temperaturdaten erreichen ein Pub/Sub-Topic und treffen in einer Pub/Sub-Subscription ein: eindeutig identifizierende Attribute
Wenn Sie es bis hierher geschafft haben: Glückwunsch (im Ernst)! So spannend es ist, echte IoT-Daten in Pub/Sub einlaufen zu sehen – wir haben gerade erst an der Oberfläche gekratzt.
Damit diese Daten wirklich nutzbar werden, müssen wir sie bei Bedarf transformieren, in ein Data Warehouse verschieben bzw. per Batch laden und analysieren. Das geschieht in einem Ökosystem aus GCP-Diensten, die diesen Datenfluss zuverlässig, skalierbar und kosteneffizient ermöglichen – in jeder Entwicklungsphase, vom ersten Test über den Petabyte-Produktivbetrieb bis darüber hinaus, und das alles mit minimalem bis keinem Infrastrukturaufwand. Wie das funktioniert, erfahren Sie in Teil zwei und drei – bleiben Sie dran!
Als Nächstes: Speicherung und Visualisierung
Bleiben Sie dran für Teil zwei: Dort stelle ich die passenden ETL-, Speicher- und Visualisierungsdienste vor, mit denen sich umfangreiche IoT-Streamingdaten relativ einfach in konkreten Anwendungsfällen nutzen lassen.
Einschränkungen der Google Cloud IoT-Funktionalität
Bessere Handhabung der deviceId in vollständig verwalteten GCP-Diensten
Vielleicht ist Ihnen aufgefallen, dass das Python-Skript ein device_id-Schlüssel-Wert-Paar im Nachrichtenkörper mitsendet, das im Grunde das deviceId-Attribut der Pub/Sub-Nachricht dupliziert. Dieses Attribut ordnet IoT Core der Nachricht über die Verknüpfung mit dem eindeutigen Schlüssel-Wert-Paar des sendenden Geräts ohnehin zu.
Warum sollte das Skript also eine device_id mitsenden, die auf einem kompromittierten Gerät leicht gefälscht werden könnte und das Data Warehouse beim Verschieben der Nachrichten in die Langzeitspeicherung mit verfälschten Daten verseuchen würde?
Ich greife etwas vor: Wie wir in Teil zwei sehen werden, gibt es einen praktischen, vollständig verwalteten, automatisch skalierenden und größtenteils serverlosen Workflow, der Pub/Sub-Nachrichten mithilfe von Dataflow – der vollständig verwalteten Apache-Beam-Variante von Google Cloud – transformiert und in BigQuery verschiebt.
Leider bietet die in Dataflow mitgelieferte GCP-Standardvorlage "Pub/Sub-to-BigQuery" keine Möglichkeit, Nachrichtenattribute nach BigQuery zu übernehmen – nur der Inhalt des Nachrichtenkörpers wird übertragen. Mehrere GCP-Engineers haben mir bestätigt, dass sich für die Standardvorlagen keine eigene Dataflow-JavaScript-UDF schreiben lässt, um Nachrichtenattribute in Dataflow-Sinks wie BigQuery zu übernehmen. Alternativ Java-Dataflow-Jobs zu schreiben – sei es von Grund auf oder als Anpassung bestehender GCP-Vorlagen – ist ein zeitintensives Unterfangen mit fortlaufendem Wartungs- und Update-Aufwand, das die meisten GCP-Kunden meiner Einschätzung nach nicht angehen wollen.
Standardmäßig gibt es daher keinen einfachen und sicheren Weg, eine in Pub/Sub eintreffende und an Ziel-Daten-Sinks weitergeleitete IoT-Nachricht mit ihrer deviceId zu verknüpfen.
Ich habe GCP auf dieses Versäumnis hingewiesen. Seitdem wurde ein öffentlicher Feature Request eröffnet, der sicherstellen soll, dass die Standardvorlagen die Weitergabe dieser wertvollen – und für den IoT-Anwendungsfall unverzichtbaren – Werte unterstützen. Sobald der FR umgesetzt ist, aktualisiere ich den Artikel entsprechend. Bis dahin ist es zu Demonstrationszwecken deutlich einfacher, die Nutzung der device_id über den Nachrichtenkörper zu testen, als eine Dataflow-Vorlage neu zu schreiben, die eigentlich von Haus aus vorhanden sein sollte.
Wie würde ich gerätespezifische Anmeldedaten idealerweise bereitstellen?
Die Registrierung eines einzelnen IoT-Geräts wird üblicherweise so beschrieben:
- Ein Public-Private-Key-Paar erstellen und in GCP mit IoT-Berechtigungen verknüpfen.
- Diese Dateien im Werk auf dem Gerät bereitstellen und ablegen.
- Die Anmeldedaten vom Werk aus in der IoT Registry registrieren lassen.
- Das Schlüsselpaar für IoT-API-Aufrufe freigeben, die Daten in die Cloud streamen.
Ein solches Setup allein ist allerdings nicht ideal, denn reale IoT-Anwendungsfälle umfassen Millionen von Geräten, die in eine Cloud-Umgebung streamen. Jedes Gerät einer solchen Flotte muss einen eigenen Satz an Anmeldedaten erhalten, damit bei Kompromittierung eines Geräts oder seiner Google-Cloud-Anmeldedaten und missbräuchlicher Nutzung genau dieser eine Satz deaktiviert werden kann, ohne die übrigen Geräte zu beeinträchtigen.
GCP bringt diese Funktionalität mit und unterstützt – wie das obige Skript zeigt – auch die Beschränkung, dass ein Gerät nur in einem für dieses Gerät eindeutigen Topic publizieren darf. Angesichts der verfügbaren Methoden zur Bereitstellung von Anmeldedaten ist es jedoch eine Herausforderung, Schlüsselerstellung, Deployment und Registrierung für Millionen von Geräten zu koordinieren.
Wie lässt sich das Erstellen gerätespezifischer Anmeldedaten so einfach wie möglich gestalten? Geht das, ohne Millionen Zertifikate vorab zu erzeugen und ihre eindeutige Zuordnung während der Fertigung zu koordinieren? Wollen Sie sich darauf verlassen, dass ein Hersteller diese Dateien zuverlässig und ohne Duplikate auf die Geräte aufspielt?
Oder lässt sich Geräteregistrierung samt Anmeldedaten-Vergabe abwickeln, ohne dass der Hersteller API-Aufrufe an Ihre IoT Registry absetzen muss, um direkt am Band neue Anmeldedaten on demand zu erzeugen, sobald ein Gerät mit Software und Anmeldedaten bestückt wird? Was passiert mit der Produktionslinie, wenn die Verbindung zu Ihrem API Gateway, das die IoT-Registrierung antreibt, ausfällt?
Diese Wege würde ich lieber vermeiden – sie sind komplexer, fehleranfälliger und belasten den Hersteller unnötig.
Ein sicheres und sinnvoll skalierbares Geräteregistrierungssystem, wie ich es mir von GCP wünschen würde, würde diesen Leitlinien folgen:
- Es wird ein einziges IoT-Zertifikat erstellt, das auf alle IoT-Geräte ausgerollt wird. Dieses sogenannte Bootstrap-Zertifikat ist an eine Berechtigungsrichtlinie gekoppelt, die einem Gerät nur erlaubt, eine Anfrage zu stellen, um (a) bei Genehmigung gerätespezifische Anmeldedaten zu erstellen und abzurufen und (b) sich selbst zur IoT Registry hinzuzufügen.
- Die GCP IoT Core-Plattform erstellt nach Erhalt und Genehmigung der Anfrage ein neues Schlüsselpaar. Die zugehörigen IoT-Berechtigungen sollten – wie es Google Cloud heute schon handhabt – einem Gerät nur erlauben, Nachrichten in einem für das Gerät eindeutigen Topic zu publizieren.
- Das Erstellen gerätespezifischer Anmeldedaten sollte an einen Validierungsschritt gekoppelt sein. Dafür schreiben Sie eine Cloud Function, die bestimmte eindeutige Identifier in der Anfrage verlangt, sodass diese gegen eine Whitelist (z. B. produzierte Seriennummern oder verwendete MAC-Adressen) und/oder eine Blacklist (z. B. Seriennummern kompromittierter, missbräuchlich genutzter oder bereits registrierter Geräte) abgeglichen werden.
- Wird die Anfrage im Validierungsschritt genehmigt, wird das Gerät in die IoT Registry aufgenommen und die neuen Anmeldedateien werden zur Nutzung im Daten-Streaming an das Gerät ausgeliefert.
Mit diesem Workflow müsste ein IoT-Gerätehersteller jedem Gerät lediglich das Bootstrap-Zertifikat mitgeben. Das gerätespezifische Schlüsselpaar für das Daten-Streaming kann auf Wunsch direkt im Werk erzeugt und bezogen werden – oder erst später, wenn das Gerät beim Endnutzer angekommen ist.
Unabhängig vom Zeitpunkt würde der Hersteller einfach eine von Ihnen bereitgestellte Software auf das Gerät spielen, die den auf dem Bootstrap-Zertifikat basierenden Prozess zur Erstellung des gerätespezifischen Schlüsselpaars dann ausführt, wenn:
- das Gerät hochfährt,
- eine Internetverbindung verfügbar ist und
- kein gerätespezifisches Schlüsselpaar vorhanden ist.
Leider fehlt diese Funktionalität (vorerst). Doch jenseits der Massenregistrierung von Geräten ergibt das Google Cloud IoT-Angebot – kombiniert mit den nachgelagerten, vollständig verwalteten Diensten zur Nachrichtenverarbeitung (Teil zwei) – insgesamt eine starke, sichere und einfach skalierbare cloud-native Lösung im IoT-Bereich.