Applications OpenShift modernes, partie 3: OpenShift comme environnement de développement et pipelines OpenShift

Bonjour à tous sur ce blog! Il s'agit du troisième article d'une série dans laquelle nous vous montrons comment déployer des applications Web modernes sur Red Hat OpenShift.







Dans les deux articles précédents, nous avons expliqué comment déployer des applications Web modernes en quelques étapes seulement et comment utiliser une nouvelle image S2I avec une image de serveur HTTP prête à l'emploi telle que NGINX à l'aide de versions chaînées pour le déploiement en production.



Aujourd'hui, nous allons vous montrer comment exécuter un serveur de développement pour votre application sur la plate-forme OpenShift et le synchroniser avec le système de fichiers local, ainsi que parler de ce qu'est OpenShift Pipelines et comment vous pouvez l'utiliser comme alternative aux assemblys liés.



OpenShift comme environnement de développement



Workflow de développement



Comme indiqué dans le premier article , un flux de travail de développement typique pour les applications Web modernes est simplement un «serveur de développement» qui surveille les modifications des fichiers locaux. Quand ils se produisent, la construction de l'application est lancée, puis elle est mise à jour dans le navigateur.



Dans la plupart des frameworks modernes, ce "serveur de développement" est intégré aux outils de ligne de commande correspondants.



Exemple local



Voyons d'abord comment cela fonctionne dans le cas de l'exécution d'applications localement. Prenons comme exemple l'application React des articles précédents, bien que la plupart des mêmes concepts de flux de travail s'appliquent à tous les autres frameworks modernes.

Ainsi, pour démarrer le "serveur de développement" dans notre exemple React, nous émettons la commande suivante:



$ npm run start


Ensuite, dans la fenêtre du terminal, nous verrons quelque chose comme ce qui suit:







Et notre application s'ouvrira dans le navigateur par défaut:







Maintenant, si nous apportons des modifications au fichier, l'application doit se mettre à jour dans le navigateur.



OK, avec le développement local, tout est clair, mais comment faire la même chose sur OpenShift?



Serveur de développement sur OpenShift



Si vous vous souvenez, dans le post précédent , nous avons analysé la phase dite d'exécution de l'image S2I et avons vu que par défaut, le module de service est chargé de servir notre application Web.



Cependant, si vous regardez de plus près le script d'exécution de cet exemple, vous verrez qu'il contient la variable d'environnement $ NPM_RUN, qui vous permet d'exécuter votre propre commande.



Par exemple, nous pouvons utiliser le module nodeshift pour déployer notre application:



$ npx nodeshift --deploy.env NPM_RUN="yarn start" --dockerImage=nodeshift/ubi8-s2i-web-app


Remarque: l'exemple ci-dessus est abrégé pour illustrer l'idée générale.



Ici, nous avons ajouté la variable d'environnement NPM_RUN à notre déploiement, qui indique au runtime d'exécuter la commande yarn start, qui démarre le serveur de développement React dans notre pod OpenShift.



Si vous regardez le journal d'un pod en cours d'exécution, il y aura quelque chose comme ce qui suit:







Bien sûr, tout cela ne sera rien tant que nous ne pourrons pas synchroniser le code local avec du code qui est également surveillé pour les changements, mais qui vit sur un serveur distant.



Synchronisation du code distant et local



Heureusement, nodeshift peut facilement aider à la synchronisation et vous pouvez utiliser la commande watch pour suivre les modifications.



Ainsi, après avoir exécuté la commande pour déployer le serveur de développement pour notre application, nous pouvons utiliser en toute sécurité la commande suivante:



$ npx nodeshift watch


En conséquence, une connexion sera établie avec le pod en cours d'exécution, que nous avons créé un peu plus tôt, la synchronisation de nos fichiers locaux avec le cluster distant sera activée et les fichiers sur notre système local seront surveillés pour les changements.



Par conséquent, si nous mettons maintenant à jour le fichier src / App.js, le système réagira à ces modifications, les copiera dans le cluster distant et démarrera le serveur de développement, qui mettra ensuite à jour notre application dans le navigateur.



Pour être complet, montrons à quoi ressemblent ces commandes dans leur intégralité:



$ npx nodeshift --strictSSL=false --dockerImage=nodeshift/ubi8-s2i-web-app --build.env YARN_ENABLED=true --expose --deploy.env NPM_RUN="yarn start" --deploy.port 3000

$ npx nodeshift watch --strictSSL=false


La commande watch est une abstraction par dessus la commande oc rsync, vous pouvez en savoir plus sur son fonctionnement ici .



C'était un exemple pour React, mais la même méthode peut être utilisée avec d'autres frameworks, il suffit de définir la variable d'environnement NPM_RUN si nécessaire.



