Rationaliser le développement Linux intégré avec Yocto Project et les conteneurs Docker

/ 12.12.2023 Conteneurs

Aujourd’hui, la croissance rapide des dispositifs IoT n’est une surprise pour personne, mais elle s’accompagne d’un besoin croissant de logiciels efficaces et fiables. Pour y parvenir, il est essentiel de disposer d’un processus de développement rationalisé afin de mettre le produit sur le marché plus rapidement et avec une qualité élevée. Comment y parvenir ? La réponse est le projet Yocto et la conteneurisation dans Docker.  

Linux est un choix populaire pour les systèmes intégrés en raison de sa grande fiabilité et de la disponibilité du code source. Cependant, le développement d’un tel système s’avère être un véritable défi en raison des ressources limitées, des exigences d’optimisation et d’un seuil d’entrée difficile. 

Les développeurs expérimentés qui travaillent dans le domaine des systèmes intégrés doivent non seulement avoir une connaissance approfondie du noyau Linux, des pilotes de périphériques et de la programmation de bas niveau, mais aussi de l’architecture matérielle et des systèmes d’exploitation en temps réel. Ces connaissances approfondies leur permettent de relever les défis que pose le développement de logiciels pour les appareils à ressources limitées.  

Pourquoi le développement de logiciels pour les systèmes intégrés est-il un défi ? 

L’un des aspects essentiels de la rationalisation des processus de développement est l’utilisation efficace des ressources disponibles. Les systèmes intégrés ayant souvent une mémoire et une puissance de traitement limitées, les développeurs doivent gérer avec soin la mémoire, l’utilisation de l’unité centrale et la consommation d’énergie. Cela implique l’optimisation du code, l’utilisation d’algorithmes efficaces et de techniques d’accélération matérielle. En rationalisant ces processus, les développeurs peuvent augmenter de manière significative les performances de leurs logiciels tout en minimisant l’utilisation des ressources.  

Un autre aspect important de la rationalisation des processus de développement est l’utilisation appropriée des systèmes de contrôle des versions et des outils de collaboration. Ces outils permettent aux développeurs de collaborer de manière transparente, de suivre les modifications et de résoudre les conflits de manière efficace. En adoptant les meilleures pratiques en matière de contrôle des versions et de collaboration, les équipes de développement peuvent assurer une coordination sans faille et minimiser le risque d’erreurs ou de conflits de code. 

Dans cet article, nous aborderons une façon de rationaliser le développement de systèmes intégrés à l’aide de YP et de conteneurs Docker. 

Qu’est-ce que le projet Yocto ? 

Selon la définition, Yocto Project est un projet collaboratif open-source qui fournit des modèles, des outils et des méthodes pour créer des distributions Linux personnalisées pour les systèmes intégrés tels que les appareils IoT, les smartphones, les tablettes, les appareils à écran tactile, etc. indépendamment de l’architecture matérielle. Vous pouvez créer une distribution pour votre Raspberry Pi, et même pour un Arduino UNO.  

Une enquête récente menée par la Fondation Eclipse montre que Yocto est utilisé par 71 % des personnes interrogées qui l’utilisent pour créer des distributions personnalisées pour les systèmes intégrés. 

Grâce au projet Yocto, les développeurs ont accès à des recettes qui leur permettent d’installer rapidement et facilement des logiciels dans la distribution qu’ils ont créée. De plus, l’écriture de recettes est si triviale que l’ajout de nouveaux logiciels se fait sans effort, ce qui leur permet de créer des distributions Linux dédiées et optimisées pour le matériel cible. Qu’il s’agisse d’un petit appareil IoT ou d’un système de contrôle industriel complexe, la conception de Yocto offre la flexibilité et l’évolutivité nécessaires pour répondre aux exigences uniques de chaque système intégré. 

Avantages de l’utilisation de Yocto dans les systèmes Linux intégrés 

Yocto simplifie le processus de création et de maintenance des distributions Linux spécialement conçues pour les systèmes intégrés. 

