Rationalisierung der Embedded Linux Entwicklung mit Yocto Project & Docker-Containern

/ 12.12.2023 Containern

Das rasante Wachstum der IoT-Geräte ist heute für niemanden mehr eine Überraschung, aber woran man auch denken sollte: Damit wächst auch der Bedarf an effizienter und zuverlässiger Software. Um diese herzustellen, ist ein rationalisierter Entwicklungsprozess unerlässlich, damit  sie schnell und mit hoher Qualität auf den Markt zu bringen. Wie macht man das am besten? Die Antwort ist die Kombination von Yocto Project mit Docker-Containern.  

Linux ist aufgrund seiner hohen Zuverlässigkeit und der freien Verfügbarkeit des Quellcode eine beliebte Wahl für eingebettete Systeme. Die Entwicklung eines solchen Systems erweist sich jedoch aufgrund der begrenzten Ressourcen, des Optimierungsbedarfs und der schwierigen Einstiegshürde als echte Herausforderung. 

Erfahrene Entwickler, die im Bereich der Entwicklung eingebetteter Systeme tätig sind, müssen nicht nur ein umfassendes Verständnis des Linux-Kernels, der Gerätetreiber und der Low-Level-Programmierung haben, sondern auch über Kenntnisse der Hardware-Architektur und der Echtzeitbetriebssysteme verfügen. Dieses umfassende Wissen ermöglicht es ihnen, die Herausforderungen bei der Entwicklung von Software für ressourcenbeschränkte Geräte zu meistern.  

Warum ist die Softwareentwicklung für eingebettete Systeme eine Herausforderung? 

Einer der wichtigsten Aspekte bei der Rationalisierung von Entwicklungsprozessen ist die effiziente Nutzung der verfügbaren Ressourcen. Da eingebettete Systeme oft nur über eine begrenzte Speicherverarbeitungsleistung verfügen, müssen die Entwickler Speicher, CPU-Nutzung und Stromverbrauch sorgfältig verwalten. Dazu gehört die Optimierung des Codes, die Verwendung effizienter Algorithmen und Hardware-Beschleunigungstechniken. Durch die Rationalisierung dieser Prozesse können Entwickler die Leistung ihrer Software erheblich steigern und gleichzeitig den Ressourcenverbrauch minimieren.  

Ein weiterer wichtiger Aspekt bei der Rationalisierung von Entwicklerprozessen ist der angemessene Einsatz von Versionskontrollsystemen und Tools für die Zusammenarbeit. Mit diesen Tools können Entwickler nahtlos zusammenarbeiten, Änderungen verfolgen und Konflikte effektiv lösen. Durch die Beachtung von Best Practices für Versionskontrolle und Zusammenarbeit können Entwicklungsteams eine nahtlose Koordination sicherstellen und das Risiko von Fehlern oder Codekonflikten minimieren. 

In diesem Artikel erfahren Sie mehr über Yocto Project, die Containerisierung mit Docker, welche Vorteile ihre Kombination mit sich bringt, und durch welche Best Practices sich eine Yocto-Build-Umgebung mit Docker optimieren lässt. 

Was ist das Yocto-Projekt? 

Laut Definition ist das Yocto-Projekt ein Open-Source-Gemeinschaftsprojekt, das Vorlagen, Werkzeuge und Methoden zur Erstellung benutzerdefinierter Linux-Distributionen für eingebettete Systeme wie IoT-Geräte, Smartphones, Tablets, Touchscreen-basierte Geräte usw. bereitstellt, unabhängig von der Hardwarearchitektur. Sie können eine Distribution für Ihren Raspberry Pi und sogar für einen Arduino UNO erstellen.  

Eine kürzlich von der Eclipse Foundation durchgeführte Umfrage zeigt, dass Yocto von 71% der Befragten genutzt wird, um eigene Distributionen für eingebettete Systeme zu erstellen. 

