La conteneurisation d’une application est aujourd’hui un standard dans le monde du développement, mais orchestrer des applications conteneurisées c’est encore mieux. Automatiser la construction de l’application ainsi que son déploiement est bénéfique pour l’accélération du cycle du développement logiciel. L’automatisation est réalisable par des pipelines de CI/CD et en reposant sur des plateformes de conteneurisation. Dans cet article, on démontrera étape par étape comment automatiser le build et le déploiement d’un exemple d’application Node.js en mettant en œuvre les outils : OpenShift, GitHub et Jenkins.
1. Introduction
Le terme DevOps est au cœur du développement logiciel, ainsi en mettant en place une démarche DevOps sur un projet, cela implique certains prérequis et une multitude de technologies à mettre à disposition pour assurer la réussite du projet dans un mode agile / DevOps.
Le processus du développement logiciel nécessite plusieurs étapes, en commençant par la compilation (build) de/des applications(s), tests et déploiement dans les environnements cibles. Ce processus, pour être efficace et pour qu’il puisse répondre aux prérequis des méthodologies agiles et du DevOps également, il faut implémenter la culture DevOps d’une part au sein des équipes et préparer les environnements et l’usine logicielle pour l’accomplissement de l’ensemble des phases du projet.
Dans cet article, on mettrait le process DevOps pour le déploiement d’un exemple d’application Node.js. La compilation et le déploiement de l’application sont réalisés dans OpenShift. L’automatisation des étapes de Build et de déploiement sera confiée dans un premier temps à une instance Jenkins créée par un template OpenShift.
Pour info : au début de l’article, on commence par présenter quelques concepts sur le modèle DevOps, les architectures à base de conteneurs et l’automatisation. Les ateliers réalisés dans cet article se basent tous sur ces concepts, je trouve nécessaire de faire un petit rappel.
2. Quelques définitions
2.1 DevOps
Le modèle DevOps repose sur une culture de collaboration qui s'accorde bien avec les principes de la philosophie open source et les méthodes de travail agiles. Ainsi pour développer des architectures applicatives modernes, il faut adopter de nouveaux processus, différents de ceux qui fonctionnaient par le passé. C’est pour cette raison qu’une démarche DevOps va apporter l’amélioration du processus du développement et d’exploitation, mais en plus contribuer au déclenchement de changements culturels au sein de l’entreprise.
Enfin et pour garantir la réussite du modèle DevOps, il faut sélectionner les outils adaptés à vos processus. Pour que l’équipe d’exploitation puisse suivre le rythme rapide des cycles de développement, elle doit s’appuyer sur une plateforme hautement flexible et traiter l’infrastructure de la même manière que les développeurs traitent leur code, car les déploiements manuels prennent plus de temps, sans compter le risque d’erreurs. Une plateforme hautement flexible peut se reposer sur une infrastructure OpenShift ou Kubernetes par exemple, pour déployer des applications à base de conteneurs ou des architectures applicatives à microservices.
2.2 Conteneurs et microservices
2.2.1 Les conteneurs
Les conteneurs constituent une manière simple et efficace pour empaqueter et exécuter des services. Un conteneur contient toutes les dépendances nécessaires au bon fonctionnement de l’application. Les conteneurs sont isolés du reste du système en s’appuyant sur des fonctionnalités du noyau Linux. L’avantage est de ne pas solliciter beaucoup de ressources matérielles. La technologie des conteneurs améliore non seulement l’efficacité, la souplesse et la capacité de réutilisation des applications, mais aussi la portabilité de ses applications. En effet, l’OCI (Open Container Interface) fournit un ensemble de normes de l’industrie qui définissent une spécification d’exécution de conteneur et une spécification d’image de conteneur (voir références 2). La spécification d’image définit le format de l’ensemble de fichiers et de métadonnées formant une image de conteneur. Lorsque vous créez une application en tant qu’image de conteneur, conforme à la norme OCI, vous pouvez utiliser n’importe quel moteur de conteneur compatible OCI pour exécuter l’application.
La norme OCI est fondée sur des spécifications qui définissent un format d’image standard, communautaire et non propriétaire.
Pour exécuter un conteneur, il faut créer ce qu’on appelle une image de conteneur (voir figure ci-dessous). Les images constituent la base de l’exécution des conteneurs. Les conteneurs en cours d’exécution utilisent une vue immuable de l’image, ce qui permet à plusieurs conteneurs de réutiliser la même image simultanément.
Les images sont stockées soit localement, soit dans des référentiels d’images, on utilise souvent le terme anglophone Images Registry.
Il existe une multitude de registres d’images :
- DockerHub ;
- Registre de conteneurs Google GCR (Google Container Registry) ;
- Registre de conteneurs Amazon Elastic Container ;
- Red Hat Quay.
Il est également possible d’héberger un registre de conteneurs privé. Harbor est un référentiel de conteneurs qui peut être déployé en interne à l’entreprise (On-Premise).
2.2.2 Les microservices
Les microservices désignent une approche architecturale de développement d’application. Les microservices sont des services liés entre eux par des appels API, ils sont distribués et faiblement couplés.
Les avantages d’une architecture applicative à microservice sont :
- une modification apportée à un composant n’affecte pas l’ensemble de l’application ;
- les équipes développement sont en mesure de créer rapidement de nouveaux composants d’applications pour répondre aux évolutions des besoins dans le cycle de vie du projet ;
- les services peuvent être développés et déployés indépendamment les uns des autres ;
- chaque service peut être codé dans une technologie et dans un langage différent des autres, et ainsi optimiser la performance et la fiabilité de l’application en totalité ;
- l’architecture à microservice permet des déploiements et des montées de versions plus agiles ;
- assurer une haute évolutivité, résilience, facilité de déploiement, et exposition par les API.
Note : dans cet article, on déploie donc un microservice en tant que conteneur dans la plateforme OpenShift, c’est la raison pour laquelle j’ai voulu évoquer quelques termes autour de la technologie des conteneurs et du DevOps.
2.3 Orchestration des conteneurs
Le déploiement des conteneurs est avantageux pour accélérer le processus de la livraison, mais en environnement de production, déployer un conteneur isolé sur une machine constitue un ensemble de limitations :
- si le conteneur se trouve dans un état d’échec, aucun moyen ne permet d’automatiser son redémarrage ;
- impossible d’augmenter le nombre d’instances de ce conteneur pour répondre à une montée en charge ou à une grande sollicitation de l’application ;
- la gestion automatisée des mises à jour des versions de l’application ;
- assurer la santé de l’application tout au long du cycle d’exécution du conteneur.
En raison de ces limitations, le besoin d’un orchestrateur de conteneurs demeure nécessaire, permettant d’offrir toutes les tâches assurant le bon fonctionnement de ces derniers, d’autant plus lorsque l’application est architecturée en microservices et disposant donc de plusieurs conteneurs distribués.
Les plateformes d’orchestration les plus utilisées aujourd’hui sur le marché sont Kubernetes et OpenShift.
2.3.1 Kubernetes
Kubernetes est un service d’orchestration qui automatise le processus du déploiement, de la gestion et de la mise à l’échelle des applications en conteneurs. Une plateforme Kubernetes permet d’éliminer plusieurs processus manuels et d’assurer un cycle de vie applicatif automatisé et de remédier à différentes limitations citées dans le paragraphe précédent.
Kubernetes est le moyen le plus efficace pour optimiser le développement des applications cloud-native.
Les fonctionnalités principales de Kubernetes sont :
- orchestrer des conteneurs sur plusieurs hôtes ;
- optimiser l’utilisation des ressources physiques requises pour l’exécution des différentes applications hébergées au sein du cluster Kubernetes ;
- automatiser et contrôler les déploiements ainsi que la montée en versions des différentes images encapsulant les applications ;
- mise à l’échelle automatique des conteneurs (augmentation du nombre des conteneurs à la volée) à travers les fonctionnalités d’autoscaling horizontal (HPA) et vertical qui sont nativement intégrées à Kubernetes ;
- Kubernetes peut utiliser les contrôles d’intégrité (Health-check) définis dans les manifestes de déploiement des services pour une autoréparation des conteneurs, en cas d’échec.
2.3.2 OpenShift
OpenShift est une plateforme basée principalement sur l’orchestrateur Kubernetes. C’est un produit Red Hat connu sous le nom Red Hat OpenShift Container Platform.
L’avantage d’OpenShift par rapport à Kubernetes est qu’il dispose d’un mécanisme de compilation du code source en se reposant sur les bibliothèques et les environnements d’exécution pour la plupart des langages de programmation.
En effet, à partir du code source stocké dans un référentiel Git, OpenShift peut récupérer directement le code source, puis compile et déploie l’application. Le déploiement fait en sorte de créer toutes les ressources nécessaires pour le bon fonctionnement du service déployé. OpenShift est fourni également avec un ensemble de services disponibles de modèles pour faire du CI/CD et la supervision, par exemple.
2.4 Intégration continue et déploiement continu
Dans une démarche DevOps, le concept d’intégration continue et de déploiement continu est fréquemment utilisé et il est considéré comme étant le pilier de cette démarche. Le principe de ce concept est la mise en œuvre de l’automatisation complète des phases de compilation, tests et déploiement d’applications.
2.4.1 Intégration continue
L’intégration continue est une méthodologie utilisée en développement logiciel avec laquelle le code développé est intégré régulièrement et fréquemment à un référentiel de gestion de versions tel que GitHub ou GitLab. Une fois que le code est intégré, l’intégration continue mène aussi la partie compilation et tests automatisés.
2.4.2 Déploiement continu
Le déploiement continu est une extension de l’intégration continue, une fois le code compilé et testé, une nouvelle version de l’application ou du service est déjà prête à être déployée dans les environnements d’avant production et en suite en production. Le déploiement en production le plus souvent n’est pas automatique et nécessite une approbation au préalable.
Il existe un autre terme équivalent au déploiement continu qui est la livraison continue, qui elle consiste à déployer automatiquement les changements du code dans un environnement de test ou de « préprod » afin de s’assurer du bon fonctionnement de l’application avant de promouvoir en production.
2.5 Pipelines CI/CD
Un pipeline de CI/CD est une série d’étapes à réaliser en vue de distribuer une nouvelle version d’une application. Toutes les tâches à réaliser dans le cadre de l’intégration continue et du déploiement continu peuvent être associées à un pipeline permettant d’automatiser l’ensemble des phases du pipeline.
Les phases d’un pipeline sont :
- compilation (build) du code source depuis un référentiel Git ;
- test du code comprenant les tests unitaires, tests fonctionnels, et tests de qualité du code, par exemple ;
- stockage de la nouvelle version et de ses métadonnées dans un gestionnaire de packages ;
- déploiement en environnement de préproduction en vue de réaliser des tests supplémentaires, à l’instar des tests de performance ;
- déploiement en production ;
- supervision et récupération des informations de l’application en cours d’exécution en vue de détecter une éventuelle anomalie ou un dysfonctionnement.
3. Installation d’un cluster OpenShift
Plusieurs produits permettent d’installer OpenShift, tout dépend du besoin de l’entreprise si elle veut mettre en place une plateforme OpenShift installée au sein de l’infrastructure interne (On-Premise) ou dans le cloud pour bénéficier d’une plateforme managée.
Les différentes plateformes OpenShift existantes sont :
- Red Hat OpenShift Container Platform : fournit une plateforme OpenShift destinée aux entreprises pour l’orchestration de conteneurs dans n’importe quel datacenter public ou privé. Cette plateforme est nativement compatible avec la plupart des fournisseurs cloud et de virtualisation.
- Red Hat OpenShift Dedicated : fournit un environnement OpenShift géré dans un cloud public à l’instar de AWS, GCP, Microsoft Azure ou IBM Cloud. L’infrastructure OpenShift est gérée par Red Hat pour assurer les montées de versions ou les patchs, par exemple.
- Red Hat OpenShift Online : c’est la plateforme OpenShift disponible en ligne offrant des solutions de création, de déploiement et d’hébergement d’applications dans un environnement cloud. C’est aussi Red Hat qui gère le cycle de vie du cluster.
- Red Hat OpenShift Kubernetes Engine : fournit un sous-ensemble des fonctions présentes dans OpenShift Container Platform, tel que le système d’exploitation orienté conteneur Red Hat Entreprise Linux CoreOS, le moteur CRI-O, la plateforme d’orchestration de conteneur Kubernetes et les principaux services de cluster (console web, mises à jour OTA, registre interne).
- Red Hat Code Ready Containers : fournit une installation minimale d’OpenShift à des fins de développement local ou pour tester la plateforme OpenShift.
Une alternative permettant de déployer un environnement OpenShift est de provisionner une sandbox OpenShift depuis le site Red Hat Developer : https://developers.redhat.com/developer-sandbox.
C’est ce mode de provisioning qui sera utilisé dans cet article pour mettre à disposition l’environnement OpenShift.
Vous pouvez également déployer OpenShift avec Code Ready Container (voir mon article : « Petite introduction à OpenShift » paru dans LM 250 [1]).
3.1 Provisionner OpenShift
Pour provisionner une sandbox OpenShift, rendez-vous sur le site :
https://developers.redhat.com/developer-sandbox.
Vous aurez une page comme dans la figure ci-dessous :
Cliquez sur le bouton Start your sandbox for free, puis connectez-vous avec un nom d’utilisateur et un mot de passe (sinon, créez un compte Red Hat).
Une fois connecté, cliquez sur le bouton Start using your sandbox comme indiqué sur la figure ci-dessous.
Vous êtes redirigé vers une console vous permettant de vous connecter à OpenShift. Il suffit de cliquer sur le bouton DevSandbox.
C’est fait ! Notre environnement OpenShift est maintenant prêt pour déployer notre application.
En provisionnant une sandbox, on aura accès à un projet dédié pour déployer nos ressources. Dans mon cas, le nom du projet (namespace au sens Kubernetes) est issam-mejri-ext-dev.
Commençons la mise en œuvre de notre application dans le paragraphe suivant.
4. Création manuelle des ressources dans OpenShift
Il existe deux manières de créer des ressources dans OpenShift, une via la console, et c’est la méthode la plus simple pour ceux qui veulent une prise en main rapide de la plateforme, et la deuxième, c’est d’avoir recours à la ligne de commande. À travers la ligne de commande, il est possible de taper directement des commandes (mode imperative) pour la création des ressources, ou de créer des manifestes de déploiements dans des fichiers YAML (mode declarative).
4.1 Déploiement de notre application via la console OpenShift
Le code source de notre application est stocké dans le référentiel Git :
https://github.com/imejri/nodejs-app.git.
Le dépôt Git contient le code source de notre application Node.js ainsi que les fichiers de déploiement des ressources OpenShift, dont nous aurons besoin lors de l’étape de la mise en place du pipeline CI/CD dans Jenkins et GitLab CI.
OpenShift dispose de plusieurs scénarios de déploiement. Dans notre cas, c’est de fournir l’URL du référentiel Git de notre application à OpenShift, ensuite la plateforme récupère automatiquement le code source pour compiler et déployer toutes les ressources de l’application.
La console offre deux perspectives, une pour les développeurs, et une autre pour les administrateurs. Nous choisissons le mode développeur pour intégrer notre application comme illustré sur la figure ci-dessous.
Cliquez ensuite sur Import from Git pour spécifier l’URL du référentiel Git :
Une fois qu’OpenShift accède au référentiel Git et en parcourant la racine du dépôt, il va détecter la présence d’un Dockerfile. Dans ce cas précis, il lancera un build de type Docker permettant de créer l’image correspondante et de la pousser vers le registry interne d’OpenShift.
Il est possible d’indiquer sur quelle branche la compilation sera réalisée ainsi que le chemin vers les sources lorsque le code de l’application se trouve dans un sous-répertoire, et non à la racine du référentiel Git.
Les autres options sont :
- les ressources qui seront créées à la suite de la compilation ;
- le port cible à exposer ;
- le choix pour la création de la route permettant d’accéder à l’application en dehors d’OpenShift ;
- possibilité de choisir une autre stratégie de build (Builder Image, par exemple). On évoquera cette stratégie dans la partie CI/CD.
Si l’on clique sur Edit Import Strategy - Builder Image, on affiche l’ensemble des images de build permettant de créer l’environnement de compilation du code et d’exécution de l’application. Dans notre cas, une image Node.js est choisie par défaut.
Génial ! OpenShift a réussi à détecter le langage de notre application.
Enfin, on clique sur le bouton Create pour lancer le processus de build et de déploiement.
Pour vérifier que notre application a été bien déployée, visitez l’onglet Topology de la console :
Accédez à l’application en cliquant sur la petite flèche encadrée en rouge dans l’illustration précédente.
Il s’agit de l’URL (route) créée automatiquement par OpenShift pour accéder à l’application depuis l’extérieur (https://nodejs-app-git-issam-mejri-ext-dev.apps.sandbox-m2.ll9k.p1.OpenShiftapps.com/).
Super ! Notre application est désormais accessible.
4.2 Déploiement de notre application via la CLI OpenShift
Le déploiement de notre application par la ligne de commande est très simple à faire. Une seule commande génère toutes les ressources nécessaires à l’exécution de l’application.
Sur les nouvelles versions d’OpenShift, la console fournit un terminal (OpenShift Web Terminal) qui inclut tous les outils pour administrer OpenShift.
Pour lancer un terminal, il suffit de cliquer sur le symbole situé en haut à droite de la console (voir figure ci-dessous).
Une fois le terminal lancé, on n’a pas besoin de se connecter à notre projet OpenShift, car l’authentification est intégrée directement dès lors que le terminal est en cours d’exécution.
Commençons par supprimer l’ancien déploiement :
On supprime toutes les ressources créées en spécifiant le label app=nodejs-app-git :
Maintenant, on peut déployer notre application à nouveau, mais cette fois-ci en invoquant la commande oc new-app :
Sur la console OpenShift, cliquez sur Topology dans le volet de navigation pour afficher les ressources créées.
Mais pour l’instant, notre route permettant d’atteindre l’application n’est pas encore créée. Il faut la créer comme indiqué sur la sortie de la commande oc new-app précédente :
Notre application est désormais accessible :
5. Environnement CI/CD et automatisation
Pour automatiser la compilation et la création de l’image Docker ainsi que le déploiement dans OpenShift de notre application, il faut avoir recours à des outils de CI/CD. Dans cet article, j’ai choisi Jenkins.
La création du serveur Jenkins sera réalisée directement via un pod dans OpenShift. En effet, OpenShift dispose d’un catalogue de services permettant d’ajouter des fonctionnalités directement intégrées à la plateforme, ce qui facilite le provisioning de la solution souhaitée.
6. Pipeline de build et de déploiement avec Jenkins
Dans cette partie de l’article, nous mettons en place l’automatisation des différentes étapes réalisées manuellement dans les paragraphes précédents en reposant sur une instance Jenkins déployée en tant que pod dans OpenShift. L’automatisation du processus CI/CD est réalisable par un job Jenkins de type pipeline.
Un pipeline Jenkins est créé à partir d’un fichier JenkinsFile qui contient l’ensemble des phases de compilation, tests et déploiement de l’application.
Notre instance Jenkins, sans entrer dans les détails, car ce n’est pas le but de l’article, intègre un plug-in permettant de communiquer avec les API OpenShift. Le plug-in à installer dans le cas où vous voudriez intégrer un serveur Jenkins en dehors d’OpenShift est OpenShift Jenkins Pipeline (DSL) Plug-in.
6.1 Déploiement du pod Jenkins
Le déploiement du pod Jenkins se fait via la console OpenShift. Dans le volet gauche de la console, l’onglet Add est le point d’accès à un assistant qui vous permet de choisir entre différentes méthodes de déploiement d’une application sur le cluster OpenShift. Cliquez sur Add pour afficher la liste des choix pour le déploiement des applications. Dans notre cas, il faut développer la section All Services dans le volet droit de la fenêtre, dans All Items choisir CI/CD comme indiqué sur la figure ci-dessous :
Cliquez ensuite sur CI/CD pour afficher la liste des services disponibles. Dans cette liste, on peut choisir le template Jenkins avec le volume persistant (voir capture d’écran ci-dessous).
Après avoir sélectionné Jenkins, cliquez sur instanciate Template. Dans la fenêtre qui apparaît, gardez toutes les valeurs par défaut, puis cliquez sur le bouton create en bas de la fenêtre.
Dans l’onglet Topology, le pod Jenkins apparaît avec l’ensemble des ressources nécessaires pour accéder à la console Jenkins.
6.2 Accès à la console Jenkins
À la suite au déploiement du template Jenkins dans le paragraphe précédent, une route est créée permettant d’accéder à la console du serveur Jenkins.
En copiant l’URL dans notre navigateur, on accède à la page d’authentification :
Cliquez sur Log in with OpenShift. Cela permet de s’authentifier avec les credentials d’accès à OpenShift.
Félicitation ! On peut désormais commencer à créer notre pipeline de CI/CD dans Jenkins.
6.3 Création du projet nodejs-app
Dans ce paragraphe, nous allons créer un projet de type pipeline pour le déploiement de notre application.
Dans le volet gauche de la console Jenkins, cliquez sur Nouveau Item, puis saisissez le nom du projet et choisissez Pipeline dans la liste des types de projets.
Une nouvelle fenêtre d’affiche permettant de configurer notre projet. Dans notre exemple, le build et le déploiement de l’application seront réalisés à partir d’un JenkinsFile, autrement dit, il faut indiquer à Jenkins où trouver ce fichier ainsi que le code source de l’application. Il faut aller tout en bas de la fenêtre et dans la section Pipeline, choisir Pipeline Script from SCM. Dans SCM, choisir Git et finalement dans Repositories, indiquez l’URL de notre projet dans GitHub, dans notre cas, c’est https://github.com/imejri/nodejs-app.git.
Finalement, cliquez sur le bouton Sauver pour enregistrer votre projet.
Le projet apparaît dans notre console Jenkins (voir figure ci-dessous).
Tout le reste des phases de build et de déploiement (pipeline de CI/CD) de l’application est inscrit dans le JenkinsFile, c’est le concept du Pipeline As Code.
Voici à quoi ressemble notre JenkinsFile :
Dans notre JenkinsFile, j’ai créé les stages suivants :
- Checkout du code permettant de cloner le dépôt dans le répertoire de travail de Jenkins ;
- Build Source Code pour la compilation du code avec la stratégie source to image (S2I) évoquée au début de l’article ;
- Deploy resources for DEV/STAGE environments pour le déploiement de l’application dans le cluster OpenShift ;
- Create route to access the Application pour la création de la route permettant de créer l’URL d’accès à l’application.
Il faut noter aussi que notre pipeline est paramétrable avec la section parameters au début du JenkinsFile. Le paramétrage permet de « variabiliser » le déploiement et la compilation, cela permet par exemple d’agir sur le versioning de notre application, le nombre de replicas à déployer ou encore la branche de référence pour l’exécution du pipeline (dans notre exemple, c’est la master branch).
Revenons à nos moutons, dans la console Jenkins, cliquez sur le projet nodejs-app, puis dans la partie gauche de la console, cliquez sur Lancer un build avec des paramètres. Nous allons réaliser un build d’une version 1.2 de notre application. Dans Environment, on va choisir notre projet OpenShift.
Dans DEPLOYMENT_TYPE, on choisit Build pour compiler le code source. On a une séparation dans notre pipeline de l’étape de build et du déploiement.
C’est bon, on est prêt pour exécuter notre pipeline, il suffit de cliquer sur le bouton Build en bas de la fenêtre.
Le déroulement du pipeline est accessible via la Console Output :
Notre image d’application est accessible dans OpenShift dans la partie Builds de la console :
La deuxième étape de notre pipeline est le déploiement de l’application et la création de la route. C’est le même déroulement que dans l’étape de build avec un changement de deux paramètres :
- DEPLOYMENT_TYPE : Deploy
- NB_REPLICAS : 3
On va déployer 3 pods de notre application en restant toujours sur la version du build précédent (v1.2). La sortie console permet de suivre le déroulement du déploiement :
Vérifions dans OpenShift le déploiement des trois pods et la création de la route en ligne de commande et depuis la console :
À partir du terminal intégré à OpenShift :
Vérifions la création de la route :
Comme vous l’avez remarqué tout au long de ce paragraphe, un simple clic sur un bouton dans la console Jenkins permet le build et le déploiement de notre application. C’est bien le concept d’automatisation et d’intégration et déploiement continu qui a été mis en place via Jenkins et la plateforme OpenShift.
Conclusion
La plateforme OpenShift nous a permis d’automatiser le processus de compilation et de déploiement de notre application Node.js, le fait aussi d’intégrer un outil de CI/CD comme Jenkins à OpenShift facilite la création et l’exécution du pipeline à travers notre JenkinsFile.
Un autre outil plus intégré à la plateforme, et aussi une alternative à Jenkins s’appelle Tekton. Cet outil permet de réaliser du CI/CD Cloud Native, c’est-à-dire sans besoin d’un outil annexe pour mettre en place du CI/CD. Si j’en ai le temps, je pourrais vous faire découvrir cette technologie dans un prochain article.
Références
[1] https://connect.ed-diamond.com/GNU-Linux-Magazine/glmf-250/petite-introduction-a-openshift