Les principaux avantages de Yocto comprennent plusieurs facteurs, dont les suivants : 

1. Yocto permet aux développeurs de créer un environnement de compilation standardisé et reproductible, garantissant des résultats cohérents sur différentes plates-formes matérielles. 

Yocto utilise le cadre OpenEmbedded comme système de compilation croisée. 

Il est basé sur BitBake, qui fonctionne comme un gestionnaire de paquets, c’est-à-dire qu’il lit les prescriptions et se charge de l’installation des paquets. Il permet aux développeurs de définir les composants logiciels et les configurations nécessaires à leur distribution Linux intégrée. En outre, il télécharge automatiquement le code source nécessaire, applique les correctifs et compile le logiciel, ce qui donne une image Linux complète prête à être déployée sur le matériel cible. Ceci est particulièrement important dans le domaine des systèmes intégrés, où les configurations matérielles peuvent varier considérablement. 

2. Yocto propose une architecture basée sur des couches (métacouches), qui permet de personnaliser et d’intégrer facilement des composants logiciels.  

Les développeurs peuvent ajouter ou supprimer des couches pour activer ou désactiver des fonctionnalités spécifiques, ce qui permet d’adapter facilement la distribution Linux aux exigences du système cible. Cette flexibilité garantit que le système résultant est optimisé. 

3. Il offre un large éventail de recettes prêtes à l’emploi, ce qui réduit considérablement le temps et les efforts nécessaires à l’intégration des logiciels.  

Les recettes, qui sont des recettes d’installation de paquets, sont maintenues par la communauté du projet YP et couvrent de nombreux composants logiciels couramment utilisés dans les systèmes intégrés. Ces outils comprennent un gestionnaire de paquets pour gérer les composants logiciels, un kit de développement logiciel (SDK) pour la compilation croisée des applications et un environnement d’exécution pour tester et déboguer le système. 

 Les développeurs peuvent utiliser ces ressources pour ajouter rapidement des fonctionnalités à leur distribution Linux, ce qui leur permet de gagner un temps précieux en matière de développement. 

Qu’est-ce qu’un conteneur Docker ? 

La conteneurisation est une technique qui permet aux développeurs de regrouper une application et ses dépendances dans un seul conteneur, garantissant ainsi que l’application fonctionne de la même manière, quel que soit l’environnement dans lequel elle est déployée. La technologie Docker est unique en ce sens qu’elle se concentre sur les besoins des développeurs et des opérateurs de systèmes pour séparer les dépendances de l’application par rapport à celles de l’infrastructure. Cela permet un déploiement cohérent et prévisible sur toutes les plateformes et dans tous les environnements, réduisant ainsi le risque d’erreurs et de temps d’arrêt. 

Les conteneurs Docker offrent plusieurs avantages pour le développement de logiciels : 

1. Fournir un environnement cohérent et reproductible 

Les conteneurs Docker éliminent le problème du « ça ne marche que sur mon matériel ». Les développeurs peuvent créer une image de conteneur qui contient l’ensemble de l’environnement de développement, y compris les bibliothèques, les outils et les dépendances. Cette image peut être partagée avec d’autres membres de l’équipe, ce qui garantit la cohérence tout au long du cycle de développement.  

2. Faciliter la collaboration entre les membres de l’équipe 

Les développeurs peuvent partager des images de conteneurs via le registre de conteneurs, ce qui permet à d’autres de reproduire rapidement l’environnement de développement. Cela favorise une culture DevOps dans laquelle le développement, les tests et le déploiement se déroulent de manière transparente. 

Combiner Yocto et Docker – pourquoi cela fonctionne-t-il à merveille ? 

L’utilisation de Docker pour créer vos propres distributions à l’aide d’YP présente de nombreux avantages. Les développeurs peuvent garantir la reproductibilité sur différentes machines et différents systèmes d’exploitation en encapsulant l’environnement de compilation dans un conteneur Docker. Cela élimine la nécessité de configurer manuellement l’environnement de compilation et réduit le risque d’incohérences et d’erreurs.  