Pipelines OpenShift









Ensuite, nous parlerons d'un outil comme OpenShift Pipelines et de la manière dont il peut être utilisé comme alternative aux builds chaînés.



Qu'est-ce que les pipelines OpenShift?



OpenShift Pipelines est un système d'intégration et de livraison continue CI / CD basé sur le cloud pour organiser les pipelines à l'aide de Tekton. Tekton est un framework CI / CD natif Kubernetes flexible et open source qui automatise les déploiements sur les plates-formes (Kubernetes, sans serveur, machines virtuelles, etc.) en faisant abstraction de la couche sous-jacente.



Une certaine connaissance de Pipelines est nécessaire pour comprendre cet article, nous vous conseillons donc vivement de lire d'abord le tutoriel officiel .



Mise en place de l'environnement de travail



Pour jouer avec les exemples de cet article, vous devez d'abord préparer votre environnement de production:



  1. OpenShift 4. CodeReady Containers (CRD), .
  2. , , Pipeline Operator. , , .
  3. Tekton CLI (tkn) .
  4. create-react-app, , ( React).
  5. () , npm install npm start.


Le référentiel d'applications aura également un dossier k8s, dans lequel se trouveront les YAML Kubernetes / OpenShift utilisés pour déployer l'application. Il y aura des tâches, des tâches de cluster, des ressources et des pipelines que nous créerons dans ce référentiel .



Commençons



La première étape de notre exemple consiste à créer un nouveau projet dans le cluster OpenShift. Appelons ce projet webapp-pipeline et créons-le avec la commande suivante:



$ oc new-project webapp-pipeline


De plus, ce nom de projet apparaîtra dans le code, donc si vous décidez de lui donner un autre nom, n'oubliez pas de modifier le code des exemples en conséquence. À partir de là, nous n'irons pas de haut en bas, mais de bas en haut: c'est-à-dire que nous allons d'abord créer tous les composants du convoyeur, et seulement ensuite lui-même.



Alors, tout d'abord ...



Tâches



Créons quelques tâches qui nous aideront ensuite à déployer l'application via notre pipeline. La première tâche, apply_manifests_task, est chargée d'appliquer YAML aux ressources Kubernetes (service, déploiement et route) qui se trouvent dans le dossier k8s de notre application. La deuxième tâche - update_deployment_task - est responsable de la mise à jour d'une image déjà déployée vers celle créée par notre pipeline.



Ne vous inquiétez pas si ce n'est pas encore clair. En fait, ces tâches sont quelque chose comme des utilitaires, et nous les discuterons plus en détail un peu plus tard. Pour l'instant, créons-les simplement:



$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/update_deployment_task.yaml
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/apply_manifests_task.yaml


Ensuite, à l'aide de la commande CLI tkn, vérifiez que les tâches ont été créées:



$ tkn task ls

NAME                AGE
apply-manifests     1 minute ago
update-deployment   1 minute ago


Remarque: ce sont des tâches locales de votre projet actuel.



Tâches de cluster



Les tâches groupées sont fondamentalement les mêmes que les tâches simples. Autrement dit, il s'agit d'une collection réutilisable d'étapes qui sont combinées d'une manière ou d'une autre lors du démarrage d'une tâche spécifique. La différence est que la tâche de cluster est disponible partout dans le cluster. Pour afficher une liste des tâches de cluster qui sont automatiquement créées lors de l'ajout de l'opérateur de pipeline, utilisez à nouveau la commande CLI tkn:



$ tkn clustertask ls

NAME                       AGE
buildah                    1 day ago
buildah-v0-10-0            1 day ago
jib-maven                  1 day ago
kn                         1 day ago
maven                      1 day ago
openshift-client           1 day ago
openshift-client-v0-10-0   1 day ago
s2i                        1 day ago
s2i-go                     1 day ago
s2i-go-v0-10-0             1 day ago
s2i-java-11                1 day ago
s2i-java-11-v0-10-0        1 day ago
s2i-java-8                 1 day ago
s2i-java-8-v0-10-0         1 day ago
s2i-nodejs                 1 day ago
s2i-nodejs-v0-10-0         1 day ago
s2i-perl                   1 day ago
s2i-perl-v0-10-0           1 day ago
s2i-php                    1 day ago
s2i-php-v0-10-0            1 day ago
s2i-python-3               1 day ago
s2i-python-3-v0-10-0       1 day ago
s2i-ruby                   1 day ago
s2i-ruby-v0-10-0           1 day ago
s2i-v0-10-0                1 day ago


