Im vorherigen Teil des Tutorials wurden die Grundlagen von KubeEdge und dessen Aufbau erläutert. In diesem Teil wollen wird KubeEdge beispielhaft mit einer kleinen Applikation aufbauen und testen. Den ersten Teil der Reihe Einführung in KubeEdge findet ihr hier.

Anwendungsfall

Grafana Abbildung über Anwendungsfall

Als einfacher Anwendungsfall werden Daten von einem Sensor über das MQTT-Protokoll an einen Edge-Knoten gesendet. Der Edge-Knoten sendet diese Daten an einen zentralen Kubernetes Cluster. Die Verarbeitung der gesendeten Daten übernimmt ein kleines Programm, das die Daten in einer Datenbank persistiert. Für die Visualisierung der persistenten Daten wird Grafana verwendet.

Aus diesem Anwendungsfalls lassen sich drei Teilziele ableiten:

  1. Der Aufbau eines Kubernetes Clusters mit KubeEdge Cloud
  2. Der Aufbau eines Edge-Knoten mit KubeEdge
  3. Generierung und Visualisierung der Werte

Für die einfach Umsetzung unseres Anwendungsfalls wird auf spezialisierte Hardware verzichtet.

Umsetzung

Übersicht

Während der Installation von KubeEdge werden zwei Komponenten von KubeEdge installiert. Der CloudCore, der in einem zentralen Managed Kubernetes Cluster installiert wird, und der EdgeCore, der als eigenständiger Prozess auf einem Edge Node gestartet wird. Die Testumgebung wird mit Vagrant erstellt und 2 virtuelle Maschinen (VM) mit Ubuntu 18.04 werden installiert. Diese VMs können durch echte Maschinen (e.g. Raspberry Pi 3+) ersetzt werden. Der komplette Aufbau kann kompakt in diesem GitHub Repository nachgelesen werden.

CloudCore

Für das initiale Setup des CloudCore wird ein Kubernetes Cluster mit dem Tool kubeadm erstellt. Bevor kubeadm und das Kubernetes Cluster installiert werden können, muss eine Container Runtime installiert werden. In diesem Tutorial wird containerd als Container Runtime verdendet. Die Installation von containerd ist relativ einfach. Zuvor müssen einige Voraussetzungen auf dem System erfüllt werden, siehe Block „containerd Voraussetzungen“.

Nun kann containerd auf dem System installiert werden. Für die Installation wird das aktuelle Release Package in der Version 1.3.1  auf die VM geladen. Das Release Package muss mit erhöhten Privilegien entpackt werden, da unter anderem eine systemd Unit erstellt wird. Nach dem Entpacken kann containerd einfach mit systemd gestartet und aktiviert werden.

Im nächsten Schritt wird mit kubeadm ein Kubernetes Cluster auf der VM erstellt. Für die Installation von kubeadm können die offiziellen APT Pakete von Kubernetes verwendet werden. Das Einbinden des APT Repositories sowie die Installation von kubeadm sind im Block „kubeadm-Installation“ beschrieben.

Mit dem Befehl “sudo kubeadm init –kubernetes-version=1.16.3 –skip-token-print” wird nun ein Kubernetes Cluster in der version 1.16.3 erstellt. Danach muss noch die kubeconfig für den aktuellen Benutzer kopiert werden. Diese Schritte werden in der Ausgabe von kubeadm beschrieben. In diesem minimalen Setup muss noch das Taint des Masters entfernt werden. Dieses Taint wird von kubeadm gesetzt und verhindert, dass Pods auf dem Master Node gescheduled werden. Das Taint kann mit dem Befehl „kubectl taint nodes –all node-role.kubernetes.io/master-“ entfernt werden. Über den Befehl „kubectl apply -f manifests/calico.yaml“ wird das Pod-Netzwerk, in diesem Falle Calico, installiert.

Der CloudCore von KubeEdge kann auf verschiedene Weisen installiert werden. In diesem Beispiel wird die Variante als Kubernetes Deployment verwendet. Dies hat den Vorteil, dass keine weitere Infrastruktur bereitgestellt werden muss und die Funktionalität für Restarts und Prozessüberwachung von Kubernetes verwendet werden kann. Die Installation des CloudCores in ein Kubernetes Cluster kann in die folgenden Schritte unterteilt werden:

  1. Installation der CustomResourceDefinition für Kubeedge (Device und DeviceModel)
  2. Erstellung einer Root CA für CloudCore und den EdgeCore
  3. Erstellung eines Zertifikates für den EdgeCore
  4. Speichern des Zertifikats in Kubernetes als Secret
  5. Starten des CloudCore in Kubernetes mit den entsprechenden Manifesten

Die komplette Installation wird im Block „CloudCore Installation“ beschrieben. Alle verwendeten Manifeste können dem GitHub Repository entnommen werden.