Dank des Yocto-Projekts haben Entwickler Zugang zu Rezepten, die es ihnen wiederum ermöglichen, Software schnell und einfach in der von ihnen erstellten Distribution zu installieren. Darüber hinaus ist das Schreiben von Rezepten so trivial, dass das Hinzufügen neuer Software mühelos möglich ist, so dass sie dedizierte Linux-Distributionen erstellen können, die für die Zielhardware optimiert sind. Egal ob es sich um ein kleines IoT-Gerät oder ein komplexes industrielles Steuerungssystem handelt, das Design von Yocto bietet die Flexibilität und Skalierbarkeit, die erforderlich ist, um die einzigartigen Anforderungen jedes eingebetteten Systems zu erfüllen. 

Vorteile der Verwendung von Yocto in eingebetteten Linux-Systemen 

Yocto vereinfacht den Prozess der Erstellung und Pflege von Linux-Distributionen, die speziell für eingebettete Systeme zugeschnitten sind.  

Zu den wichtigsten Vorteilen von Yocto gehören mehrere Faktoren, darunter: 

Yocto ermöglicht es Entwicklern, eine standardisierte und wiederholbare Kompilierungsumgebung zu erstellen, die konsistente Ergebnisse auf verschiedenen Hardware-Plattformen gewährleistet. 

1. Yocto verwendet das OpenEmbedded-Framework als Cross-Compilation-System. 

Es basiert auf BitBake, das wie ein Paketmanager funktioniert, d.h. es liest Rezepte und kümmert sich um die Paketinstallation. Es ermöglicht den Entwicklern, die für ihre eingebettete Linux-Distribution erforderlichen Softwarekomponenten und Konfigurationen zu definieren. Außerdem lädt es automatisch den erforderlichen Quellcode herunter, wendet Patches an und kompiliert die Software, so dass ein vollständiges Linux-Image entsteht, das auf der Zielhardware eingesetzt werden kann. Dies ist besonders im Bereich der eingebetteten Systeme wichtig, wo die Hardwarekonfigurationen stark variieren können. 

2. Yocto bietet eine Architektur auf Basis von Schichten (Metaschichten), die eine einfache Anpassung und Integration von Softwarekomponenten ermöglicht.  

Die Entwickler können Schichten hinzufügen oder entfernen, um bestimmte Funktionen zu aktivieren oder zu deaktivieren, so dass die Linux-Distribution leicht an die Anforderungen des Zielsystems angepasst werden kann. Diese Flexibilität gewährleistet, dass das resultierende System optimiert ist. 

3. Es bietet eine breite Palette an vorgefertigten Rezepten, die den Zeit- und Arbeitsaufwand für die Softwareintegration erheblich reduzieren.  

Die Rezepte für Paketinstallationen werden von der YP-Projektgemeinschaft gepflegt und decken viele Softwarekomponenten ab, die in eingebetteten Systemen häufig verwendet werden. Zu diesen Tools gehören ein Paketmanager für die Verwaltung von Softwarekomponenten, ein Software Development Kit (SDK) für die Cross-Kompilierung von Anwendungen und eine Laufzeitumgebung zum Testen und Debuggen des Systems. Entwickler können diese Ressourcen nutzen, um ihrer Linux-Distribution schnell Funktionen hinzuzufügen und so wertvolle Entwicklungszeit zu sparen. 

Was sind Docker-Container? 

Bei der Containerisierung handelt es sich um eine Technik, die es Entwicklern ermöglicht, eine Anwendung und ihre Abhängigkeiten in einen einzigen Container zu packen und so sicherzustellen, dass die Anwendung in jeder Umgebung, in der sie eingesetzt wird, auf die gleiche Weise funktioniert. Die Docker-Technologie ist insofern einzigartig, als sie sich auf die Anforderungen von Entwicklern und Systembetreibern konzentriert, um die Abhängigkeiten der Anwendung von der Infrastruktur zu trennen. Dies ermöglicht eine konsistente und vorhersehbare Bereitstellung auf allen Plattformen und in allen Umgebungen, wodurch das Risiko von Fehlern und Ausfallzeiten verringert wird. 