Comment Docker résout-il les problèmes de l’approche traditionnelle ? 

Au lieu d’un document d’installation, nous pouvons donner l’image docker à nos collègues. En construisant le système de fichiers racine, appelé rotfs (root file system), nous lançons le conteneur docker (docker-composer), et dans celui-ci, nous exécutons uniquement bitbake. Le conteneur docker garantit que la compilation de notre distribution à l’aide d’YP sera exécutée par tout le monde dans exactement le même environnement d’exécution. YP a des tests de reproductibilité conçus pour créer des versions complètement reproductibles. Cela signifie que si vous exécutez une compilation aujourd’hui et que vous exécutez la même configuration X fois dans le futur, les binaires que vous obtiendrez de la compilation devraient être identiques. En exécutant en amont pour maintenir la reproductibilité après chaque changement de ces tests, peu importe les correctifs que vous ajoutez au code BitBake, à la couche OpenEmbedded, ou à d’autres couches mineures comme meta-python, vous obtiendrez le même résultat de compilation chaque fois. 

Grâce à l’utilisation de YP, la situation ne changera pas, même dans quelques années ; lorsque nous aurons de nouvelles versions de Linux sur nos ordinateurs ou lorsque les experts en compilation auront quitté l’équipe, nous pourrons recréer exactement la même image de Linux que celle que nous avons construite trois ou cinq ans plus tôt. 

Cela est possible parce que Docker permet de revenir à un code précédemment figé. Si vous constatez qu’il ne compile plus sur les nouvelles versions des bibliothèques, alors la conteneurisation permet de compiler notre code sur les anciennes versions des bibliothèques. 

Docker facilite la maintenance des produits à longue durée de vie par rapport à l’approche traditionnelle, car il accélère considérablement la résolution des erreurs de compilation. 

Meilleures pratiques utilisées pour gérer efficacement les compilations YP et Docker 

Il est essentiel de suivre les meilleures pratiques et d’être vigilant en ce qui concerne les versions et le débogage dans les environnements de conteneurs. Il est préférable d’utiliser un système de contrôle des versions et de procéder à des tests approfondis.  

Nous présentons ci-dessous quelques conseils utiles qui influenceront l’efficacité de la gestion des compilations YP et Docker : 

1. Appliquer les grands principes de la conteneurisation. 

Commencez par des images de base officielles et minimales afin de réduire les frais généraux inutiles. Utilisez également la compilation Docker en plusieurs étapes pour réduire au minimum la taille de l’image finale. 

2. Utiliser les meilleures pratiques du projet Yocto. 

  • Organisez efficacement les couches Yocto et mettez-les à jour régulièrement pour bénéficier des dernières améliorations et corrections de bogues. 

Chaque couche dans YP a un équivalent pour une version particulière de Yocto. Par exemple, si nous travaillons avec la version YP tag : yocto-4.0.13, tag : 2022-04.13-kirkstone, tag : 2022-04.13 signifie que c’est la version 4.0.13 de kirkstone qui tourne sur l’image docker. Chaque couche, de la plus importante, c’est-à-dire openembedded-core, aux plus mineures, comme meta-python, etc., doit être dans la version kirkstone. Le bitbake, quant à lui, doit être dans la version associée à la version Yocto. 

  • Une bonne pratique dans la gestion des couches est d’utiliser les fichiers .bbappend. En cas d’erreur dans une couche provenant de l’extérieur, il n’est pas nécessaire d’insérer des modifications dans la couche en question, mais d’utiliser bbappend. 

3. Mise en cache des images Docker 

Utilisez le mécanisme de mise en cache des couches de Docker pour accélérer les compilations ultérieures en réutilisant les couches intermédiaires (Leverage Docker Layer Caching). Chaque dépendance doit être mise en cache séparément afin d’éviter les téléchargements et reconstructions inutiles au cours du développement itératif. 