Damit sich der EdgeCore im nächsten Schritt auch als Kubernetes Node anmelden kann, muss ein Kubernetes Node per API erstellt werden. Bei der Erstellung ist darauf zu achten, dass der Name des Kubernetes Nodes mit dem Namen von EdgeCore übereinstimmen muss. Der Anmeldenamen des EdgeCore-Prozesses kann über eine Konfigurationseinstellung angepasst werden. Abschließend muss das Zertifikat und die Root CA für den EdgeCore-Prozess zugänglich sein. Hierfür werden die Dateien aus der Kubernetes API ausgelesen und in ein gemeinsames Verzeichnis verschoben. Der Block „Vorbereitungen für EdgeCore“ beschreibt diese Schritte.

EdgeCore

Der EdgeCore benötigt eine Container Runtime wie z.B. Docker oder containerd, um Pods lokal starten zu können. Die KubeEdge Binaries können aus den offiziellen Quellen (GitHub) heruntergeladen werden. Über eine Konfigurationsdatei wird der KubeEdge Daemon konfiguriert. Abschließend wird ein Systemd-Service verwendet um KubeEdge als Systemdienst und bei jedem Reboot automatisiert zu starten Als Container Runtime wird für den EdgeCore Docker verwendet. Die Installation von Docker kann von den offiziellen Quellen aus Docker übernommen werden.

Ähnlich wie beim CloudCore kann der EdgeCore in unterschiedlichen Varianten installiert werden. In diesem Beispiel wird die vorkompilierte Binary verwendet, die hier heruntergeladen werden kann.

Bei der Installation des EdgeCores ist darauf zu achten, die richtige CPU-Architektur zu verwenden. Die aktuelle CPU-Architektur kann über den Befehl “uname -m“ auf einem Linux OS ausgelesen werden.

Es wird empfohlen, die Konfiguration unter dem Verzeichnis “/etc/kubeedge” anzulegen. Mit dem Nachfolgenden Befehl wird ein entsprechendes Verzeichnis angelegt und die benötigten Inhalte des heruntergeladene TAR-Verzeichnis werden verschoben.

Für die Prozessverwaltung des EdgeCores wird systemd verwendet. systemd startet den EdgeCore-Prozess bei Fehlern neu und startet zusätzlich den Prozess bei jedem Neustart. Vor der Verwendung von systemd sollte der EdgeCore einmal händisch über das Terminal gestartet werden, um eine Fehlkonfiguration frühzeitig zu entdecken. Der Block „Erstellung edgecore.service“ zeigt, wie die systemd Service Unit erstellt werden kann. Wie aus dem Service File ersichtlich, muss der EdgeCore mit Superuser-Rechten ausgeführt werden.

Erstellung Zertifikate

Bei der Installation des CloudCores wurde bereits ein Zertifikat für den EdgeCore erstellt. Auf dem EdgeCore wird bei der Verwendung der Websocket-Verbindung ein Private Key und ein Client-Zertifikat benötigt. Wichtig ist hierbei, dass alle Zertifikate mithilfe derselben Root-CA erstellt wurden. Um in die Zertifikatserstellung möglichst einfach zu halten wird in diesem Beispiel auf die bereits generierten Zertifikate zurückgegriffen. Diese werden auf dem EdgeCore unter dem Pfad „/etc/kubeedge/certs“ abgelegt. Bei unterschiedlichen Geräten kann das Tool “scp” verwendet werden. Die Befehlsfolge ist folgende:

Konfiguration Edge

Bevor die Edge-Komponente gestartet werden kann, muss diese noch konfiguriert werden. Die Grundlegende Konfiguration ist in der Beispielkonfiguration von KubeEdge schon vorgenommen worden. Die Beispielkonfiguration muss aber noch angepasst werden, damit sich der EdgeCore als Node im Kubernetes Cluster melden kann.

Der Ordner für die Konfigurationsdateien ist unter /etc/kubeedge/conf zu finden. In diesem Ordner liegen die Dateien “edge.yaml”, “logging.yaml” und “modules.yaml”:

  • Über die Datei “modules.yaml” können die in EdgeCore verwendeten Module verwaltet werden.
  • In der Datei “logging.yaml” kann das Logging des Edgecores konfiguriert werden.
  • In der Datei “edge.yaml” wird der EdgeCore konfiguriert. Diese Konfiguration muss für jede Instanz des EdgeCores verändert werden. Die Datei selbst ist in die Abschnitte MQTT, Edgehub, Edged und Mesh aufgeteilt.

In der Sektion MQTT wird die MQTT-Verbindung konfiguriert. Dabei ist es möglich, den EdgeCore-eigenen MQTT Broker oder einen externen Broker wie Eclipse Mosquitto zu verwenden. In diesem Beispiel wird die Standardeinstellung, der internen MQTT Broker, verwendet.