Docker-Container bieten mehrere Vorteile für die Softwareentwicklung: 

1.  Sorgen für eine konsistente und wiederholbare Umgebung 

Mit Docker-Containern entfällt das Problem, dass es nur auf meiner Hardware funktioniert. Entwickler können ein Container-Image erstellen, das die gesamte Entwicklungsumgebung enthält, einschließlich Bibliotheken, Tools und Abhängigkeiten. Dieses Image kann mit anderen Teammitgliedern geteilt werden, um während des gesamten Entwicklungszyklus die Konsistenz sicherzustellen.  

2. Erleichtern die Zusammenarbeit zwischen den Teammitgliedern 

Entwickler können Container-Images über die Container-Registry freigeben, so dass andere die Entwicklungsumgebung schnell replizieren können. Dies fördert eine DevOps-Kultur, in der Entwicklung, Tests und Bereitstellung nahtlos erfolgen. 

Vorteile der Verwendung von Docker für Yocto-Builds – warum funktioniert diese Kombination so gut? 

Es gibt viel Vorteile der Verwendung von Docker für Yocto-Builds und der Erstellung eigener Distributionen. Entwickler können die Reproduzierbarkeit auf verschiedenen Maschinen und Betriebssystemen sicherstellen, indem sie die Kompilierungsumgebung in einem Docker-Container kapseln. Dadurch entfällt die Notwendigkeit, die Kompilierungsumgebung manuell zu konfigurieren, und das Risiko von Inkonsistenzen und Fehlern wird verringert.  

Eine Yocto-Build-Umgebung mit Docker optimieren – Warum werden sodie Probleme des traditionellen Ansatzes vermieden? 

Anstelle eines Installationsdokuments können wir das Docker-Image an unsere Kollegen weitergeben. Indem wir das Root-Dateisystem, das so genannte rotfs (root file system), aufbauen, starten wir den Docker-Container (docker-composer), und darin führen wir nur bitbake aus. Der Docker-Container garantiert, dass die Kompilierung unserer Distribution mit YP von jedem in genau der gleichen Ausführungsumgebung ausgeführt wird. YP verfügt über Reproduzierbarkeitstests, die darauf ausgelegt sind, vollständig reproduzierbare Versionen zu erstellen. Das heißt, wenn Sie heute eine Kompilierung durchführen und dann dieselbe Konfiguration X-mal in der Zukunft ausführen, sollten die Binärdateien, die Sie von der Kompilierung erhalten, binär identisch sein. Indem man nach jeder Änderung dieser Tests die Reproduzierbarkeit aufrecht erhält, wird man, egal welche Patches man dem BitBake-Code, der OpenEmbedded-Schicht oder anderen kleineren Schichten wie Meta-Python hinzufügt, jedes Mal das gleiche Kompilierungsergebnis erhalten. 

Dank der Verwendung von YP wird sich die Situation auch in einigen Jahren nicht ändern. Auch wenn wir neuere Versionen von Linux auf unseren Computern haben oder wenn die Kompilierungsexperten das Team verlassen haben, werden wir in der Lage sein, genau das gleiche Linux-Image wiederherzustellen, das wir drei oder fünf Jahre zuvor erstellt haben. 

Dies ist möglich, weil Docker es Ihnen erlaubt, zu einem zuvor eingefrorenen Code zurückzukehren. Wenn Sie feststellen, dass er sich mit neuen Versionen von Bibliotheken nicht mehr kompilieren lässt, ermöglicht die Containerisierung die Kompilierung unseres Codes mit alten Versionen von Bibliotheken. 