Créons maintenant deux tâches de cluster. Le premier va générer une image S2I et l'envoyer au registre interne OpenShift; la seconde est de construire notre image basée sur NGINX en utilisant l'application que nous avons déjà assemblée comme contenu.



Créer et envoyer l'image



Lors de la création de la première tâche, nous répéterons ce que nous avons déjà fait dans l'article précédent sur les assemblys liés. Rappelons que nous avons utilisé l'image S2I (ubi8-s2i-web-app) pour «construire» notre application et que nous avons fini avec l'image stockée dans le registre interne d'OpenShift. Nous allons maintenant utiliser cette image S2I de l'application Web pour créer un DockerFile pour notre application, puis utiliser Buildah pour faire la construction réelle et pousser l'image résultante dans le registre OpenShift interne, car c'est exactement ce que fait OpenShift lorsque vous déployez le vôtre. applications utilisant NodeShift.



Comment savions-nous tout cela, demandez-vous? À partir de la version officielle de Node.js officiel , nous venons de le copier et de le terminer nous-mêmes.



Nous créons donc maintenant la tâche de cluster s2i-web-app:



$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/s2i-web-app-task.yaml


Nous n'entrerons pas dans les détails à ce sujet, mais nous attarderons simplement sur le paramètre OUTPUT_DIR:



params:
      - name: OUTPUT_DIR
        description: The location of the build output directory
        default: build


Par défaut, ce paramètre est défini sur build, c'est là que React place le contenu collecté. D'autres frameworks utilisent des chemins différents, par exemple Ember utilise dist. La sortie de notre première tâche de cluster sera une image contenant le HTML, le JavaScript et le CSS que nous avons collectés.



Construire une image basée sur NGINX



Quant à notre deuxième tâche de cluster, elle devrait nous collecter une image basée sur NGINX, en utilisant le contenu de l'application que nous avons déjà collecté. Fondamentalement, c'est la partie de la section précédente où nous avons examiné les versions chaînées.



Pour ce faire, nous créons - de la même manière qu'un peu ci-dessus - une tâche de cluster webapp-build-runtime:



$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/webapp-build-runtime-task.yaml


Si vous regardez le code de ces tâches de cluster, vous pouvez voir que le référentiel Git avec lequel nous travaillons ou les noms des images que nous créons n'y sont pas spécifiés. Nous spécifions uniquement ce que nous transférons exactement vers Git, ou une certaine image, où l'image finale doit être affichée. C'est pourquoi ces tâches de cluster peuvent être réutilisées lorsque vous travaillez avec d'autres applications.



Et ici, nous passons gracieusement au point suivant ...



Ressources



Ainsi, puisque, comme nous venons de le dire, les tâches de cluster doivent être aussi génériques que possible, nous devons créer des ressources qui seront utilisées en entrée (référentiel Git) et en sortie (images finales). La première ressource dont nous avons besoin est Git où réside notre application, quelque chose comme ceci:



# This resource is the location of the git repo with the web application source
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: web-application-repo
spec:
  type: git
  params:
    - name: url
      value: https://github.com/nodeshift-starters/react-pipeline-example
    - name: revision
      value: master