In der Sektion Edgehub wird die Verbindung zur CloudCore-Komponente definiert. Hier kann das verwendete Protokoll zur Kommunikation zwischen EdgeCore und CloudCore ausgewählt werden. Zu Verfügung stehen die Protokolle Websocket und Quic. Tests haben gezeigt, dass Websocket eine höhere Performance bietet. Im Controller ist aus diesem Grund das Protokoll Websocket als Default Wert vorkonfiguriert. Bevor die Verbindung konfiguriert wird, sollte die Node-ID gesetzt werden. Die Node-ID ist ein String, welcher beliebig gewählt werden kann. Es empfiehlt sich aber hier einen String zu verwenden, mit dem der Edge Node identifiziert werden kann. Wenn die Node ID geändert wurde, sollte in der Websocket URL der vorletzte Teilstring ebenfalls abgeändert werden. In diesem Tutorial wurde bereits beim Hinzufügen des Nodes ein Name gesetzt. Dieser lautet „edgenode“.   Zusätzlich muss in der URL im Bereich Websocket noch die IP-Adresse 0.0.0.0 durch die tatsächliche IP-Adresse des CloudCores ersetzt werden. Beim aufsetzen des CloudCores wurde ein Service mit dem Typ NodePort erstellt. Die richtige URL für die Websocket-Verbindung setzt sich dementsprechend aus der IP-Adresse des Nodes und dem Port in diesem Service zusammen, in unserem Fall ist dies der Port 30000.

Im Abschnitt edged ist die Konfiguration für die Kubelet-Funktionalität auf den EdgeCore zu finden. Bei einer Anpassung der Node-ID muss ebenfalls die Option hostname-override entsprechend gesetzt werden. Mithilfe des Befehles ip address list kann der Name des aktuell verwendeten Netzwerk-Interfaces herausgefunden werden und mit der Option “interface-name” entsprechend gesetzt werden. Wird eine andere CPU-Architektur als x86 verwendet muss noch die Option „podsandbox-image“ entsprechend angepasst werden. Die entsprechenden images für die konkreten CPU-Architekturen sind als Kommentar in der Konfigurationsdatei enthalten.

Im Bereich Mesh kann die Strategie für einen Loadbalancer definiert werden, der in diesem Tutorial allerdings nicht verwendet wird.

Der EdgeCore kann nun mithilfe der Kommandozeile und der Binary edgecore oder über den Service mit “systemctl start edgecore” gestartet werden.

Node hinzufügen

Nachdem die EdgeCore-Komponente nun ausgeführt wird, soll der Node im Cluster hinzugefügt werden. Dies wurde in diesem Tutorial schon im Block „Vorbereitungen für EdgeCore“ vorgenommen. Der Block Node.yaml beschreibt den Inhalt dieser Datei. Das Feld “name” muss mit der EdgeCore Node-ID übereinstimmen, damit Kubernetes und der CloudCore den EdgeCore identifizieren können.

Um sicherzugehen, dass der EdgeCore nur Workload für Edge-Anwendungsfälle erhält, wird ein entsprechendes Taint verwendet. Die Anwendungen, die entsprechend auf einem EdgeNode ausgeführt werden sollen, müssen diesen Taint tolerieren. Ein Beispiel hierzu ist im nächsten Kapitel zu finden.

Um zu kontrollieren, dass der Node auch hinzugefügt wurde und verfügbar ist, kann der Befehl kubectl get node -o wide verwendet werden.

Demo-Applikation starten

Zum Abschluss dieses Teiles soll auf dem EdgeNode eine einfache Web-Applikation ausgeführt werden. Ein Nginx Pod soll auf dem EdgeNode gestartet werden und über einen Browser oder ein Terminal die Willkommensseite von NGINX aufrufen. Das Kubernetes-Manifest für das Nginx Deployment is in dem Block „NGINX Deployment“ beschrieben.

Dieses Manifest ist bereits in der Datei “manifest/demo/nginx.yaml” verfügbar und kann mit dem Befehl “kubectl apply -f manifest/demo/nginx.yaml” auf dem Cluster erstellt werden.

Ausblick auf Abschließenden Teil

Im letzten Teil des Tutorials wird eine Anwendung auf dem EdgeNode deployt werden. Diese wird die CPU-Temperatur messen und über den EdgeCore und den CloudCore die Werte in der Kubernetes API aktualisieren. Aus der Kubernetes API werden die Daten ausgelesen und in eine Timeseries-Datenbank geschrieben. Die gespeicherten Daten werden über ein Grafana Dashboard ausgelesen und visualisiert.

Die Inhalte dieser Arbeit stammen aus dem Projekt KOSMoS – Kollaborative Smart Contracting Plattform für digitale Wertschöpfungsnetze. Dieses Forschungs- und Entwicklungsprojekt wird mit Mitteln des Bundesministeriums für Bildung und Forschung (BMBF) im Programm „Innovationen für die Produktion, Dienstleistung und Arbeit von morgen“ (Förderkennzeichen 02P17D026) gefördert und vom Projektträger Karlsruhe (PTKA) betreut. Die Verantwortung für den Inhalt dieser Veröffentlichung liegt bei den Autor:innen.