Der Vergleich von Yocto-Builds mit und ohne Docker zeigt ganz eindeutig: Docker macht die Wartung von langlebigen Produkten viel einfacher als der traditionelle Ansatz, da es die Behebung von Kompilierungsfehlern erheblich beschleunigt. 

Best Practices für Yocto-Builds mit Docker 

Die Einhaltung von Best Practices und die Wachsamkeit bei der Versionskontrolle und Fehlersuche in Container-Umgebungen sind von entscheidender Bedeutung. Am besten ist es, ein Versionskontrollsystem und gründliche Tests durchzuführen.  

Nachfolgend werden einige hilfreiche Tipps erörtert, die die Effektivität des YP- und Docker-Kompilierungsmanagements beeinflussen werden: 

1. Beachten Sie die wichtigsten Grundsätze der Containerisierung

Beginnen Sie mit offiziellen und minimalen Basis-Images, um unnötigen Overhead zu vermeiden. Verwenden Sie außerdem eine mehrstufige Docker-Kompilierung, um die Größe des endgültigen Images auf ein Minimum zu beschränken. 

2. Stützen Sie sich auf die Best Practices des Yocto-Projekts

Organisieren Sie Yocto-Ebenen effektiv und aktualisieren Sie die Ebenen regelmäßig, um mit den neuesten Erweiterungen und Fehlerkorrekturen auf dem Laufenden zu bleiben. 

Jede Schicht in YP hat eine Entsprechung für eine bestimmte Version von Yocto. Wenn wir z.B. mit YP Version Tag: yocto-4.0.13, Tag: 2022-04.13-kirkstone arbeiten, bedeutet Tag: 2022-04.13, dass es sich um die Version 4.0.13 von kirkstone handelt, die auf dem Docker Image läuft. Jede Schicht, von der wichtigsten, d.h. openembedded-core, bis hin zu kleineren, wie meta-python, usw., muss in der kirkstone-Version sein. Das Bitbake hingegen muss in der Version sein, die mit dem Yocto-Release verbunden ist. 

Eine bewährte Praxis bei der Verwaltung von Ebenen ist die Verwendung von .bbappend-Dateien. Wenn ein Fehler in einer Ebene von außen auftritt, müssen Sie keine Änderungen in die betreffende Ebene einfügen, sondern bbappend verwenden. 

3. Speichern Sie Docker-Images 

Verwenden Sie den Docker Layer Caching-Mechanismus, um nachfolgende Kompilierungen durch die Wiederverwendung von Zwischenschichten zu beschleunigen (Leverage Docker Layer Caching). Jede Abhängigkeit sollte separat zwischengespeichert werden, um unnötiges erneutes Herunterladen und Wiederherstellen während der iterativen Entwicklung zu vermeiden. 

4. Optimieren Sie Yocto 

  • Passen Sie die Anzahl der parallelen Kompilierungsaufgaben (z.B. make -jX) basierend auf den verfügbaren Systemressourcen an, um Yocto-Kompilierungen zu beschleunigen. 
  • SSTATE-Cache: Konfigurieren und verwenden Sie den Shared State Cache (SSTATE) zur Speicherung von Kompilierungs-Zwischenergebnissen und beschleunigen Sie so den Prozess erheblich. 

5. Bilder selektiv erstellen 

Wenn Sie für einen bestimmten Zweck entwickeln, bauen Sie selektiv nur die notwendigen Images und Komponenten, um Zeit und Ressourcen zu sparen. Verwenden Sie die BitBake-Umgebungsvariablen, um zu kontrollieren, welche Pakete in unserem Distributions-Image installiert werden. 

6. Achten Sie auf die Überwachung und Kontrolle 

Regelmäßige Profilerstellung und Überwachung der Kompilierzeit sind unerlässlich, um Engpässe zu erkennen und ressourcenintensive Aufgaben zu optimieren. Eine detaillierte Protokollierung während der Kompilierung ist ebenfalls wichtig, um Probleme zu beheben und zu identifizieren. 