Ici, PipelineResource est de type git. La clé url dans la section params pointe vers un référentiel spécifique et définit la branche master (c'est facultatif, mais nous l'écrivons par souci d'exhaustivité).



Maintenant, nous devons créer une ressource pour l'image, où les résultats de la tâche s2i-web-app seront enregistrés, ceci se fait comme ceci:



# This resource is the result of running "npm run build",  the resulting built files will be located in /opt/app-root/output
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: built-web-application-image
spec:
  type: image
  params:
    - name: url
      value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-application:latest


Ici, PipelineResource est de type image, et la valeur du paramètre url pointe vers le registre interne d'images OpenShift, en particulier vers celui de l'espace de noms webapp-pipeline. N'oubliez pas de modifier ce paramètre si vous utilisez un espace de noms différent.



Et enfin, la dernière ressource dont nous avons besoin sera également de type image et ce sera l'image NGINX finale, qui sera ensuite utilisée lors du déploiement:



# This resource is the image that will be just the static html, css, js files being run with nginx
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: runtime-web-application-image
spec:
  type: image
  params:
    - name: url
      value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtime-web-application:latest


Encore une fois, notez que cette ressource stocke l'image dans le registre OpenShift interne dans l'espace de noms webapp-pipeline.



Pour créer toutes ces ressources à la fois, utilisez la commande create:



$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/resources/resource.yaml


Vous pouvez vous assurer que les ressources ont été créées comme ceci:



$ tkn resource ls


Pipeline



Maintenant que nous avons tous les composants nécessaires, nous allons assembler un pipeline à partir d'eux, en le créant avec la commande suivante:



$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/pipelines/build-and-deploy-react.yaml


Mais avant d'exécuter cette commande, jetons un coup d'œil à ces composants. Le premier est le nom:



apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
  name: build-and-deploy-react


Ensuite, dans la section spec, nous voyons une indication des ressources que nous avons créées précédemment:



spec:
  resources:
    - name: web-application-repo
      type: git
    - name: built-web-application-image
      type: image
    - name: runtime-web-application-image
      type: image


Ensuite, nous créons des tâches que notre pipeline doit terminer. Tout d'abord, il doit exécuter la tâche s2i-web-app que nous avons déjà créée:



tasks:
    - name: build-web-application
      taskRef:
        name: s2i-web-app
        kind: ClusterTask


Cette tâche prend les paramètres d'entrée (ressource gir) et de sortie (ressource d'image d'application Web intégrée). Nous lui passons également un paramètre spécial afin qu'il ne vérifie pas TLS puisque nous utilisons des certificats auto-signés:



resources:
        inputs:
          - name: source
            resource: web-application-repo
        outputs:
          - name: image
            resource: built-web-application-image
      params:
        - name: TLSVERIFY
          value: "false"


La tâche suivante est presque la même, mais ici, la tâche de cluster webapp-build-runtime déjà créée est appelée:



name: build-runtime-image
    taskRef:
      name: webapp-build-runtime
      kind: ClusterTask


Comme pour la tâche précédente, nous transmettons la ressource, mais il s'agit maintenant d'une image d'application Web intégrée (la sortie de notre tâche précédente). Et en sortie, nous définissons à nouveau l'image. Puisque cette tâche doit être effectuée après la précédente, nous ajoutons le champ runAfter:



resources:
        inputs:
          - name: image
            resource: built-web-application-image
        outputs:
          - name: image
            resource: runtime-web-application-image
        params:
        - name: TLSVERIFY
          value: "false"
      runAfter:
        - build-web-application


Les deux tâches suivantes sont chargées d'appliquer les fichiers YAML de service, de routage et de déploiement qui résident dans le répertoire k8s de notre application Web, ainsi que de mettre à jour ce déploiement lors de la création de nouvelles images. Nous définissons ces deux tâches de cluster au début de l'article.



Faire fonctionner le convoyeur



Ainsi, toutes les parties de notre pipeline sont créées et nous allons le démarrer avec la commande suivante:



$ tkn pipeline start build-and-deploy-react


A ce stade, la ligne de commande est utilisée de manière interactive et vous devez sélectionner les ressources appropriées en réponse à chacune de ses requêtes: pour la ressource git, sélectionnez le repo-application-web, puis pour la ressource de la première image, sélectionnez l'image-application-web-intégrée, et enfin pour deuxième ressource image –runtime-web-application-image:



? Choose the git resource to use for web-application-repo: web-application-repo (https://github.com/nodeshift-starters/react-pipeline-example)
? Choose the image resource to use for built-web-application-image: built-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-
application:latest)
? Choose the image resource to use for runtime-web-application-image: runtime-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtim
e-web-application:latest)
Pipelinerun started: build-and-deploy-react-run-4xwsr


Maintenant, vérifions l'état du pipeline avec la commande suivante:



$ tkn pipeline logs -f


Une fois le pipeline démarré et l'application déployée, nous demandons la route publiée avec la commande suivante:



$ oc get route react-pipeline-example --template='http://{{.spec.host}}'


Pour plus de visibilité, vous pouvez afficher notre pipeline en mode développeur de la console Web dans la section Pipelines , comme illustré à la Fig. 1.







Fig. 1. Vue d'ensemble des pipelines en cours d'exécution.



Cliquez sur un pipeline en cours d'exécution pour afficher des informations supplémentaires, comme illustré à la figure 2.







Figure: 2. Plus d'informations sur le pipeline.



Après plus d'informations, vous pouvez voir les applications en cours d'exécution dans la vue Topologie , comme illustré à la figure 3.







Fig 3. Pod en marche.



Cliquez sur le cercle dans le coin supérieur droit de l'icône pour ouvrir notre application, comme le montre la figure 4.







Figure: 4. Lancement de l'application React.



Conclusion



Nous avons donc montré comment exécuter un serveur de développement pour votre application sur OpenShift et le synchroniser avec le système de fichiers local. Nous avons également examiné comment imiter le modèle de construction en chaîne à l'aide d'OpenShift Pipelines. Tous les exemples de codes de cet article peuvent être trouvés ici .



Ressources supplémentaires (EN)







Annonces de webinaires à venir



Nous lançons une série de webinaires du vendredi sur l'expérience native de l'utilisation de Red Hat OpenShift Container Platform et de Kubernetes:






All Articles