4. Optimiser Yocto 

  • Ajuster le nombre de tâches de compilation parallèle (par exemple, make -jX) en fonction des ressources système disponibles pour accélérer les compilations Yocto. 
  • Cache SSTATE : Configurez et utilisez le Shared State Cache (SSTATE) pour stocker les artefacts de compilation intermédiaires, ce qui accélère considérablement le processus. 

5. Créer des images de manière sélective 

Lorsque vous développez dans un but spécifique, ne construisez sélectivement que les images et les composants nécessaires afin d’économiser du temps et des ressources. Utiliser les variables d’environnement BitBake pour contrôler les paquets qui seront installés sur notre image de distribution. 

6. Veillez à contrôler et à enregistrer 

 Le profilage régulier et la surveillance de la compilation sont essentiels pour identifier les goulets d’étranglement et optimiser les tâches gourmandes en ressources. Une journalisation détaillée pendant la compilation est également importante pour aider au débogage et à l’identification des problèmes. 

7. Intégration du contrôle de version 

 Si vous utilisez des couches Yocto à partir de dépôts Git, pensez à utiliser des sous-modules Git pour gérer les dépendances plus efficacement. De plus, stockez vos configurations d’environnement Yocto dans votre système de contrôle de version afin d’assurer la reproductibilité dans différents environnements de développement. 

Défis potentiels lors de la compilation de Yocto avec Docker 

 Bien que la combinaison de Yocto et de Docker offre des avantages significatifs, il y a aussi des défis auxquels les développeurs peuvent être confrontés. Un défi typique est la taille de l’image Docker résultante, qui peut être assez grande en raison du processus de compilation lui-même qui cause déjà une énorme surcharge. Par exemple, un petit programme dont le code prend 10 Mo peut créer un code transitoire pour l’éditeur de liens, le fichier objet, etc., qui prendra 500 Mo pour que le fichier exécutable prenne 1 Mo. Il est toutefois possible de remédier à ce problème en utilisant des techniques de compilation en plusieurs étapes et d’optimisation d’image afin de réduire la taille finale de l’image Docker. 

Les autres défis sont les suivants:

  • Les conflits entre les formulations peuvent entraîner l’échec de la compilation.  
  • Veiller à ce que le fichier Docker soit optimisé en termes de performances et d’utilisation des ressources.  
  • La gestion des dépendances et l’intégration des couches dans les conteneurs Docker lorsque l’on travaille avec Yocto peut s’avérer difficile. 
  • Assurer la reproductibilité et la cohérence de la compilation de Yocto dans différents environnements. 

Pour surmonter ces défis, il est important de choisir une image de base compatible, d’installer en toute sécurité les paquets requis, d’ajouter des couches Yocto et d’utiliser soigneusement la compilation parallèle et incrémentale. En outre, il est important de suivre les meilleures pratiques pour la gestion des dépendances et l’intégration des couches dans les conteneurs Docker pendant le développement.  

 Résumé    

 Pour le développement de Linux intégré, il est préférable d’utiliser un environnement de développement entièrement conteneurisé afin de garantir une compilation et une configuration répétables. Cela permet de travailler en parallèle sur plusieurs projets ayant des exigences de configuration différentes sur la même machine. De plus, le fait d’utiliser un environnement de développement conteneurisé nous permet de garder le système propre et de ne pas l’encombrer avec des paquets spécifiques à un projet. 

Si vous souhaitez discuter de l’expérience des spécialistes de VM.PL dans les projets de systèmes intégrés, n’hésitez pas à nous contacter. Nous nous ferons un plaisir de vous conseiller sur le choix des bonnes solutions. 

Sources : 

Catégorie: Conteneurs


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

Conception, développement, DevOps ou Cloud - de quelle équipe avez-vous besoin pour accélérer le travail sur vos projets ?

Discutez avec vos partenaires de consultation pour voir si nous sommes compatibles.

Jakub Orczyk

Membre du Conseil d’administration/Directeur des ventes VM.PL

Réservez une consultation gratuite
kuba (2)