7. Integrieren Sie ihre Yocto-Umgebungskonfiguration in die Versionskontrolle 

Wenn Sie Yocto-Schichten aus Git-Repositories verwenden, sollten Sie die Verwendung von Git-Submodulen in Betracht ziehen, um Abhängigkeiten effizienter zu verwalten. Speichern Sie außerdem Ihre Yocto-Umgebungskonfigurationen in Ihrem Versionskontrollsystem, um die Reproduzierbarkeit über verschiedene Entwicklungsumgebungen hinweg sicherzustellen. 

Mögliche Herausforderungen bei der Yocto-Build-Einrichtung mit Docker 

Während die Kombination von Yocto und Docker erhebliche Vorteile bietet, gibt es auch Herausforderungen, denen sich Entwickler stellen können. Eine typische Herausforderung ist die Größe des resultierenden Docker-Images, das aufgrund des Kompilierungsprozesses selbst, der bereits einen enormen Overhead verursacht, recht groß sein kann. Ein kleines Programm, dessen Code 10 MB benötigt, kann beispielsweise einen transienten Code für den Linker, die so genannte Objektdatei usw. erzeugen, der 500 MB benötigt, damit die ausführbare Datei 1 MB groß wird. Dies kann jedoch durch die Verwendung von mehrstufigen Kompilierungs- und Bildoptimierungstechniken behoben werden, um die endgültige Größe des Docker-Images zu verringern. 

Weitere Herausforderungen bei der Yocto-Build-Einrichtung mit Docker sind: 

  • Widersprüche zwischen den Formulierungen können zu Kompilierungsfehlern führen.  
  • Das Sicherstellen, dass das Dockerfile für Leistung und Ressourcennutzung optimiert ist.  
  • Die Verwaltung von Abhängigkeiten und die Integration von Schichten in Docker-Containern bei der Arbeit mit Yocto kann schwierig sein. 
  • Das Sicherstellen der Reproduzierbarkeit und Konsistenz der Yocto-Kompilierung in verschiedenen Umgebungen. 

Um diese Herausforderungen zu meistern, ist es wichtig, ein kompatibles Basis-Image zu wählen, die benötigten Pakete sicher zu installieren, Yocto-Schichten hinzuzufügen und sorgfältig parallele und inkrementelle Kompilierung zu verwenden. Darüber hinaus ist es wichtig, während der Entwicklung Best Practices für die Verwaltung von Abhängigkeiten und die Integration von Schichten in Docker-Containern zu befolgen.  

Fazit 

Für die Entwicklung von Embedded Linux ist es am besten, eine vollständig containerisierte Entwicklungsumgebung zu verwenden, um eine wiederholbare Kompilierung und Konfiguration zu gewährleisten. So können Sie parallel an mehreren Projekten mit unterschiedlichen Konfigurationsanforderungen auf demselben Rechner arbeiten. Außerdem können wir durch die Dockerisierung der Entwicklungsumgebung das System sauber halten und so die Belastung mit projektspezifischen Paketen vermeiden. 

Wenn Sie wissen wollen, welche Erfahrung die Spezialisten von VM.PL in Projekten mit eingebetteten Systemen gemacht haben, nehmen Sie bitte Kontakt mit uns auf. Wir beraten Sie gerne bei der Auswahl der richtigen Lösungen. 

Quellen: 

Kategorien Containern


Mariola Nowak
Mariola Nowak Content Writer
Piotr Łobacz Senior Security Embedded Developer

Design, Entwicklung, DevOps oder Cloud - welches Team brauchen Sie, um die Arbeit an Ihren Projekten zu beschleunigen?
Chatten Sie mit unseren Beratungspartnern, um herauszufinden, ob wir gut zusammenpassen.

Jakub Orczyk

Vorstandsmitglied /Verkaufsdirektor

Buchen Sie eine kostenlose Beratung
kuba (1)